REPORT z_memory. *---------------------------------------------------------------------* * Memory Game * * From a copy of http://www.oocities.org/ralfonsii/abap_4_fun.htm * *---------------------------------------------------------------------* * Author : Ralf Rubel (http://www.ralf-rubel.de/ ) / Michel PIOUD * * Email : mpioud@yahoo.fr HomePage : http://www.oocities.org/mpioud * *---------------------------------------------------------------------* * Create the report Z_MEMORY * * Create the dynpro 0100 * * Upload the dynpro 0100 * * from http://www.oocities.org/mpioud/Z_MEMORY_screen_0100.txt * * Create the status BASE with the BACK, EXIT, CANCEL functions * *---------------------------------------------------------------------* SELECTION-SCREEN BEGIN OF BLOCK b0 WITH FRAME. PARAMETERS : p_row TYPE n DEFAULT 4 OBLIGATORY, p_col TYPE n DEFAULT 4 OBLIGATORY. SELECTION-SCREEN SKIP. PARAMETERS : p_wait TYPE n DEFAULT 2 OBLIGATORY. SELECTION-SCREEN SKIP. PARAMETERS : p_random AS CHECKBOX DEFAULT 'X', p_option AS CHECKBOX DEFAULT 'X'. SELECTION-SCREEN END OF BLOCK b0. *---------------------------------------------------------------------* AT SELECTION-SCREEN. IF p_row < 2 OR p_row > 8. MESSAGE e002(sy) WITH ''. ENDIF. IF p_col < 2 OR p_col > 8. MESSAGE e002(sy) WITH ''. ENDIF. *---------------------------------------------------------------------* * Eventhandler CLASS lcl_event_handler DEFINITION. PUBLIC SECTION. CLASS-METHODS on_control_click FOR EVENT control_click OF cl_gui_picture IMPORTING sender. ENDCLASS. *---------------------------------------------------------------------* TYPES: BEGIN OF ty_boardline, visible(1), ico(4), icon TYPE i, index TYPE i, row TYPE i, column TYPE i, count TYPE i, picture TYPE REF TO cl_gui_picture, container TYPE REF TO cl_gui_container, END OF ty_boardline, BEGIN OF ty_highscoreline, no(2), name(12), date(10), time(5), score(6), END OF ty_highscoreline. *---------------------------------------------------------------------* * register events at control framework DATA g_row TYPE i. DATA g_line TYPE i. DATA g_row_col TYPE numc3. DATA wa_events TYPE cntl_simple_event. DATA events TYPE cntl_simple_events. DATA g_row_m_1 TYPE i. DATA wa_board TYPE ty_boardline. DATA wa_cell_first TYPE ty_boardline. DATA wa_cell_second TYPE ty_boardline. DATA gt_board TYPE TABLE OF ty_boardline. DATA score TYPE i. DATA container TYPE REF TO cl_gui_custom_container. DATA splitter TYPE REF TO cl_gui_splitter_container. DATA first_clicked TYPE REF TO cl_gui_picture. DATA second_clicked TYPE REF TO cl_gui_picture. DATA event_handler TYPE REF TO lcl_event_handler. DATA g_counter TYPE i. DATA pairs_left TYPE i. DATA wa_highscore TYPE ty_highscoreline. DATA gt_highscore TYPE TABLE OF ty_highscoreline. DATA tx_container TYPE REF TO cl_gui_custom_container. DATA tx_editor TYPE REF TO cl_gui_textedit. DATA wa_lines TYPE tline. DATA gt_lines TYPE TABLE OF tline. DATA svcode TYPE syucomm. DATA okcode TYPE syucomm. DATA objects_created TYPE flag. DATA g_indx_key(10) VALUE 'MEMORY'. *---------------------------------------------------------------------* START-OF-SELECTION. g_row = p_row. g_line = p_col. g_row_m_1 = p_row - 1. g_row_col = p_row * p_col. pairs_left = ( ( p_row * p_col ) - 1 ) / 2. CONCATENATE g_indx_key g_row_col INTO g_indx_key. CALL SCREEN 100. *---------------------------------------------------------------------* * Module USER_COMMAND_0100 INPUT *---------------------------------------------------------------------* MODULE user_command_0100 INPUT. svcode = okcode. CLEAR okcode. CASE svcode. WHEN 'BACK'. PERFORM housekeeping. SET SCREEN 0. WHEN 'EXIT'. PERFORM housekeeping. SET SCREEN 0. WHEN 'ZRESET'. PERFORM f_reset. EXPORT gt_lines TO DATABASE indx(st) ID g_indx_key. SET SCREEN 0. ENDCASE. ENDMODULE. " USER_COMMAND_0100 INPUT *---------------------------------------------------------------------* * Module EXIT INPUT *---------------------------------------------------------------------* MODULE exit INPUT. CASE okcode. WHEN 'EXIT'. PERFORM housekeeping. LEAVE PROGRAM. WHEN 'CANCEL'. PERFORM housekeeping. SET SCREEN 0. ENDCASE. ENDMODULE. " EXIT INPUT *---------------------------------------------------------------------* * Module STATUS_0100 OUTPUT *---------------------------------------------------------------------* MODULE status_0100 OUTPUT. SET PF-STATUS 'BASE'. SET TITLEBAR 'BAS'. PERFORM create_objects. ENDMODULE. " STATUS_0100 OUTPUT *---------------------------------------------------------------------* * Form SHOW_CELL *---------------------------------------------------------------------* FORM show_cell USING u_row TYPE i u_column TYPE i u_container TYPE REF TO cl_gui_container u_picture TYPE REF TO cl_gui_picture u_icon TYPE icon_d. CALL METHOD splitter->get_container EXPORTING row = u_row column = u_column RECEIVING container = u_container. IF u_picture IS INITIAL. CREATE OBJECT u_picture EXPORTING parent = u_container. * Register events wa_events-eventid = u_picture->eventid_control_click. APPEND wa_events TO events. CALL METHOD u_picture->set_registered_events EXPORTING events = events. SET HANDLER event_handler->on_control_click FOR u_picture. ENDIF. IF NOT u_icon IS INITIAL. CALL METHOD u_picture->load_picture_from_sap_icons EXPORTING icon = u_icon. CALL METHOD u_picture->set_display_mode EXPORTING display_mode = cl_gui_picture=>display_mode_fit_center. ENDIF. ENDFORM. " SHOW_CELL *---------------------------------------------------------------------* * CLASS lcl_event_handler IMPLEMENTATION *---------------------------------------------------------------------* CLASS lcl_event_handler IMPLEMENTATION. METHOD on_control_click. * First_clicked IF first_clicked IS INITIAL. READ TABLE gt_board INTO wa_cell_first WITH KEY picture = sender. IF wa_cell_first-visible IS INITIAL AND NOT wa_cell_first-ico IS INITIAL. * Show icon PERFORM show_cell USING wa_cell_first-row wa_cell_first-column wa_cell_first-container wa_cell_first-picture wa_cell_first-ico. first_clicked = sender. ADD 1 TO wa_cell_first-count. ENDIF. * Second_clicked ELSE. CHECK sender <> first_clicked. READ TABLE gt_board INTO wa_cell_second WITH KEY picture = sender. IF wa_cell_second-visible IS INITIAL AND NOT wa_cell_second-ico IS INITIAL. * Show icon PERFORM show_cell USING wa_cell_second-row wa_cell_second-column wa_cell_second-container wa_cell_second-picture wa_cell_second-ico. second_clicked = sender. ADD 1 TO wa_cell_second-count. ENDIF. ENDIF. * Pair visible IF NOT first_clicked IS INITIAL AND NOT second_clicked IS INITIAL. IF wa_cell_first-icon = wa_cell_second-icon. wa_cell_first-visible = wa_cell_second-visible = 'X'. MODIFY gt_board FROM wa_cell_first INDEX wa_cell_first-index. MODIFY gt_board FROM wa_cell_second INDEX wa_cell_second-index. pairs_left = pairs_left - 1. ELSE. MODIFY gt_board FROM wa_cell_first INDEX wa_cell_first-index. MODIFY gt_board FROM wa_cell_second INDEX wa_cell_second-index. IF p_option = 'X' AND ( wa_cell_first-count > 1 OR wa_cell_second-count > 1 ). MESSAGE i319(01) WITH 'Game over'. LEAVE TO SCREEN 0. ENDIF. CALL METHOD cl_gui_cfw=>update_view. WAIT UP TO p_wait SECONDS. CALL METHOD wa_cell_first-picture->clear_picture. CALL METHOD wa_cell_second-picture->clear_picture. ENDIF. CLEAR: first_clicked, second_clicked, wa_cell_first, wa_cell_second. * Cause field transport when scored score = score + 1. CALL METHOD cl_gui_cfw=>set_new_ok_code EXPORTING new_code = 'ENTE'. * Game over ? IF pairs_left = 0. PERFORM game_over. ENDIF. ENDIF. ENDMETHOD. ENDCLASS. *---------------------------------------------------------------------* * Form BOARD_INIT *---------------------------------------------------------------------* FORM board_init. DATA: l_index TYPE i, l_no_freecells TYPE i, l_random_cell TYPE i, l_icon TYPE icon_d, lt_icon TYPE TABLE OF icon_d, lt_freecells TYPE TABLE OF ty_boardline. * Read icon ids from DB IF NOT p_random IS INITIAL. SELECT id FROM icon INTO TABLE lt_icon WHERE locked = space AND name <> 'ICON_SPACE'. ELSE. SELECT id FROM icon INTO TABLE lt_icon UP TO pairs_left ROWS WHERE locked = space AND name <> 'ICON_SPACE' ORDER BY PRIMARY KEY. ENDIF. g_row_col = p_row * p_col. g_counter = 0. DO p_row TIMES. l_index = sy-index. DO p_col TIMES. g_counter = g_counter + 1. CLEAR wa_board. wa_board-row = l_index. wa_board-index = g_counter. wa_board-column = sy-index. PERFORM show_cell USING wa_board-row wa_board-column wa_board-container wa_board-picture space. APPEND wa_board TO gt_board. APPEND wa_board TO lt_freecells. ENDDO. ENDDO. CLEAR g_counter. g_row_col = ( ( p_row * p_col ) - 1 ) / 2. DO g_row_col TIMES. g_counter = g_counter + 1. DESCRIBE TABLE lt_icon LINES l_no_freecells. CHECK NOT l_no_freecells IS INITIAL. CALL FUNCTION 'QF05_RANDOM_INTEGER' EXPORTING ran_int_max = l_no_freecells ran_int_min = 1 IMPORTING ran_int = l_random_cell. READ TABLE lt_icon INTO l_icon INDEX l_random_cell. * Delete entry in lt_icon DELETE lt_icon INDEX sy-tabix. DO 2 TIMES. DESCRIBE TABLE lt_freecells LINES l_no_freecells. CALL FUNCTION 'QF05_RANDOM_INTEGER' EXPORTING ran_int_max = l_no_freecells ran_int_min = 1 IMPORTING ran_int = l_random_cell. * Read freecells READ TABLE lt_freecells INTO wa_board INDEX l_random_cell. * Delete entry in freecells DELETE lt_freecells INDEX sy-tabix. * Update board wa_board-icon = g_counter. wa_board-ico = l_icon. MODIFY gt_board FROM wa_board INDEX wa_board-index. ENDDO. ENDDO. ENDFORM. " BOARD_INIT *---------------------------------------------------------------------* * Form GAME_OVER *---------------------------------------------------------------------* FORM game_over. DATA: l_no TYPE i, l_hs TYPE i, l_new_highscore(1). * New Highscore ? PERFORM read_highscore. g_counter = 5. l_no = 1. LOOP AT gt_highscore INTO wa_highscore. READ TABLE gt_lines INTO wa_lines INDEX g_counter. IF score < wa_highscore-score AND l_new_highscore <> 'X'. l_new_highscore = 'X'. WRITE l_no NO-SIGN TO wa_lines-tdline(2). wa_lines-tdline+4(12) = sy-uname. WRITE sy-datum DD/MM/YYYY TO wa_lines-tdline+17(10). WRITE sy-uzeit(5) USING EDIT MASK '__:__' TO wa_lines-tdline+28(5) . WRITE score NO-SIGN TO wa_lines-tdline+34(6). l_hs = l_no. l_no = l_no + 1. MODIFY gt_lines FROM wa_lines INDEX g_counter. g_counter = g_counter + 1. ENDIF. CHECK l_no < 31. WRITE l_no NO-SIGN TO wa_lines-tdline(2). wa_lines-tdline+4(12) = wa_highscore-name. wa_lines-tdline+17(10) = wa_highscore-date. wa_lines-tdline+28(5) = wa_highscore-time. wa_lines-tdline+34(6) = wa_highscore-score. MODIFY gt_lines FROM wa_lines INDEX g_counter. g_counter = g_counter + 1. l_no = l_no + 1. ENDLOOP. IF l_new_highscore = 'X'. SELECT SINGLE mandt INTO sy-mandt FROM t000 WHERE mandt = sy-mandt AND cccategory = 'T'. IF sy-subrc EQ 0. EXPORT gt_lines TO DATABASE indx(st) ID g_indx_key. ENDIF. CALL METHOD tx_editor->set_text_as_r3table EXPORTING table = gt_lines. MESSAGE i319(01) WITH 'New Highscore' 'No.' l_hs. ELSE. MESSAGE i319(01) WITH 'Game over'. ENDIF. LEAVE TO SCREEN 0. ENDFORM. " GAME_OVER *---------------------------------------------------------------------* * Form read_highscore *---------------------------------------------------------------------* FORM read_highscore. REFRESH gt_highscore. IMPORT gt_lines FROM DATABASE indx(st) ID g_indx_key. IF gt_lines[] IS INITIAL. PERFORM f_reset_score. ENDIF. LOOP AT gt_lines INTO wa_lines. IF sy-tabix > 4. CLEAR wa_highscore. wa_highscore-no = wa_lines-tdline(2). wa_highscore-name = wa_lines-tdline+4(12). wa_highscore-date = wa_lines-tdline+17(10). wa_highscore-time = wa_lines-tdline+28(5). wa_highscore-score = wa_lines-tdline+34(6). APPEND wa_highscore TO gt_highscore. ENDIF. ENDLOOP. ENDFORM. " READ_HIGHSCORE *---------------------------------------------------------------------* * Form housekeeping *---------------------------------------------------------------------* FORM housekeeping. LOOP AT gt_board INTO wa_board. IF NOT wa_board-picture IS INITIAL. CALL METHOD wa_board-picture->free. ENDIF. CALL METHOD wa_board-container->free. ENDLOOP. CALL METHOD tx_editor->free. CALL METHOD tx_container->free. ENDFORM. " HOUSEKEEPING *---------------------------------------------------------------------* * Form create_objects *---------------------------------------------------------------------* FORM create_objects. CHECK objects_created IS INITIAL. objects_created = 'X'. * Splitter container CREATE OBJECT container EXPORTING container_name = 'CONTAINER'. * Splitter CREATE OBJECT splitter EXPORTING parent = container rows = g_row columns = g_line EXCEPTIONS others = 3. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. CLEAR g_counter. DO g_row_m_1 TIMES. g_counter = g_counter + 1. CALL METHOD splitter->set_column_sash EXPORTING id = g_counter type = splitter->type_movable value = splitter->false EXCEPTIONS OTHERS = 3. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. CALL METHOD splitter->set_row_sash EXPORTING id = g_counter type = splitter->type_movable value = splitter->false EXCEPTIONS OTHERS = 3. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDDO. * Highscore-Table PERFORM read_highscore. CREATE OBJECT tx_container EXPORTING container_name = 'TX_CONTAINER'. CREATE OBJECT tx_editor EXPORTING parent = tx_container wordwrap_mode = cl_gui_textedit=>wordwrap_at_fixed_position wordwrap_position = 42 wordwrap_to_linebreak_mode = cl_gui_textedit=>true. CALL METHOD tx_editor->set_text_as_r3table EXPORTING table = gt_lines. CALL METHOD tx_editor->set_toolbar_mode EXPORTING toolbar_mode = tx_editor->false. CALL METHOD tx_editor->set_statusbar_mode EXPORTING statusbar_mode = tx_editor->false. CALL METHOD tx_editor->set_readonly_mode EXPORTING readonly_mode = tx_editor->true. PERFORM board_init. PERFORM f_show_all. ENDFORM. " CREATE_OBJECTS *---------------------------------------------------------------------* * Form f_reset_score *---------------------------------------------------------------------* FORM f_reset_score. DATA: lf_count TYPE i. REFRESH gt_lines. wa_lines-tdformat = '*'. wa_lines-tdline = ' * * * High Scores * * *'. APPEND wa_lines TO gt_lines. wa_lines-tdformat = '/'. wa_lines-tdline = ' '. APPEND wa_lines TO gt_lines. wa_lines-tdformat = '/'. wa_lines-tdline = 'No. Name Date Time Score'. APPEND wa_lines TO gt_lines. wa_lines-tdformat = '/'. wa_lines-tdline = '----------------------------------------'. APPEND wa_lines TO gt_lines. lf_count = 1. DO 30 TIMES. wa_lines-tdformat = '/'. wa_lines-tdline = '30. NN 01.01.2002 12:00 99999' . WRITE lf_count TO wa_lines-tdline(2). APPEND wa_lines TO gt_lines. lf_count = lf_count + 1. ENDDO. ENDFORM. " f_reset_score *---------------------------------------------------------------------* * FORM f_show_all * *---------------------------------------------------------------------* FORM f_show_all. * LOOP AT gt_board INTO wa_board. * PERFORM show_cell USING wa_board-row * wa_board-column * wa_board-container * wa_board-picture * wa_board-ico. * ENDLOOP. ENDFORM. *---------------------------------------------------------------------* * Form f_reset *---------------------------------------------------------------------* FORM f_reset. DATA: l_answer. CALL FUNCTION 'POPUP_TO_CONFIRM_STEP' EXPORTING defaultoption = 'N' textline1 = 'Delete Scores ?' titel = 'Delete Score' IMPORTING answer = l_answer. CHECK l_answer = 'J'. PERFORM f_reset_score. ENDFORM. " f_reset *********************** END OF PROGRAM Z_MEMORY ***********************