SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Abap Minesweeper



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> Programming Techniques | Приемы программирования -> Games
View previous topic :: View next topic  
Author Message
mrand
Участник
Участник


Age: 43
Joined: 15 Apr 2008
Posts: 10
Location: москва

PostPosted: Wed Apr 01, 2009 1:18 am    Post subject: Abap Minesweeper Reply with quote

Описание и скриншоты в блоге


Code:

REPORT  zminesweeper NO STANDARD PAGE HEADING LINE-SIZE 125.
* ------------------------------------------------------------
* ABAP Minesweeper
* (c) Andrey Timofeev
* http://mrand.name/sap-abap
* license: free, "as is"
* ------------------------------------------------------------
* Installation: compile and run.
*   (for SAP 4.x, use http://mrand.name/sap-abap/sweeper4.txt)
* ------------------------------------------------------------
*  v1.0    2009.04.01
*     initial release
*


INCLUDE <icon>.


CONSTANTS:
" >> board cell values
   blank_hidden  TYPE c VALUE '0',
   blank_marked  TYPE c VALUE 'm',
   blank_opened  TYPE c VALUE '.',

   bomb_hidden   TYPE c VALUE '*',
   bomb_marked   TYPE c VALUE 'M',
   bomb_opened   TYPE c VALUE '&',

   "digit_hidden TYPE c VALUE 'A', "  A B C D E F G H
   "digit_marked TYPE c VALUE 'a', "  a b c d e f g h
   "digit_opened TYPE c VALUE '1', "  1 2 3 4 5 6 7 8

   endgame_bomb_boom       TYPE c VALUE 'X',
   endgame_bomb_missmark   TYPE c VALUE '@',
   border                  TYPE c VALUE '#',

" >> game state
   game_in   VALUE '1',
   game_over VALUE '2',
   game_win  VALUE '3'.

DATA:
   board(9999) TYPE c,  " 2D board,  x_size * y_size + borders
   ofs         TYPE i,  " board[ofs] = cell unique ID
   min         TYPE i,  " board[min] .. board[max]
   max         TYPE i,
   rdx         TYPE i,  " = 2 + width  of board
   rdy         TYPE i,  " = 2 + height of board
   square      TYPE i,  " = x_size * y_size = visible area
   square2     TYPE i,  " =    rdx *    rdy = visible area + border
   range       TYPE i,  " = max - min + 1
   rest        TYPE i,  " = square - bomb_cnt = empty cells to invent
   game        TYPE c,  " gamestate  = 1,2,3
   game_size   TYPE c,  " B=Beginner, I=Interm, E=Expert, C=Custom
   game_time(5) TYPE c, " seconds
   b_left(4)   TYPE c.  " unmarked bombs left

"  >> eight directions: North, South, East, West, NE, NW, SE, SW
DATA:  eight_directions TYPE TABLE OF i INITIAL SIZE 8 WITH HEADER LINE .

" >> cells2update list, to track board[] changes
TYPES:
   BEGIN OF celltype,
      offset(4) TYPE c,
      color TYPE c,
   END OF celltype.
DATA: cells2update TYPE TABLE OF celltype INITIAL SIZE 1000 WITH HEADER LINE.

" >> misc
CONSTANTS:
   x_ofs TYPE i VALUE 1,
   y_ofs TYPE i VALUE 5.
DATA:
   game_time1 TYPE timestamp, " game    begin
   game_time2 TYPE timestamp.


" >> high_scores
CONSTANTS:
   database_id_prefix(21) TYPE c VALUE 'ABAPMINESWEEPERSCORES'.
TYPES:
   BEGIN OF score_line,
      user    LIKE sy-uname,
      time(5) TYPE c,
   END OF score_line.

DATA:
   high_scores TYPE SORTED TABLE OF score_line
        WITH UNIQUE KEY time WITH HEADER LINE,
   database_id LIKE indx-srtfd. " export/import to database ID





" >> game difficulty
SELECTION-SCREEN BEGIN OF BLOCK bl_game_difficulty.

SELECTION-SCREEN: BEGIN OF LINE.
SELECTION-SCREEN: COMMENT  (23) hstitle1.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: BEGIN OF LINE.
PARAMETERS g1 RADIOBUTTON GROUP one
        USER-COMMAND radiogroup01.
SELECTION-SCREEN: COMMENT (10) text1.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: BEGIN OF LINE.
PARAMETERS g2 RADIOBUTTON GROUP one.
SELECTION-SCREEN: COMMENT (12) text2.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: BEGIN OF LINE.
PARAMETERS g3 RADIOBUTTON GROUP one.
SELECTION-SCREEN: COMMENT (10) text3.
SELECTION-SCREEN: END OF LINE.


SELECTION-SCREEN: BEGIN OF LINE.
PARAMETERS g4 RADIOBUTTON GROUP one.
SELECTION-SCREEN: COMMENT (10) text4.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: END OF BLOCK bl_game_difficulty.


" >> High Scores table
SELECTION-SCREEN BEGIN OF BLOCK bl_high_scores.

SELECTION-SCREEN: BEGIN OF LINE.
SELECTION-SCREEN: COMMENT  (1) dummy1.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: BEGIN OF LINE.
SELECTION-SCREEN: COMMENT  (23) hstitle2.
SELECTION-SCREEN: END OF LINE.

DEFINE displ_hsline.
  selection-screen: begin of line.
  selection-screen: comment  (1) hs1_&1.
  selection-screen: comment (12) hs2_&1.
  selection-screen: comment  (5) hs3_&1.
  selection-screen: end of line.
END-OF-DEFINITION.

SELECTION-SCREEN ULINE /1(20).
displ_hsline 0.
SELECTION-SCREEN ULINE /1(20).
displ_hsline 1.
displ_hsline 2.
displ_hsline 3.
displ_hsline 4.
displ_hsline 5.
displ_hsline 6.
displ_hsline 7.
displ_hsline 8.
displ_hsline 9.

SELECTION-SCREEN: END OF BLOCK bl_high_scores.



" >> Window: Custom Game Dimensions

SELECTION-SCREEN BEGIN OF SCREEN 1001.

SELECTION-SCREEN: BEGIN OF LINE.
SELECTION-SCREEN: COMMENT (12) txtcustw.
PARAMETERS: x_size TYPE i  DEFAULT '09'.

SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: BEGIN OF LINE.
SELECTION-SCREEN: COMMENT (12) txtcusth.
PARAMETERS: y_size TYPE i  DEFAULT '09'.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN: BEGIN OF LINE.
SELECTION-SCREEN: COMMENT (12) txtcustb.
PARAMETERS: bomb_cnt TYPE i DEFAULT '10'.
SELECTION-SCREEN: END OF LINE.

SELECTION-SCREEN END OF SCREEN 1001.




" >>  modify board[ofs] and track changes
DEFINE setcell.
  board+ofs(1) = &1.

  cells2update-offset = ofs.
  cells2update-color = &1.
  append cells2update.

  if game_time1 is initial.
    get time stamp field game_time1.
  endif.
END-OF-DEFINITION.


*----------------------------------------------------------------------*
*       CLASS cl_my_gui_html_viewer DEFINITION
*----------------------------------------------------------------------*
* Custom HTML contol
*----------------------------------------------------------------------*
CLASS cl_my_gui_html_viewer DEFINITION INHERITING FROM
         cl_gui_html_viewer.
  PUBLIC SECTION.
    METHODS: constructor  IMPORTING parent TYPE REF TO cl_gui_container.
    METHODS: html_board_update.
  PRIVATE SECTION.
    METHODS: on_sapevent FOR EVENT sapevent OF cl_gui_html_viewer
                 IMPORTING action query_table.
    DATA: js TYPE STANDARD TABLE OF char255 INITIAL SIZE 1000.

ENDCLASS.                    "cl_my_gui_html_viewer DEFINITION


DATA:
    lo_dock TYPE REF TO cl_gui_docking_container,
    lo_cont TYPE REF TO cl_gui_container,
    html_control TYPE REF TO cl_my_gui_html_viewer,
    wnd_style TYPE i.


INITIALIZATION.
  hstitle1 = '   :: GAME DIFFICULTY ::'.

  text1 = 'Beginner'.
  text2 = 'Intermediate'.
  text3 = 'Expert'.
  text4 = 'Custom'.

  txtcustw = 'Width'.
  txtcusth = 'Height'.
  txtcustb = 'Bombs'.

  hstitle2 = '   :: HIGH SCORES ::'.
  hs1_0 = '#'.
  hs2_0 = 'user'.
  hs3_0 = 'time'.

  hs1_1  = '1'.
  hs1_2  = '2'.
  hs1_3  = '3'.
  hs1_4  = '4'.
  hs1_5  = '5'.
  hs1_6  = '6'.
  hs1_7  = '7'.
  hs1_8  = '8'.
  hs1_9  = '9'.




  " >> create controls
  wnd_style = cl_gui_control=>ws_thickframe + cl_gui_control=>ws_child.

  CREATE OBJECT lo_dock
    EXPORTING
      repid = sy-cprog
      dynnr = sy-dynnr
      ratio = 80
      side  = cl_gui_docking_container=>dock_at_right
      name  = 'DOCK_CONT'
      style = wnd_style.

  lo_cont = lo_dock.

  CREATE OBJECT html_control
    EXPORTING
      parent = lo_cont.

  " >>
  PERFORM game_create USING 'B' x_size y_size bomb_cnt.

  PERFORM html_load_gifs.

  PERFORM html_show.


AT LINE-SELECTION. " abap-mode, cmd 'PICK'
  ADD -1 TO sy-lsind.

  IF sy-lisel CS 'switch'.
    LEAVE LIST-PROCESSING.
  ELSE.
    CHECK game = game_in.

    PERFORM cell_get_clicked CHANGING ofs.
    CHECK ofs > 0.

    PERFORM cell_open USING ofs.
    IF rest <= 0 AND game = game_in.

      GET TIME STAMP FIELD game_time2.
      game_time = game_time2 - game_time1.

      PERFORM game_ok.
    ENDIF.
    PERFORM game_print_abap.

  ENDIF.

AT PF09.  " abap-mode, cmd 'MARK'
  ADD -1 TO sy-lsind.
  IF game = game_in.
    PERFORM cell_get_clicked CHANGING ofs.
    CHECK ofs > 0.
    PERFORM cell_mark USING ofs.
    PERFORM game_print_abap.
  ENDIF.



AT SELECTION-SCREEN OUTPUT.
  IF LINES( cells2update ) > 0.
    " here: switch back from abap to html
    CALL METHOD html_control->html_board_update( ).
  ENDIF.


AT SELECTION-SCREEN ON RADIOBUTTON GROUP one.
  CHECK sy-ucomm = 'RADIOGROUP01'.
  IF g1 = 'X'.
    PERFORM game_create USING 'B' 09 09 10.
  ELSEIF g2 = 'X'.
    PERFORM game_create USING 'I' 16 16 40.
  ELSEIF g3 = 'X'.
    PERFORM game_create USING 'E' 30 16 99.
  ELSE.
    CALL SELECTION-SCREEN 1001
         STARTING AT 20 4.
    PERFORM game_create USING 'C' x_size y_size bomb_cnt.
  ENDIF.

  PERFORM html_show.


*&---------------------------------------------------------------------*
*&      Form  game_print_abap.
*&---------------------------------------------------------------------*
FORM game_print_abap.
  DATA:  ofs TYPE i, ch TYPE c.

  SKIP TO LINE 3.

  WRITE: / 'Bombs left: ', b_left NO-ZERO.

  ofs = rdx.
  SKIP TO LINE y_ofs.

  DO y_size TIMES.
    WRITE AT x_ofs '|' NO-GAP.

    DO x_size TIMES.
      ADD 1 TO ofs.
      ch = board+ofs(1).
      CASE ch.
        WHEN blank_opened.
          WRITE: ' '.

        WHEN '1' OR '2' OR '3' OR '4' OR '5' OR '6' OR '7' OR '8'.
          WRITE: ' ' NO-GAP, ch NO-GAP.

        WHEN bomb_marked.
          WRITE icon_breakpoint AS ICON NO-GAP.

        WHEN blank_marked
        OR 'a' OR 'b' OR 'c' OR 'd' OR 'e' OR 'f' OR 'g' OR 'h'.
          WRITE icon_breakpoint AS ICON NO-GAP.

        WHEN endgame_bomb_missmark.
          WRITE icon_breakpoint_disable AS ICON NO-GAP.

        WHEN endgame_bomb_boom.
          WRITE icon_system_cancel AS ICON NO-GAP.

        WHEN bomb_opened. "endgame only
          WRITE icon_dummy AS ICON NO-GAP.

        WHEN OTHERS.
          WRITE: icon_wd_transparent_container AS ICON NO-GAP.
      ENDCASE.
    ENDDO.
    WRITE '|'.
    ADD 2 TO ofs.
    NEW-LINE.
  ENDDO.
  WRITE: AT x_ofs '' NO-GAP, '    switch back   ' COLOR 2 HOTSPOT ON.

  IF game = game_over.
    WRITE: /, /4  'Game over', /, /.
  ELSEIF   game = game_win.
    WRITE: /, /4   'You win', /, /.
  ELSE.
    SKIP 3.
  ENDIF.
  WRITE: / '   open: double-click'.
  WRITE: / '   mark: click and press F9'.
ENDFORM.                    "game_print_abap


*&---------------------------------------------------------------------*
*&      Form  CELL_MARK
*&---------------------------------------------------------------------*
*   mark a cell with 'bomb sign'
*----------------------------------------------------------------------*
FORM cell_mark USING value(ofs) TYPE i.
  DATA: ch TYPE c.
  ch = board+ofs(1).
  CASE ch.
    WHEN blank_hidden. setcell blank_marked. ADD -1 TO b_left.
    WHEN blank_marked. setcell blank_hidden. ADD +1 TO b_left.
    WHEN bomb_hidden.  setcell bomb_marked.  ADD -1 TO b_left.
    WHEN bomb_marked.  setcell bomb_hidden.  ADD +1 TO b_left.

    WHEN 'A' OR 'B' OR 'C' OR 'D' OR 'E' OR 'F' OR 'G' OR 'H'.
      TRANSLATE ch TO LOWER CASE.
      setcell   ch.      ADD -1 TO b_left.

    WHEN 'a' OR 'b' OR 'c' OR 'd' OR 'e' OR 'f' OR 'g' OR 'h'.
      TRANSLATE ch TO UPPER CASE.
      setcell  ch.       ADD +1 TO b_left.

  ENDCASE.
ENDFORM.                    "CELL_MARK



*&---------------------------------------------------------------------*
*&      Form  cell_open
*&---------------------------------------------------------------------*
*       open a cell, at one's own risk
*----------------------------------------------------------------------*
FORM cell_open USING value(ofs) TYPE i.
  CASE board+ofs(1).
    WHEN blank_hidden.
      PERFORM cell_floodfill USING ofs.
    WHEN 'A'. setcell  '1'. ADD -1 TO rest.
    WHEN 'B'. setcell  '2'. ADD -1 TO rest.
    WHEN 'C'. setcell  '3'. ADD -1 TO rest.
    WHEN 'D'. setcell  '4'. ADD -1 TO rest.
    WHEN 'E'. setcell  '5'. ADD -1 TO rest.
    WHEN 'F'. setcell  '6'. ADD -1 TO rest.
    WHEN 'G'. setcell  '7'. ADD -1 TO rest.
    WHEN 'H'. setcell  '8'. ADD -1 TO rest.
    WHEN '1' OR '2' OR '3' OR '4' OR '5' OR '6' OR '7' OR '8'.
      PERFORM cell_open_around USING ofs.
    WHEN bomb_hidden.
      setcell endgame_bomb_boom.
      PERFORM game_lose.
  ENDCASE.
ENDFORM.                    "cell_open

*&---------------------------------------------------------------------*
*&      Form  cell_get_clicked
*&---------------------------------------------------------------------*
FORM cell_get_clicked CHANGING ofs TYPE i.
  DATA: row TYPE i, col TYPE i.
  row =   sy-curow - y_ofs.
  col = ( sy-cucol - x_ofs - 2 ) DIV 2.
  ofs = ( 1 + row ) * rdx + col + 1.
  IF row < 0 OR row > y_size OR
     col < 0 OR col > x_size.
    ofs = 0.
  ENDIF.
ENDFORM.                    "cell_get_clicked



DATA: floodfill TYPE TABLE OF i INITIAL SIZE 1000.

*&---------------------------------------------------------------------*
*&      Form  cell_flood_fill
*&---------------------------------------------------------------------*
*      open all adjacent empty cells
*----------------------------------------------------------------------*
FORM cell_floodfill USING value(x) TYPE i.
  DATA: ofs TYPE i.

  ofs = x + 00. " cell itself
  setcell blank_opened. ADD -1 TO rest.

  APPEND x TO floodfill.
  LOOP AT floodfill INTO x.
    LOOP AT eight_directions.
      ofs = x + eight_directions.

      CASE board+ofs(1).
        WHEN blank_hidden.
          setcell blank_opened.  ADD -1 TO rest.
          APPEND ofs TO floodfill.
        WHEN 'A'. setcell '1'. ADD -1 TO rest.
        WHEN 'B'. setcell '2'. ADD -1 TO rest.
        WHEN 'C'. setcell '3'. ADD -1 TO rest.
        WHEN 'D'. setcell '4'. ADD -1 TO rest.
        WHEN 'E'. setcell '5'. ADD -1 TO rest.
        WHEN 'F'. setcell '6'. ADD -1 TO rest.
        WHEN 'G'. setcell '7'. ADD -1 TO rest.
        WHEN 'H'. setcell '8'. ADD -1 TO rest.
      ENDCASE.
    ENDLOOP.
  ENDLOOP.
  REFRESH floodfill.
ENDFORM.                    "cell_flood_fill



*&---------------------------------------------------------------------*
*&      Form  cell_open_eight_directions
*&---------------------------------------------------------------------*
*       Open up to 8 cells around current one
*----------------------------------------------------------------------*
FORM cell_open_around USING value(x) TYPE i.
  DATA: ofs TYPE i.
  DATA: value TYPE i.

  " 1 >> get cell's VALUE       (1 to 8)
  value = board+x(1).

  " 2 >> look around it, get count of marked
  LOOP AT eight_directions.
    ofs = x + eight_directions.
    CASE board+ofs(1).
      WHEN bomb_marked
        OR blank_marked
        OR 'a' " digit_maked
        OR 'b' " ..
        OR 'c'
        OR 'd'
        OR 'e'
        OR 'f'
        OR 'g'
        OR 'h'.
        value = value - 1.
    ENDCASE.
  ENDLOOP.

  " 3 >> check its EQness
  CHECK value = 0.

  " 4 >> here: opening is possible

  " 5 >> do open
  LOOP AT eight_directions.
    ofs = x + eight_directions.
    CASE board+ofs(1).
      WHEN blank_hidden.
        PERFORM cell_floodfill USING ofs.

      WHEN 'A'. setcell '1'. ADD -1 TO rest.
      WHEN 'B'. setcell '2'. ADD -1 TO rest.
      WHEN 'C'. setcell '3'. ADD -1 TO rest.
      WHEN 'D'. setcell '4'. ADD -1 TO rest.
      WHEN 'E'. setcell '5'. ADD -1 TO rest.
      WHEN 'F'. setcell '6'. ADD -1 TO rest.
      WHEN 'G'. setcell '7'. ADD -1 TO rest.
      WHEN 'H'. setcell '8'. ADD -1 TO rest.

      WHEN blank_marked
        OR 'a'
        OR 'b'
        OR 'c'
        OR 'd'
        OR 'e'
        OR 'f'
        OR 'g'
        OR 'h'.
        setcell endgame_bomb_missmark.

      WHEN bomb_hidden.
        setcell endgame_bomb_boom.
        PERFORM game_lose.
    ENDCASE.

  ENDLOOP.
ENDFORM.                    "cell_open_eight_directions



*&---------------------------------------------------------------------*
*&      Form  game_lose
*&---------------------------------------------------------------------
FORM game_lose.

  game = game_over.
  ADD -1 TO b_left.
  " >> show actual bombs
  WHILE board(square2) CA '*abcdefghm'. "  digit_marked + blank_marked
    ofs = sy-fdpos.
    IF board+ofs(1) = bomb_hidden. " if  = '*'
      setcell bomb_opened.
    ELSE.
      setcell endgame_bomb_missmark.
    ENDIF.
  ENDWHILE.

  MESSAGE s000(su) WITH 'Game over'.
ENDFORM.                                                    "game_lose


*&---------------------------------------------------------------------*
*&      Form  game_ok
*&---------------------------------------------------------------------*
FORM game_ok.

  game = game_win.
  b_left = 0.
  " >> show bombs
  WHILE board(square2) CS bomb_hidden.
    ofs = sy-fdpos.
    setcell bomb_marked.
  ENDWHILE.

  MESSAGE s000(su) WITH 'You win!' .

  CHECK game_size <> 'C'.

  PERFORM high_scores_read.
  PERFORM high_scores_update.
  PERFORM high_scores_show.

ENDFORM.                                                    "game_ok


*&---------------------------------------------------------------------*
*&      Form  game_create
*&---------------------------------------------------------------------*
FORM game_create USING
     value(sz)  TYPE c
     value(x)   TYPE i
     value(y)   TYPE i
     value(b)   TYPE i.

  DATA:
     ofs        TYPE i,
     j          TYPE i,
     drop_cnt   TYPE i,
     drop_bombs TYPE c.
  DATA:
     prng TYPE REF TO cl_abap_random_int,
     backgr     TYPE c,
     foregr     TYPE c,
     half       TYPE i.


  game_size = sz.
  x_size = x.
  y_size = y.
  bomb_cnt = b.

  CONCATENATE database_id_prefix game_size INTO database_id.

  CLEAR:
    game_time,
    game_time1,
    game_time2.

  game = game_in.

  PERFORM high_scores_read.
  PERFORM high_scores_show.

  CLEAR: board.

  square = x_size * y_size.
  IF bomb_cnt > square.
    bomb_cnt = square. " limit bombs to 100%
  ENDIF.
  b_left = bomb_cnt.

  rest = square - bomb_cnt. " empty places to invent

  rdx =  2 + x_size. " width  + left and right  border
  rdy =  2 + y_size. " height + top  and button border

  square2 = rdx * rdy.

  IF square2 > 9999.
    MESSAGE e000(su)  WITH 'board too large (9999)'.
  ENDIF.

  " >>  board[9999]'s used space
  min = 1 + 1 * rdx.       " topleft
  max = square2 - rdx - 2. " bottomright
  range = max - min + 1.

  " >> directions
  REFRESH eight_directions.
  eight_directions = -1 + rdx * -1.  APPEND eight_directions. " NW
  eight_directions = 00 + rdx * -1.  APPEND eight_directions. " North
  eight_directions = +1 + rdx * -1.  APPEND eight_directions. " NE
  eight_directions = -1 + rdx * 00.  APPEND eight_directions. " W
  eight_directions = +1 + rdx * 00.  APPEND eight_directions. " E
  eight_directions = -1 + rdx * +1.  APPEND eight_directions. " SW
  eight_directions = 00 + rdx * +1.  APPEND eight_directions. " S
  eight_directions = 01 + rdx * +1.  APPEND eight_directions. " SE

  " >> bomb placement

  " >>   speed optimization:
  "        if bombs < 50%, place bombs  randomly
  "        if bombs > 50%, place spaces randomly

  half = x_size * y_size DIV 2.
  IF bomb_cnt < half.
    drop_bombs = 'X'.     " straight order
    drop_cnt = bomb_cnt.
    backgr = blank_hidden.
    foregr = bomb_hidden.
  ELSE.
    drop_bombs = ' '.     " reversed order
    drop_cnt = rest.
    backgr = bomb_hidden.
    foregr = blank_hidden.
  ENDIF.

  " >> fill background
  ofs = min.
  DO range TIMES.
    board+ofs(1) = backgr.
    ADD 1 TO ofs.
  ENDDO.

  " >> horizontal border
  DO rdx TIMES.

    ofs = sy-index - 1.
    board+ofs(1) = border.

    ofs = square2 - sy-index .
    board+ofs(1) = border.
  ENDDO.
  " >> vertical border
  DO y_size TIMES.
    ofs = rdx * sy-index.
    board+ofs(1) = border.
    ofs = sy-index * rdx + rdx - 1.
    board+ofs(1) = border.
  ENDDO.


  " >> actual placement
  DATA: seed TYPE i.
  seed = cl_abap_random=>seed( ).


  prng = cl_abap_random_int=>create(
   seed = seed min = min max = max ).

  DO drop_cnt TIMES.
    DO.
      ofs = prng->get_next( ).

      CASE board+ofs(1).
        WHEN foregr OR border.
          " skip used cells
        WHEN OTHERS.
          EXIT. " found unused (BG 1 2 3 4 5 6 7 8)
      ENDCASE.
    ENDDO.

    board+ofs(1) = foregr.

    IF drop_bombs = 'X'.
      " add 1 point to cells around
      LOOP AT eight_directions.
        j = ofs + eight_directions.
        CASE board+j(1).
          WHEN bomb_hidden OR border.

          WHEN OTHERS.
            board+j(1) = board+j(1) + 1.
        ENDCASE.
      ENDLOOP.
    ELSE.
      " get 1 point from every bomb around
      LOOP AT eight_directions.
        j = ofs + eight_directions.
        CASE board+j(1).
          WHEN bomb_hidden.
            board+ofs(1) = board+ofs(1) + 1.
        ENDCASE.
      ENDLOOP.
    ENDIF.
  ENDDO.

  " >> hide digits
  TRANSLATE board(square2) USING '1A2B3C4D5E6F7G8H'.

ENDFORM.                    "game_create








*----------------------------------------------------------------------*
*       CLASS my_cl_gui_html_viewer IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_my_gui_html_viewer IMPLEMENTATION.

  METHOD constructor.
    DATA: myevent_tab TYPE cntl_simple_events,
          myevent TYPE cntl_simple_event.

    CALL METHOD super->constructor(
      parent = parent
      uiflag = html_control->uiflag_noiemenu
      ).

    myevent-appl_event = 'X'.
    myevent-eventid = html_control->m_id_sapevent.
    APPEND myevent TO myevent_tab.
    myevent-eventid = html_control->m_id_navigate_complete.
    APPEND myevent TO myevent_tab.

    CALL METHOD html_control->set_registered_events(
      events = myevent_tab
      ).

    SET HANDLER me->on_sapevent FOR html_control.

  ENDMETHOD.                    "constructor

  " >> HTML callback event
  METHOD on_sapevent.  " arguments:  action, query_table[]
    DATA: param LIKE LINE OF query_table.
    DATA: cell_ofs TYPE i.


    READ TABLE query_table WITH KEY name = 'ID' INTO param.
    IF sy-subrc EQ 0.  cell_ofs = param-value. ENDIF.

    READ TABLE query_table WITH KEY name =  'TIME' INTO param.
    IF sy-subrc EQ 0.  game_time = param-value. ENDIF.

    CASE action.

      WHEN 'click'.    " left-click
        CHECK game = game_in.
        PERFORM cell_open USING cell_ofs.
        IF rest <= 0 AND game = game_in.
          PERFORM game_ok.
        ENDIF.
        CALL METHOD me->html_board_update( ).

      WHEN 'mouseup'.   " right-click
        CHECK game = game_in.
        PERFORM cell_mark USING cell_ofs.
        CALL METHOD me->html_board_update( ).

      WHEN 'newgame'.
        PERFORM game_create USING game_size x_size y_size bomb_cnt.
        PERFORM html_show.

      WHEN 'switch'.
        LEAVE TO LIST-PROCESSING.
        SET PF-STATUS space.
        PERFORM game_print_abap.
    ENDCASE.

  ENDMETHOD.                    "on_sapevent

  " >> transport board[]'s changes (saved in cells2update[]), to HTML
  METHOD html_board_update.
    DATA: ofs TYPE i, new TYPE i, len TYPE i, end TYPE i.
    DATA: buf TYPE string.
    DATA: jsline LIKE LINE OF js.

    " >> convert cells2update[] to plain string
    CONCATENATE LINES OF cells2update INTO buf SEPARATED BY '|'.
    CONDENSE buf NO-GAPS.

    " >> convert plain string to JavaScript code
    "    and pack it to HTML_VIEWER's compatible table
    ofs = 0.
    end = STRLEN( buf ).

    WHILE ofs < end.
      new = ofs + 249. "    255 - strlen ( b+=""; ) is 249

      IF new > end. "
        len = end - ofs.
      ELSE.
        len = 249.
      ENDIF.

      CONCATENATE 'b+="' buf+ofs(len) '";'  INTO jsline.
      APPEND jsline TO js.

      ofs = ofs + len.
    ENDWHILE.


    CONCATENATE 'updateCells(' game ',"' b_left+1 '")' INTO jsline.
    APPEND jsline TO js.

    " >> actual transfer
    CALL METHOD me->set_script( script = js[] ).
    CALL METHOD me->execute_script( ).


    " >>
    REFRESH js.
    REFRESH cells2update.

  ENDMETHOD.                    "html_board_update

ENDCLASS.                    "cl_my_gui_html_viewer IMPLEMENTATION


*&---------------------------------------------------------------------*
*&      Form  html_create
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->S          text
*----------------------------------------------------------------------*
FORM html_create TABLES html.
  DATA: html_str TYPE string, s TYPE string,
        table1 TYPE TABLE OF char255 WITH HEADER LINE INITIAL SIZE 150.


  IF 1 = 2.

"    CALL FUNCTION 'WS_UPLOAD'
"      EXPORTING
"        filename = 'C:\SAP\game\source.html'
"        filetype = 'ASC'
"      TABLES
"        data_tab = html[]
"      EXCEPTIONS
"        OTHERS   = 1.
"    CHECK sy-subrc EQ 0.
"
"    CONCATENATE LINES OF html INTO html_str SEPARATED BY '~'.

  ELSE.


    " >>  create html
    CONCATENATE

      '<html><head>'
  '<meta http-equiv="content-type" content="text/html">'
  '<style type="text/css">'
  '*    { font: bold 12px sans-serif}'
  'span { position: absolute;  width: 16px; height: 16px;'
  '       font-size: 6pt;      background: url("blank.gif")}'
  'div  { background: silver;  margin: 8px 0;'
  '       text-align: center;  border: 2px inset white}'
  'td   { text-align: center;  padding: 0}'
  'td div{height: 24px;        width: 30px; margin: 0;'
  '       padding: 3px;        border: 1px gray solid}'
  '#wMain{position: absolute;  padding: 0 8px;'
  '       border: 2px outset white}'
  '#wTool{height: 34px}'
  '</style>'

  '<script>'
  'var DX=10, DY=10, BB=98,'
  '    game=1, tID, tm=0,    mouse_left=0, mouse_right=2,'
  '    images=[], SZ=16, x, y, b="",'
  '    imagesInfo = ['
  '   "blank *0ABCDEFGH",'

  '   "bombdeath X",        "bombrevealed &",'
  '   "bombmisflagged @",   "bombflagged mMabcdefgh",'

  '   "open1 1",   "open2 2",   "open3 3",'
  '   "open4 4",   "open5 5",   "open6 6",'
  '   "open7 7",   "open8 8",   "open0 ."'
  '];'

  '/*VARIABLES_INITIALIZATION_HERE_DONT_DELETE*/'

  'function init(){'
  '  c1.innerText = BB;'

  '  c2.onclick        = abapHandler("IMG" , mouse_left, "newgame");'
  '  document.onclick  = abapHandler("SPAN", mouse_left,   "click");'
  '  document.onmouseup= abapHandler("SPAN", mouse_right,"mouseup");'

  '  var p, w = DX*SZ+4;  var h = DY*SZ+4;'
  '  setSize(wBrd,  w, h);'
  '  setSize(wMain, w+20);'
  '  map(imagesInfo, function(x){'
  '      map((p = x.split(" "))[1].split(""),'
  '        function(ch){images[ch]=p[0]+".gif"})}'
  '  )'
  '}'

  'function updateCells(game_state, bomb_left){'
  '  game = game_state;  c1.innerText = bomb_left;'

  '  var x, i, seq = b.split("|"); b = "";'
  '  for(i=0;i<seq.length;i++)'
  '    if (x=seq[i]) with(document.getElementById("x"+x.slice(0,-1)))'
  '       style.backgroundImage = "url("+images[x.slice(-1)]+")";'
  '  if (game==2) {clearTimeout(tID); c2.src = "facedead.gif"}'
  '  if (game==3) {clearTimeout(tID); c2.src = "facewin.gif" }'
  '}'

  'function abapHandler(tag, mouse_button, action){'
  '  return('
  '    function(){'
  '      var ev = window.event, obj = ev.srcElement;'
  '      if (obj.nodeName == tag && ev.button==mouse_button) {'
  '        tID = tID ? tID : setTimeout("onTimer()", 1000);'
  '        callback.href ='
  '          "SAPEVENT:"+action+"?ID="+obj.id.slice(1)+"&TIME="+tm;'
  '        callback.click();'
  '      }'
  '    }'
  '  )'
  '}'

  'function onTimer(){'
  '  c3.innerText = ++tm;'
  '  tID = (game==1) ? setTimeout("onTimer()", 1000) : tID;'
  '}'

  'function setSize(obj, w, h){'
  '  obj.style.width = w;'
  '  if (h) obj.style.height = h;'
  '}'

  'function map(list, func){'
  '  var a = new Array(list.length);'
  '  for (var i=0;i<list.length;i++) a[i]=func(list[i],i);'
  '  return a;'
  '}'
  '</script></head>'


  '<body onload="init()">'
  '<div id=wMain>'
  '<div id=wTool><table border=0 id=wHdr>'
  '<tr>'
  ' <td width=34px><div id=c1>0</div></td>'
  ' <td width=100%><img id=c2 src="facesmile.gif"></td>'
  ' <td width=34px><div id=c3>0</div></td>'
  '</tr></table></div>'
  '<div id=wBrd>'
  '<script>'
  '  for(y=0;y<DY;y++) for(x=0;x<DX;x++) document.write('
  '    "<span id=x"+((y+1)*(DX+2)+x+1)+" style=\"left:"'
  '    +(10+SZ*x)+"px;top:"+(52+SZ*y)+"px;\"></span>")'
  '</script>'
  '</div>'
  '<div><a id=btnSwitch href="SAPEVENT:switch?0">'
  'switch to ABAP</a>'
  '</div></div>'
  '<a id=callback style="display:none"'
  '  href="SAPEVENT:click?dummy">SAPEVENT:click</a>'
  '</body>'
  '</html>'


    INTO html_str SEPARATED BY '~'.

  ENDIF.

  CONDENSE html_str.



  " >> patch html with game parameters
  DATA: xstr(4) TYPE c, ystr(4) TYPE c.
  WRITE x_size TO xstr NO-GROUPING.
  WRITE y_size TO ystr NO-GROUPING.

  CONCATENATE 'DX=' xstr ',DY=' ystr ',BB="' b_left '";' INTO s.

  REPLACE FIRST OCCURRENCE OF
   '/*VARIABLES_INITIALIZATION_HERE_DONT_DELETE*/'
   IN html_str WITH s.

  IF sy-subrc <> 0.
    MESSAGE e000(su) WITH 'html template is broken'.
  ENDIF.

  "  >> performance improvement: condense html to width 255,
  "         to reduce whitespaces sent to client

  SPLIT html_str AT '~' INTO TABLE table1.

  DATA: ofs TYPE i, len TYPE i, nex TYPE i.

  REFRESH html.
  ofs = 0.
  LOOP AT table1.
    len = STRLEN( table1 ).
    CHECK len > 0.
    nex = ofs + len.

    IF nex < 255.
      html+ofs(len) = table1.
      ofs = nex.
    ELSE.
      APPEND html.
      html = table1.
      ofs = len.
    ENDIF.
  ENDLOOP.
  APPEND html.

ENDFORM.                    "html_create

*&---------------------------------------------------------------------*
*&      Form  load_graphics
*&---------------------------------------------------------------------*
*       create GIF-images from scratch
*----------------------------------------------------------------------*
FORM html_load_gifs.


  PERFORM html_load_gif USING 'open0.gif'
       'R0lGODlhEAAQAIAAAHt7e729vSH5BAAAAAAALAAAAAAQABAAA'
       'AIdhI9pwe0PnnRxzmphlniz7oGbmJGWeXmU2qAcyxQAOw=='
       '' '' '' ''.

  PERFORM html_load_gif USING 'open1.gif'
       'R0lGODlhEAAQAJEAAAAA/3t7e729vQAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIpjI9pwu0fnnRRAiCruxg+3lEbmFlX+Z1eGjZaw6'
       'EMGLsjLU7Tq9v9UwAAOw==' '' '' ''.

  PERFORM html_load_gif USING 'open2.gif'
       'R0lGODlhEAAQAJEAAAB7AHt7e729vQAAACH5BAAAAAAALAAAA'
       'AAQABAAAAItjI9pwu0fnnSRgYsvtbm3ijkhU02jUIon+ngbt3'
       '4wMJFzR9sCnsm1lPrphI0CADs=' '' '' ''.

  PERFORM html_load_gif USING 'open3.gif'
       'R0lGODlhEAAQAJEAAHt7e729vf8AAAAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIshI9pwe0PnnQxiIsxZbmLVk0aE0pjUFrd5niseI'
       'ETF5O0V6O3K89S6tMFHQUAOw==' '' '' ''.

  PERFORM html_load_gif USING 'open4.gif'
       'R0lGODlhEAAQAJEAAAAAe3t7e729vQAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIujI9pwu0fnnSxgSsuoE5n3FTfNnKMV4anxoJC1b'
       'bqhDLiU79Tau/5vZsFTcNGAQA7' '' '' ''.

  PERFORM html_load_gif USING 'open5.gif'
       'R0lGODlhEAAQAJEAAHsAAHt7e729vQAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIpjI9pwu0fnnRRgItzq7mDzWATaF0jw3kmqYro6Q'
       'rVFKcte5MntUO9UwAAOw==' '' '' ''.

  PERFORM html_load_gif USING 'open6.gif'
       'R0lGODlhEAAQAJEAAAB7e3t7e729vQAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIsjI9pwu0fnnSRgYsvtTlvgU1NFYoC2ZUMmmorBz'
       'gqK7sn3I5NG+sm9AMGGwUAOw==' '' '' ''.

  PERFORM html_load_gif USING 'open7.gif'
       'R0lGODlhEAAQAJEAAAAAAHt7e729vQAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIqjI9pwu0fnnRRgItzq7mDPTEYGI5MJZlneVGTuq'
       'at+8CxYwtoSPO9zygAADs=' '' '' ''.

  PERFORM html_load_gif USING 'open8.gif'
       'R0lGODlhEAAQAIAAAHt7e729vSH5BAAAAAAALAAAAAAQABAAA'
       'AIphI9pwe0PnnSRqdXqPdliXwXaJ37hRmVXWoZt96onuFpywk'
       '6Sq8O9UwAAOw==' '' '' ''.

  PERFORM html_load_gif USING 'blank.gif'
       'R0lGODlhEAAQAJEAAHt7e729vf///wAAACH5BAAAAAAALAAAA'
       'AAQABAAAAIqlI8ZyRdggpxUAiiqfnjXG3kTmIlWZ3KhSaZqya'
       'LxKrYpyF36ruf8DygAADs=' '' '' ''.

  PERFORM html_load_gif USING 'bombdeath.gif'
       'R0lGODlhEAAQAJEAAAAAAHt7e/8AAP///yH5BAAAAAAALAAAA'
       'AAQABAAAAI0jI9pwu0fHgNSREnlFRR4zzUb933O5g1DmVlNup'
       'YiydbuVIMMmrdjfnrRQL5KK4ipjCqOAgA7' '' '' ''.

  PERFORM html_load_gif USING 'bombflagged.gif'
       'R0lGODlhEAAQAKIAAAAAAHt7e729vf8AAP///wAAAAAAAAAAA'
       'CH5BAAAAAAALAAAAAAQABAAAAM8SLrc0nCJoIS92AZK8hjZVl'
       'nfF3JkCWJil5osisFXmwnAOWJ5vOOAoM8VLBY1MqMR+bsxJ5u'
       'oVAqdWjcJADs='  '' ''.

  PERFORM html_load_gif USING 'bombmisflagged.gif'
       'R0lGODlhEAAQAKIAAAAAAHt7e729vf8AAP///wAAAAAAAAAAA'
       'CH5BAAAAAAALAAAAAAQABAAAANEGLrcKjDKGSYEVtQxJI6cBo'
       'VAWQqhOA5mmaoCwBEuG1WXzHInVLU6Vgtm4gg/RJ0SiVsVOzf'
       'QsRZFQWNSn9UjCTUzkwQAOw==' '' ''.

  PERFORM html_load_gif USING 'bombrevealed.gif'
       'R0lGODlhEAAQAJEAAAAAAHt7e729vf///yH5BAAAAAAALAAAA'
       'AAQABAAAAI0jI9pwu0fHgNSREnlFRR4zzUb933O5g1DmVlNup'
       'YiydbuVIMMmrdjfnrRQL5KK4ipjCqOAgA7' '' '' ''.

  PERFORM html_load_gif USING 'facedead.gif'
       'R0lGODlhGgAaAKIAAAAAAHt7e729vf//AP///wAAAAAAAAAAA'
       'CH5BAAAAAAALAAAAAAaABoAAAOAGLrcziKQSau9M0rMr95CKI'
       '4kyWRlWp6ECrxvypbvYNvxOI/A7eO6BSrU+/0Aop2g2CsOmsA'
       'PiHhz4qqhnRN63UpRVuPx21qKz0jtWZwWlsOwmq+tGG6PWLKI'
       'yY4qzWtPSW4kYXNBdWU8cEiIUzRxMoQqlFlCUg+ZDZianZydm'
       'gkAOw=='.

  PERFORM html_load_gif USING 'facesmile.gif'
       'R0lGODlhGgAaAKIAAAAAAHt7e729vf//AP///wAAAAAAAAAAA'
       'CH5BAAAAAAALAAAAAAaABoAAAN/GLrcziKQSau9M0rMr95CKI'
       '4kyWRlWp6ECrxvypbvYNvxOI/A7eO6BSrU+/0Aop2gaDyGlMw'
       'aLvoUtpY+6UC7/YCwzSZyxwxnvaiyGUi+qXFu9BW8PcblojKM'
       'i8Tn111VCkNEZn2CXzxqOUlWLnsyjiqTiC0Pl5hemJsBmpyYC'
       'QA7'.

  PERFORM html_load_gif USING 'facesmile.gif'
       'R0lGODlhGgAaAKIAAAAAAHt7e729vf//AP///wAAAAAAAAAAA'
       'CH5BAAAAAAALAAAAAAaABoAAAN/GLrcziKQSau9M0rMr95CKI'
       '4kyWRlWp6ECrxvypbvYNvxOI/A7eO6BSrU+/0Aop2gaDyGlMw'
       'aLvoUtpY+6UC7/YCwzSZyxwxnvaiyGUi+qXFu9BW8PcblojKM'
       'i8Tn111VCkNEZn2CXzxqOUlWLnsyjiqTiC0Pl5hemJsBmpyYC'
       'QA7'.

  PERFORM html_load_gif USING 'facewin.gif'
       'R0lGODlhGgAaAKIAAAAAAHt7AHt7e729vf//AP///wAAAAAAA'
       'CH5BAAAAAAALAAAAAAaABoAAAOEKLrczkOUSau9M0rMr95DKI'
       '4kyWRlWp6FCrxvypYvYdvxOI/A7eO6BSrU+/0Aot2gaDyGlEW'
       'YtEZAfkBLnLS6rV5RvTCMWwt/W8tigMoNaM/Ephy5Y8p9dCE6'
       'izverFB4XUBwInZNVoWGd4mKhoc5SXouUjKTKphPQlcPnQ2cn'
       'qGgoZ4JADs='.
ENDFORM.                    "html_load_gifs

*&---------------------------------------------------------------------*
*&      Form  create_gif
*&---------------------------------------------------------------------*
FORM  html_load_gif USING
        image_name TYPE c
        s1 TYPE c
        s2 TYPE c
        s3 TYPE c
        s4 TYPE c
        s5 TYPE c
        s6 TYPE c.

  DATA: gif_size  TYPE i,
        gif_base64 TYPE string,
        gif_binary TYPE xstring,
        gif_binary_table TYPE TABLE OF w3mime.

  CONCATENATE s1 s2 s3 s4 s5 s6 INTO gif_base64.

  CALL FUNCTION 'SSFC_BASE64_DECODE'
    EXPORTING
      b64data = gif_base64
    IMPORTING
      bindata = gif_binary
    EXCEPTIONS
      OTHERS  = 1.
  CHECK sy-subrc EQ 0.

  PERFORM xstring_to_table
     TABLES     gif_binary_table
     USING      gif_binary
     CHANGING   gif_size.

  CALL METHOD html_control->load_data
    EXPORTING
      url                  = image_name
      type                 = 'image'
      subtype              = 'gif'
      size                 = gif_size
    CHANGING
      data_table           = gif_binary_table
    EXCEPTIONS
      dp_invalid_parameter = 1
      dp_error_general     = 2
      cntl_error           = 3
      OTHERS               = 4.
ENDFORM.                    "html_load_gif


*---------------------------------------------------------------------*
*       FORM XSTRING_TO_TABLE                                         *
*---------------------------------------------------------------------*
*       convert xstring to xtable[255]
*---------------------------------------------------------------------*
FORM xstring_to_table
    TABLES    table1
    USING     buffer TYPE  xstring
    CHANGING  binary_size TYPE i.

  DATA: rows TYPE i, pos TYPE i.
  FIELD-SYMBOLS:   <fs> TYPE x.

  ASSIGN COMPONENT 0 OF STRUCTURE table1 TO <fs> TYPE 'X'.
  binary_size = XSTRLEN( buffer ).
  rows = ( binary_size + 255 - 1 ) DIV 255.
  DO rows TIMES.
    <fs> = buffer+pos.
    pos = pos + 255.
    APPEND table1.
  ENDDO.
ENDFORM.                    "xstring_to_table


*&---------------------------------------------------------------------*
*&      Form  html_show
*&---------------------------------------------------------------------*
FORM html_show.
  DATA: doc_url(80),
        html TYPE TABLE OF w3html INITIAL SIZE 150.

  PERFORM html_create TABLES html.

  CALL METHOD html_control->load_data(
     IMPORTING  assigned_url = doc_url
     CHANGING   data_table  = html
      EXCEPTIONS
       dp_invalid_parameter = 1
       dp_error_general     = 2
       cntl_error           = 3
       OTHERS               = 4
   ).

  CALL METHOD html_control->show_url( url = doc_url ).

ENDFORM.                                                    "html_show






*---------------------------------------------------------------------*
*       FORM high_scores_read                                         *
*---------------------------------------------------------------------*
FORM high_scores_read.
  REFRESH high_scores.
  IMPORT lines = high_scores[] FROM DATABASE indx(st) ID database_id.
ENDFORM.                    "high_scores_read


*---------------------------------------------------------------------*
*       FORM high_scores_show                                         *
*---------------------------------------------------------------------*
FORM high_scores_show.
  DATA: s(6) TYPE c, line TYPE c.
  FIELD-SYMBOLS: <fs1> TYPE c, <fs2> TYPE c.

  DO 9 TIMES.
    line = sy-index.
    CONCATENATE 'hs2_' line INTO s.
    ASSIGN (s) TO <fs1>.
    CONCATENATE 'hs3_' line INTO s.
    ASSIGN (s) TO <fs2>.
    READ TABLE high_scores INDEX sy-index.
    IF sy-subrc EQ 0.
      <fs1> = high_scores-user.
      <fs2> = high_scores-time.
    ELSE.
      CLEAR: <fs1>, <fs2>.
    ENDIF.
  ENDDO.
ENDFORM.                    "high_scores_show



*---------------------------------------------------------------------*
*       FORM high_scores_update                                       *
*---------------------------------------------------------------------*
FORM high_scores_update.

  high_scores-user = sy-uname.
  WRITE game_time TO high_scores-time RIGHT-JUSTIFIED.

  INSERT high_scores INTO TABLE high_scores[].

  LOOP AT high_scores FROM 10.
    DELETE high_scores INDEX sy-tabix.
  ENDLOOP.

  EXPORT lines = high_scores[] TO DATABASE indx(st) ID database_id.
ENDFORM.                    "high_scores_update
Back to top
View user's profile Send private message Blog
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> Programming Techniques | Приемы программирования -> Games All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
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.