INCLUDE <LIST>.
TYPES: BEGIN OF POSITION,
COUNT TYPE I,
X TYPE I,
Y TYPE I,
END OF POSITION,
POSTAB TYPE TABLE OF POSITION.
DATA: DIM_WALL TYPE TABLE OF POSITION,
DIM_PLACE TYPE TABLE OF POSITION,
DIM_CARGO TYPE TABLE OF POSITION,
CURR_POS TYPE POSITION,
OLD_POS TYPE POSITION,
NEXT_POS TYPE POSITION,
DOUB_POS TYPE POSITION,
OBJECT_POS TYPE POSITION.
DATA: BEGIN OF HISTORY OCCURS 0 ,
STEP TYPE COUNT,
CURR_POS TYPE POSITION,
DIM_CARGO TYPE POSTAB,
END OF HISTORY.
DATA: INFORMATION TYPE TABLE OF TEXT132 WITH HEADER LINE.
DATA: LEVEL_NUMBER TYPE I,
COUNT_LINES TYPE I.
DATA: FACT_POSX TYPE I,
STEP TYPE COUNT.
DATA: LEVEL TYPE TABLE OF TEXT132 WITH HEADER LINE.
CONSTANTS: WALL VALUE '#',
CARGO VALUE '$',
PLACE VALUE '.',
SOKOBAN VALUE '@'.
INITIALIZATION.
PERFORM CREATE_INFO.
START-OF-SELECTION.
SET PF-STATUS 'NEW'.
LEVEL_NUMBER = LEVEL_NUMBER + 1.
PERFORM CREATE_LEVEL USING LEVEL_NUMBER.
* User-commands processing
AT USER-COMMAND.
CASE SY-UCOMM.
WHEN 'EXIT' OR 'CANCEL'.
LEAVE PROGRAM.
WHEN 'UNDO'.
CHECK STEP > 0.
READ TABLE HISTORY WITH KEY STEP = STEP.
DIM_CARGO[] = HISTORY-DIM_CARGO.
OLD_POS = CURR_POS.
CURR_POS = HISTORY-CURR_POS.
DELETE HISTORY WHERE STEP = STEP.
STEP = STEP - 1.
PERFORM REDRAW_LEVEL.
WHEN 'INFO'.
CALL FUNCTION 'POPUP_WITH_TABLE_DISPLAY'
EXPORTING
ENDPOS_COL = 70
ENDPOS_ROW = 15
STARTPOS_COL = 5
STARTPOS_ROW = 5
TITLETEXT = 'What is Sokoban?'
TABLES
VALUETAB = INFORMATION
EXCEPTIONS
BREAK_OFF = 1.
IF SY-SUBRC <> 0.
ENDIF.
.
ENDCASE.
AT PF20. " Left
PERFORM MOVEMENT USING 'LEFT'.
AT PF21. " Right
PERFORM MOVEMENT USING 'RIGHT'.
AT PF23. " Down
PERFORM MOVEMENT USING 'DOWN'.
AT PF24. " Up
PERFORM MOVEMENT USING 'UP'.
*&---------------------------------------------------------------------*
*& Form CREATE_LEVEL
*&---------------------------------------------------------------------*
FORM CREATE_LEVEL USING P_NUMBER.
DATA: X_NEW TYPE I,
Y_NEW TYPE I.
DATA: LENGTH TYPE I,
TEMP_X TYPE I,
TEMP_Y TYPE I,
N TYPE I,
FIELD.
CASE P_NUMBER.
WHEN 1.
APPEND ' ########' TO LEVEL.
APPEND ' ### .#' TO LEVEL.
APPEND ' #. #### #' TO LEVEL.
APPEND '### #' TO LEVEL.
APPEND '# . @ .# #' TO LEVEL.
APPEND '# #### ### #' TO LEVEL.
APPEND '# # #' TO LEVEL.
APPEND '##### # #' TO LEVEL.
APPEND ' # #' TO LEVEL.
APPEND ' # $$$$ #' TO LEVEL.
APPEND ' # ###' TO LEVEL.
APPEND ' ###### ' TO LEVEL.
WHEN 2.
APPEND '######## #####' TO LEVEL.
APPEND '# # ### #' TO LEVEL.
APPEND '# ## $ #' TO LEVEL.
APPEND '#.# @ ## $ ##' TO LEVEL.
APPEND '#.# # $ ## ' TO LEVEL.
APPEND '#.# $ ## ' TO LEVEL.
APPEND '#. ## ##### ' TO LEVEL.
APPEND '## # ' TO LEVEL.
APPEND ' ###### ' TO LEVEL.
WHEN 3.
APPEND ' #### ' TO LEVEL.
APPEND ' ## ###' TO LEVEL.
APPEND '#### # $ #' TO LEVEL.
APPEND '# #### $ $ #' TO LEVEL.
APPEND '# ..# #$ #' TO LEVEL.
APPEND '# # @ ###' TO LEVEL.
APPEND '## #..# ### ' TO LEVEL.
APPEND ' # ## # # ' TO LEVEL.
APPEND ' # # ' TO LEVEL.
APPEND ' ######## ' TO LEVEL.
WHEN 4.
APPEND ' ### ' TO LEVEL.
APPEND ' ## # ####' TO LEVEL.
APPEND ' ## ### #' TO LEVEL.
APPEND '## $ #' TO LEVEL.
APPEND '# @$ # #' TO LEVEL.
APPEND '### $### #' TO LEVEL.
APPEND ' # #.. #' TO LEVEL.
APPEND ' ## ##.# ##' TO LEVEL.
APPEND ' # ## ' TO LEVEL.
APPEND ' # ## ' TO LEVEL.
APPEND ' ####### ' TO LEVEL.
WHEN 5.
APPEND '#### ' TO LEVEL.
APPEND '# # ####' TO LEVEL.
APPEND '# ######## ####### #' TO LEVEL.
APPEND '# ### ## $ #' TO LEVEL.
APPEND '##.###### ... #. #' TO LEVEL.
APPEND ' #.# # .# # $ #' TO LEVEL.
APPEND ' #$$$$#$$$ #.# ##. #' TO LEVEL.
APPEND ' #.# $ $ #.. ##' TO LEVEL.
APPEND ' #.# $ $ # # ## ' TO LEVEL.
APPEND ' # # $$ # ##### ' TO LEVEL.
APPEND ' #. ##$ ###### ' TO LEVEL.
APPEND ' #. # $. # ' TO LEVEL.
APPEND '##. @ ###.#$ # ' TO LEVEL.
APPEND '# # # # ' TO LEVEL.
APPEND '# ## ###### ' TO LEVEL.
APPEND '###### ' TO LEVEL.
ENDCASE.
LOOP AT LEVEL.
TEMP_X = LENGTH = STRLEN( LEVEL ).
N = N + 1.
WHILE LENGTH > 0.
CLEAR: COUNT_LINES, CURR_POS-COUNT.
LENGTH = LENGTH - 1.
FIELD = LEVEL.
SHIFT LEVEL.
OBJECT_POS-X = TEMP_X - LENGTH.
CASE FIELD.
WHEN WALL.
WRITE AT OBJECT_POS-X FIELD COLOR COL_NEGATIVE.
DESCRIBE TABLE DIM_WALL LINES COUNT_LINES.
CURR_POS-COUNT = COUNT_LINES + 1.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
APPEND CURR_POS TO DIM_WALL.
WHEN SOKOBAN.
WRITE AT OBJECT_POS-X FIELD.
X_NEW = OBJECT_POS-X - 1.
Y_NEW = N.
WHEN CARGO.
WRITE AT OBJECT_POS-X FIELD.
DESCRIBE TABLE DIM_CARGO LINES COUNT_LINES.
CURR_POS-COUNT = COUNT_LINES + 1.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
APPEND CURR_POS TO DIM_CARGO.
WHEN PLACE.
WRITE AT OBJECT_POS-X FIELD COLOR 2.
DESCRIBE TABLE DIM_PLACE LINES COUNT_LINES.
CURR_POS-COUNT = COUNT_LINES + 1.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
APPEND CURR_POS TO DIM_PLACE.
ENDCASE.
ENDWHILE.
NEW-LINE.
ENDLOOP.
PERFORM PRINT_LEGEND.
CURR_POS-X = X_NEW. CURR_POS-Y = Y_NEW. " Start human position
ENDFORM. " CREATE_LEVEL
*&---------------------------------------------------------------------*
*& Form MOVEMENT
*&---------------------------------------------------------------------*
FORM MOVEMENT USING DIRECTION TYPE CHAR10.
CLEAR: FACT_POSX.
PERFORM SAVE_HISTORY.
CASE DIRECTION.
WHEN 'LEFT' OR 'RIGHT'.
IF DIRECTION EQ 'LEFT'.
NEXT_POS-X = CURR_POS-X - 1.
DOUB_POS-X = CURR_POS-X - 2.
ELSE.
NEXT_POS-X = CURR_POS-X + 1.
DOUB_POS-X = CURR_POS-X + 2.
ENDIF.
READ LINE CURR_POS-Y LINE VALUE INTO CURR_LINE.
CASE CURR_LINE+NEXT_POS-X(1).
WHEN SPACE OR PLACE.
CURR_LINE+NEXT_POS-X(1) = CURR_LINE+CURR_POS-X(1).
CURR_LINE+CURR_POS-X(1) = SPACE.
CURR_POS-X = NEXT_POS-X.
WHEN WALL.
CLEAR: NEXT_POS, DOUB_POS.
EXIT.
WHEN CARGO.
CASE CURR_LINE+DOUB_POS-X(1).
WHEN SPACE OR PLACE.
FACT_POSX = NEXT_POS-X + 1.
READ TABLE DIM_CARGO INTO OBJECT_POS
WITH KEY X = FACT_POSX
Y = CURR_POS-Y.
FACT_POSX = FACT_POSX + 1.
IF DIRECTION EQ 'LEFT'.
OBJECT_POS-X = NEXT_POS-X.
ELSE.
OBJECT_POS-X = DOUB_POS-X + 1.
ENDIF.
MODIFY DIM_CARGO FROM OBJECT_POS INDEX OBJECT_POS-COUNT.
CURR_LINE+NEXT_POS-X(1) = CURR_LINE+CURR_POS-X(1).
CURR_LINE+CURR_POS-X(1) = SPACE.
CURR_POS-X = NEXT_POS-X.
WHEN WALL OR CARGO.
CLEAR: NEXT_POS, DOUB_POS.
EXIT.
ENDCASE.
ENDCASE.
CLEAR: NEXT_POS, DOUB_POS.
MODIFY LINE CURR_POS-Y LINE VALUE FROM CURR_LINE.
WHEN 'DOWN' OR 'UP'.
IF DIRECTION EQ 'DOWN'.
NEXT_POS-Y = CURR_POS-Y + 1.
DOUB_POS-Y = CURR_POS-Y + 2.
ELSE.
NEXT_POS-Y = CURR_POS-Y - 1.
DOUB_POS-Y = CURR_POS-Y - 2.
ENDIF.
READ LINE CURR_POS-Y LINE VALUE INTO CURR_LINE.
READ LINE NEXT_POS-Y LINE VALUE INTO NEXT_LINE.
READ LINE DOUB_POS-Y LINE VALUE INTO DOUB_LINE.
CASE NEXT_LINE+CURR_POS-X(1).
WHEN SPACE OR PLACE.
NEXT_LINE+CURR_POS-X(1) = CURR_LINE+CURR_POS-X(1).
CURR_LINE+CURR_POS-X(1) = SPACE.
WHEN WALL.
CLEAR: NEXT_POS, DOUB_POS.
EXIT.
WHEN CARGO.
CASE DOUB_LINE+CURR_POS-X(1).
WHEN SPACE OR PLACE.
FACT_POSX = CURR_POS-X + 1.
READ TABLE DIM_CARGO INTO OBJECT_POS
WITH KEY X = FACT_POSX
Y = NEXT_POS-Y.
OBJECT_POS-Y = DOUB_POS-Y.
MODIFY DIM_CARGO FROM OBJECT_POS INDEX OBJECT_POS-COUNT.
NEXT_LINE+CURR_POS-X(1) = CURR_LINE+CURR_POS-X(1).
CURR_LINE+CURR_POS-X(1) = SPACE.
WHEN WALL OR CARGO.
CLEAR: NEXT_POS, DOUB_POS.
EXIT.
ENDCASE.
ENDCASE.
MODIFY LINE CURR_POS-Y LINE VALUE FROM CURR_LINE.
MODIFY LINE NEXT_POS-Y LINE VALUE FROM NEXT_LINE.
MODIFY LINE DOUB_POS-Y LINE VALUE FROM DOUB_LINE.
CURR_POS-Y = NEXT_POS-Y.
CLEAR: NEXT_POS, DOUB_POS.
ENDCASE.
PERFORM REDRAW_LEVEL.
PERFORM CHECK_COMPLETE.
PERFORM PRINT_LEGEND.
ENDFORM. " MOVEMENT
*&---------------------------------------------------------------------*
*& Form REDRAW_LEVEL
*&---------------------------------------------------------------------*
FORM REDRAW_LEVEL .
DATA: POSX TYPE I.
* Clear level
PERFORM CLEAR_LEVEL.
* Restore soko-ban
READ LINE CURR_POS-Y LINE VALUE INTO NEXT_LINE.
NEXT_LINE+CURR_POS-X(1) = SOKOBAN.
MODIFY LINE CURR_POS-Y LINE VALUE FROM NEXT_LINE.
* Restore wall
LOOP AT DIM_WALL INTO OBJECT_POS.
READ LINE OBJECT_POS-Y LINE VALUE INTO NEXT_LINE.
POSX = OBJECT_POS-X - 1.
IF NEXT_LINE+POSX(1) IS INITIAL.
NEXT_LINE+POSX(1) = WALL.
ENDIF.
MODIFY LINE OBJECT_POS-Y LINE VALUE FROM NEXT_LINE.
CLEAR NEXT_LINE.
ENDLOOP.
* Restore placement
LOOP AT DIM_PLACE INTO OBJECT_POS.
READ LINE OBJECT_POS-Y LINE VALUE INTO NEXT_LINE.
POSX = OBJECT_POS-X - 1.
IF NEXT_LINE+POSX(1) IS INITIAL.
NEXT_LINE+POSX(1) = PLACE.
ENDIF.
MODIFY LINE OBJECT_POS-Y LINE VALUE FROM NEXT_LINE.
CLEAR NEXT_LINE.
ENDLOOP.
* Restore cargo
LOOP AT DIM_CARGO INTO OBJECT_POS.
READ LINE OBJECT_POS-Y LINE VALUE INTO NEXT_LINE.
POSX = OBJECT_POS-X - 1.
IF NEXT_LINE+POSX(1) IS INITIAL OR NEXT_LINE+POSX(1) EQ PLACE.
NEXT_LINE+POSX(1) = CARGO.
ENDIF.
MODIFY LINE OBJECT_POS-Y LINE VALUE FROM NEXT_LINE.
CLEAR NEXT_LINE.
ENDLOOP.
ENDFORM. " REDRAW_LEVEL
*&---------------------------------------------------------------------*
*& Form CHECK_COMPLETE
*&---------------------------------------------------------------------*
FORM CHECK_COMPLETE .
DATA: FOUND,
CARGO_POS TYPE POSITION.
LOOP AT DIM_PLACE INTO OBJECT_POS.
READ TABLE DIM_CARGO
WITH KEY X = OBJECT_POS-X
Y = OBJECT_POS-Y
TRANSPORTING NO FIELDS.
IF SY-SUBRC <> 0.
FOUND = 'X'.
EXIT.
ENDIF.
ENDLOOP.
IF FOUND IS INITIAL. " Complete
MESSAGE 'Level complete' TYPE 'I'.
LEVEL_NUMBER = LEVEL_NUMBER + 1.
PERFORM CLEAR_LEVEL.
PERFORM CREATE_LEVEL USING LEVEL_NUMBER.
ENDIF.
ENDFORM. " CHECK_COMPLETE
*&---------------------------------------------------------------------*
*& Form SAVE_HISTORY
*&---------------------------------------------------------------------*
FORM SAVE_HISTORY .
DESCRIBE TABLE HISTORY LINES COUNT_LINES.
STEP = HISTORY-STEP = COUNT_LINES + 1.
HISTORY-CURR_POS = CURR_POS.
HISTORY-DIM_CARGO = DIM_CARGO[].
APPEND HISTORY.
ENDFORM. " SAVE_HISTORY
*&---------------------------------------------------------------------*
*& Form CLEAR_LEVEL
*&---------------------------------------------------------------------*
FORM CLEAR_LEVEL .
CLEAR NEXT_LINE.
DO.
MODIFY LINE SY-INDEX LINE VALUE FROM NEXT_LINE.
IF SY-SUBRC <> 0.
EXIT.
ENDIF.
ENDDO.
ENDFORM. " CLEAR_LEVEL
*&---------------------------------------------------------------------*
*& Form CREATE_INFO
*&---------------------------------------------------------------------*
FORM CREATE_INFO .
APPEND:
'Sokoban is a logic game consisting of sets of puzzles or "levels"' TO INFORMATION,
'similar to the example shown above. It is not a video game and' TO INFORMATION,
'does not require quick reflexes nor does it involve blasting' TO INFORMATION,
'aliens to bits. Sokoban means warehouse keeper in Japanese.' TO INFORMATION,
'The player pushes objects (balls, crates or money bags depending' TO INFORMATION,
'on the version) to their correct destinations in a crowded' TO INFORMATION,
'"warehouse". The puzzles range from very simple to extremely' TO INFORMATION,
'difficult ones requiring many hours of brain work.' TO INFORMATION,
INITIAL LINE TO INFORMATION,
'The game was invented in Japan and won a computer game contest' TO INFORMATION,
'there. The original program was written by Hiroyuki Imabayashi' TO INFORMATION,
'and is Copyright (c) 1982 by THINKING RABBIT Inc. JAPAN. Since' TO INFORMATION,
'then, many other versions of the program have been written and' TO INFORMATION,
'additional sets of puzzles have been created. Many of these may' TO INFORMATION,
'be found by searching the internet' TO INFORMATION.
ENDFORM. " CREATE_INFO
*&---------------------------------------------------------------------*
*& Form PRINT_LEGEND
*&---------------------------------------------------------------------*
FORM PRINT_LEGEND .
READ LINE 1 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = '@ - warehause keeper (sokoban)'.
MODIFY LINE 1 LINE VALUE FROM NEXT_LINE.
READ LINE 2 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = '# - wall'.
MODIFY LINE 2 LINE VALUE FROM NEXT_LINE.
READ LINE 3 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = '. - warehause place'.
MODIFY LINE 3 LINE VALUE FROM NEXT_LINE.
READ LINE 4 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = '$ - good'.
MODIFY LINE 4 LINE VALUE FROM NEXT_LINE.
READ LINE 5 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = 'You must keep all goods at warehause places.'.
MODIFY LINE 5 LINE VALUE FROM NEXT_LINE.
READ LINE 6 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = 'You can push only one good at time.'.
MODIFY LINE 6 LINE VALUE FROM NEXT_LINE.
READ LINE 7 LINE VALUE INTO NEXT_LINE.
NEXT_LINE+30 = 'Keys: F5 left; F6 right; F7 down; F8 up; F9 undo'.
MODIFY LINE 7 LINE VALUE FROM NEXT_LINE.
ENDFORM. " PRINT_LEGEND
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG. SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG. Every effort is made to ensure content integrity. Use information on this site at your own risk.