Age: 46 Joined: 05 Nov 2007 Posts: 725 Location: КраснАдар
Posted: Mon Jun 16, 2008 11:07 pm Post subject: Gardener (Sokoban Advance)
Посвящается тем, кто не любит псевдографику.
Теперь будем рассаживать деревья в ямки...
GUI-статус по аналогии с Sokoban. В принципе достаточно заменить код в предыдущей программе.
Code:
*&---------------------------------------------------------------------*
*& Report ZSOKOBAN2
*&
*&---------------------------------------------------------------------*
*& Developed by Markin A. 16.06.2008
*& All game levels created by David W. Skinner & getting from this source:
*& http://users.bentonrea.com/~sasquatch/sokoban/
*&---------------------------------------------------------------------*
REPORT ZSOKOBAN NO STANDARD PAGE HEADING.
INCLUDE <LIST>.
TYPES: BEGIN OF POSITION,
COUNT TYPE I,
OBJECT(4),
X TYPE I,
Y TYPE I,
END OF POSITION,
POSTAB TYPE TABLE OF POSITION.
DATA: DIM_LEVEL TYPE TABLE OF POSITION,
CURR_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_LEVEL TYPE POSTAB,
END OF HISTORY.
DATA: INFORMATION TYPE TABLE OF TEXT132 WITH HEADER LINE.
DATA: LEVEL_NUMBER TYPE I,
COUNT_LINES TYPE I,
XCOUNT_LINES TYPE I.
DATA: FACT_POSX TYPE I,
XLENGTH TYPE I,
STEP TYPE COUNT.
DATA: NEXT_LINE(255).
DATA: LEVEL TYPE DMS_TAB_TDLINE WITH HEADER LINE.
CONSTANTS: WALLX VALUE '#',
WALL(4) VALUE ICON_ES_REPOSITORY,
CARGOX VALUE '$',
CARGO(4) VALUE ICON_HIERARCHY_RED,
PLACEX VALUE '.',
PLACE(4) VALUE ICON_HIERARCHY_INA,
CARGO_IN_PLACEX VALUE '*',
CARGO_IN_PLACE(4) VALUE ICON_HIERARCHY_ACT,
SOKOBANX VALUE '@',
SOKOBAN(4) VALUE ICON_MANAGER.
DEFINE GET_POSITION.
READ TABLE DIM_LEVEL INTO &1
WITH KEY OBJECT = CARGO_IN_PLACE X = &2 Y = &3.
IF SY-SUBRC <> 0.
READ TABLE DIM_LEVEL INTO &1
WITH KEY OBJECT = CARGO X = &2 Y = &3.
IF SY-SUBRC <> 0.
READ TABLE DIM_LEVEL INTO &1
WITH KEY OBJECT = WALL X = &2 Y = &3.
IF SY-SUBRC <> 0.
READ TABLE DIM_LEVEL INTO &1
WITH KEY OBJECT = PLACE X = &2 Y = &3.
ENDIF.
ENDIF.
ENDIF.
END-OF-DEFINITION.
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 'CHECK'.
DATA: RETCODE TYPE SY-SUBRC.
PERFORM CHECK_COMPLETE CHANGING RETCODE.
IF RETCODE = 0.
PERFORM REDRAW_LEVEL.
ENDIF.
WHEN 'EXIT' OR 'CANCEL'.
LEAVE PROGRAM.
WHEN 'UNDO'.
CHECK STEP > 0.
READ TABLE HISTORY WITH KEY STEP = STEP.
DIM_LEVEL[] = HISTORY-DIM_LEVEL.
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.
WHEN 2.
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.
WHEN 4.
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.
WHEN 6.
APPEND '###### #####' TO LEVEL.
APPEND '# ### #' TO LEVEL.
APPEND '# $$ #@#' TO LEVEL.
APPEND '# $ #... #' TO LEVEL.
APPEND '# ########' TO LEVEL.
APPEND '#####' TO LEVEL.
WHEN 7.
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 8.
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 9.
APPEND '#####' TO LEVEL.
APPEND '#. ##' TO LEVEL.
APPEND '#@$$ #' TO LEVEL.
APPEND '## #' TO LEVEL.
APPEND ' ## #' TO LEVEL.
APPEND ' ##.#' TO LEVEL.
APPEND ' ###' TO LEVEL.
WHEN 10.
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.
DESCRIBE TABLE LEVEL LINES XCOUNT_LINES.
LOOP AT LEVEL.
TEMP_X = LENGTH = STRLEN( LEVEL ).
IF XLENGTH < LENGTH.
XLENGTH = LENGTH.
ENDIF.
N = N + 1.
WHILE LENGTH > 0.
CLEAR: COUNT_LINES.
LENGTH = LENGTH - 1.
FIELD = LEVEL.
SHIFT LEVEL.
OBJECT_POS-X = TEMP_X - LENGTH.
FACT_POSX = OBJECT_POS-X * 2 - 1.
CASE FIELD.
WHEN WALLX.
WRITE AT FACT_POSX WALL AS ICON.
CURR_POS-OBJECT = WALL.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
CURR_POS-COUNT = CURR_POS-COUNT + 1.
APPEND CURR_POS TO DIM_LEVEL.
WHEN SOKOBANX.
WRITE AT FACT_POSX SOKOBAN AS ICON.
CURR_POS-OBJECT = SOKOBAN.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
CURR_POS-COUNT = CURR_POS-COUNT + 1.
APPEND CURR_POS TO DIM_LEVEL.
WHEN CARGOX.
WRITE AT FACT_POSX CARGO AS ICON.
CURR_POS-OBJECT = CARGO.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
CURR_POS-COUNT = CURR_POS-COUNT + 1.
APPEND CURR_POS TO DIM_LEVEL.
WHEN PLACEX.
WRITE AT FACT_POSX PLACE AS ICON.
CURR_POS-OBJECT = PLACE.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
CURR_POS-COUNT = CURR_POS-COUNT + 1.
APPEND CURR_POS TO DIM_LEVEL.
WHEN CARGO_IN_PLACEX.
WRITE AT FACT_POSX CARGO_IN_PLACE AS ICON.
CURR_POS-OBJECT = PLACE.
CURR_POS-X = OBJECT_POS-X. CURR_POS-Y = N.
CURR_POS-COUNT = CURR_POS-COUNT + 1.
APPEND CURR_POS TO DIM_LEVEL.
CURR_POS-OBJECT = CARGO_IN_PLACE.
CURR_POS-COUNT = CURR_POS-COUNT + 1.
APPEND CURR_POS TO DIM_LEVEL.
ENDCASE.
ENDWHILE.
NEW-LINE.
ENDLOOP.
PERFORM PRINT_LEGEND.
" Start human position
READ TABLE DIM_LEVEL INTO CURR_POS WITH KEY OBJECT = SOKOBAN.
ENDFORM. " CREATE_LEVEL
*&---------------------------------------------------------------------*
*& Form MOVEMENT
*&---------------------------------------------------------------------*
FORM MOVEMENT USING DIRECTION TYPE CHAR10.
DATA: SOKOBAN_POSITION TYPE POSITION.
CLEAR: FACT_POSX, NEXT_POS, DOUB_POS.
READ TABLE DIM_LEVEL INTO SOKOBAN_POSITION WITH KEY OBJECT = SOKOBAN.
CURR_POS = SOKOBAN_POSITION.
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.
GET_POSITION NEXT_POS NEXT_POS-X CURR_POS-Y.
GET_POSITION DOUB_POS DOUB_POS-X CURR_POS-Y.
CASE NEXT_POS-OBJECT.
WHEN SPACE.
SOKOBAN_POSITION-X = NEXT_POS-X.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
WHEN WALL.
EXIT.
WHEN CARGO.
CASE DOUB_POS-OBJECT.
WHEN SPACE.
SOKOBAN_POSITION-X = NEXT_POS-X.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-X = DOUB_POS-X.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
WHEN WALL OR CARGO OR CARGO_IN_PLACE.
EXIT.
WHEN PLACE.
SOKOBAN_POSITION-X = NEXT_POS-X.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-X = DOUB_POS-X. NEXT_POS-OBJECT = CARGO_IN_PLACE.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
ENDCASE.
WHEN CARGO_IN_PLACE.
CASE DOUB_POS-OBJECT.
WHEN SPACE.
SOKOBAN_POSITION-X = NEXT_POS-X.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-X = DOUB_POS-X. NEXT_POS-OBJECT = CARGO.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
WHEN WALL OR CARGO OR CARGO_IN_PLACE.
EXIT.
WHEN PLACE.
SOKOBAN_POSITION-X = NEXT_POS-X.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-X = DOUB_POS-X.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
ENDCASE.
WHEN PLACE.
SOKOBAN_POSITION-X = NEXT_POS-X.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
ENDCASE.
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.
GET_POSITION NEXT_POS CURR_POS-X NEXT_POS-Y.
GET_POSITION DOUB_POS CURR_POS-X DOUB_POS-Y.
CASE NEXT_POS-OBJECT.
WHEN SPACE.
SOKOBAN_POSITION-Y = NEXT_POS-Y.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
WHEN WALL.
EXIT.
WHEN CARGO.
CASE DOUB_POS-OBJECT.
WHEN SPACE.
SOKOBAN_POSITION-Y = NEXT_POS-Y.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-Y = DOUB_POS-Y.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
WHEN PLACE.
SOKOBAN_POSITION-Y = NEXT_POS-Y.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-Y = DOUB_POS-Y. NEXT_POS-OBJECT = CARGO_IN_PLACE.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
WHEN WALL OR CARGO OR CARGO_IN_PLACE.
EXIT.
ENDCASE.
WHEN CARGO_IN_PLACE.
CASE DOUB_POS-OBJECT.
WHEN SPACE.
SOKOBAN_POSITION-Y = NEXT_POS-Y.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-Y = DOUB_POS-Y. NEXT_POS-OBJECT = CARGO.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
WHEN PLACE.
SOKOBAN_POSITION-Y = NEXT_POS-Y.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
NEXT_POS-Y = DOUB_POS-Y.
MODIFY DIM_LEVEL FROM NEXT_POS INDEX NEXT_POS-COUNT.
WHEN WALL OR CARGO OR CARGO_IN_PLACE.
EXIT.
ENDCASE.
WHEN PLACE.
SOKOBAN_POSITION-Y = NEXT_POS-Y.
MODIFY DIM_LEVEL FROM SOKOBAN_POSITION INDEX SOKOBAN_POSITION-COUNT.
ENDCASE.
ENDCASE.
PERFORM REDRAW_LEVEL.
CALL FUNCTION 'RFC_PING_AND_WAIT' STARTING NEW TASK '001'
PERFORMING TASK_END ON END OF TASK
EXPORTING
SECONDS = 1 " Refresh time
BUSY_WAITING = SPACE
EXCEPTIONS
RESOURCE_FAILURE = 1
COMMUNICATION_FAILURE = 2
SYSTEM_FAILURE = 3
OTHERS = 4.
ENDFORM. " MOVEMENT
*&---------------------------------------------------------------------*
*& Form TASK_END
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->TASK text
*----------------------------------------------------------------------*
FORM TASK_END USING TASK.
SET USER-COMMAND 'CHECK'.
ENDFORM. "TASK_END
*&---------------------------------------------------------------------*
*& Form REDRAW_LEVEL
*&---------------------------------------------------------------------*
FORM REDRAW_LEVEL .
DATA: PLACE_POSITION TYPE POSITION,
TEMP_LEVEL TYPE POSTAB.
SY-LSIND = 1.
READ TABLE DIM_LEVEL INTO CURR_POS WITH KEY OBJECT = SOKOBAN.
DO XCOUNT_LINES TIMES.
TEMP_LEVEL[] = DIM_LEVEL[].
DELETE TEMP_LEVEL WHERE Y NE SY-INDEX.
SORT TEMP_LEVEL BY X.
LOOP AT TEMP_LEVEL INTO OBJECT_POS.
FACT_POSX = OBJECT_POS-X * 2 - 1.
IF OBJECT_POS-X = CURR_POS-X AND OBJECT_POS-Y = CURR_POS-Y.
WRITE AT FACT_POSX CURR_POS-OBJECT AS ICON.
ELSE.
GET_POSITION OBJECT_POS OBJECT_POS-X OBJECT_POS-Y.
WRITE AT FACT_POSX OBJECT_POS-OBJECT AS ICON.
ENDIF.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Form CHECK_COMPLETE
*&---------------------------------------------------------------------*
FORM CHECK_COMPLETE CHANGING RETCODE TYPE SY-SUBRC.
READ TABLE DIM_LEVEL WITH KEY OBJECT = CARGO TRANSPORTING NO FIELDS.
RETCODE = SY-SUBRC.
IF RETCODE <> 0. " Complete
MESSAGE 'Level complete' TYPE 'I'.
LEVEL_NUMBER = LEVEL_NUMBER + 1.
REFRESH: LEVEL, DIM_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_LEVEL = DIM_LEVEL[].
APPEND HISTORY.
ENDFORM. " SAVE_HISTORY
*&---------------------------------------------------------------------*
*& 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
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.