Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

If you remember ZX-spectrum, you must remember this funny "time-killer". I port it to ABAP.

 For correct work need create gui status named 'NEW' with some functions: 

Function Keys:

F2 INFO  ICON_INFORMATION

F9 UNDO ICON_SYSTEM_UNDO

F5 PF20 ICON_COLUMN_LEFT

F6 PF21 ICON_COLUMN_RIGHT

F7 PF23 ICON_PREVIOUS_VALUE

F8 PF24 ICON_NEXT_VALUE

Standard Toolbar: EXIT, CANCEL.

Application Toolbar: PF20, PF21, PF23, PF24, UNDO, INFO.

Also need create gui titlebar named 'NEW' with 'Sokoban: Level &'.

Code:

Error rendering macro 'code': Invalid value specified for parameter 'lang'
*&---------------------------------------------------------------------*
*& Report  ZSOKOBAN
*&
*&---------------------------------------------------------------------*
*& Developed by Markin A. 10.06.2008
*& Some game levels created by David W. Skinner & getting from this source:
*& http://users.bentonrea.com/~sasquatch/sokoban/
*& So, I am Pirat (smile)  David, sorry...
*&---------------------------------------------------------------------*
REPORT  ZSOKOBAN.
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 DMS_TAB_TDLINE WITH HEADER LINE.
DATA: CURR_LINE(132),
      NEXT_LINE(132),
      DOUB_LINE(132).
DATA: LEVEL_NUMBER TYPE I,
      COUNT_LINES TYPE I.
DATA: FACT_POSX TYPE I,
      STEP TYPE COUNT.
DATA: LEVEL TYPE DMS_TAB_TDLINE 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.
  FREE: HISTORY, LEVEL, DIM_WALL, DIM_PLACE, DIM_CARGO.
  CLEAR: LEVEL, STEP.
  SET TITLEBAR 'NEW' WITH P_NUMBER.
  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

 

 

1 Comment

  1. Nice one!!)) My favorite game in the childhood!)) I played it on AGAT PCs yet!