REPORT z_memory.
*---------------------------------------------------------------------*
* Memory Game *
* From a copy of http://www.geocities.com/ralfonsii/abap_4_fun.htm *
*---------------------------------------------------------------------*
* Author : Ralf Rubel (http://www.ralf-rubel.de/ ) / Michel PIOUD *
* Email : mpioud@yahoo.fr HomePage : http://www.geocities.com/mpioud *
*---------------------------------------------------------------------*
* Create the report Z_MEMORY *
* Create the dynpro 0100 *
* Upload the dynpro 0100 *
* from http://www.geocities.com/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 ***********************
유용하게 사용하겠습니다. 감사합니다^^