Enterprise Resource Planning PortalERPGenie.COM Enterprise Resource Planning Portal

   Advertise | Founder BLOG

Web ERPGenie.COM  Other Search Options

Home | Vote for us |

ERPGenie.COM -> SAP Technical -> ABAP -> Example code -> Minesweeper

*&==============================================================

*&                Developed by ROMAN LOPEZ NAVARRO                  *

*&           http://personales.com/espana/madrid/abap/              *

*&           http://www.geocities.com/romlopabap/                   *

*&==============================================================

*&---------------------------------------------------------------------*

*& Report ZBUSCAMIN                                                 *

*&---------------------------------------------------------------------*

* Una celda marcada 

como

 bomba ' B ' no admite ser marcada 

como

 detecta-

* da ' D ' ya que implicitamente esta detectada.

* Una vez que el juego acabo no se muestran mas mensajes aunque si se

* permite seguir explorando las celdas ocultas.

* Si algunas de las celdas marcadas 

como

 detectadas son incorrectas, es-

* tas se muestran en un nuevo listado.

* Evidentemente NUM_BOMB debe ser superior o igual a MAX_HERI.

* El boton que aparece debajo 

del

 tablero indica la accion actual 

del



* usuario, y que puede ser una de las dos siguientes:

* 1.- <pisando bombas> : La casilla se marca con el numero de bombas que

*                        rodean a dicha casilla.

* 2.- <marcando bombas>: La casilla se marca con una < D > (aunque el

*                        jugador se haya equivocado y no haya bomba).

* 
Para
 marcar bombas (detectar bombas) hay que hacer clic en el boton

* hasta que aparezca el texto '<marcando bombas>'.

*&---------------------------------------------------------------------*

   REPORT ZBUSCAMIN NO STANDARD PAGE HEADING.

   INCLUDE <icon>.


 
   CONSTANTS:

     LINE_INI TYPE I VALUE 2,"       Primera linea de comienzo de escritura

     POSINI TYPE I VALUE 4,"       Justificacion a la izquierda 

del

 tablero

* NUM_BOMB TYPE I VALUE 15,"              Numero de bombas en el tablero

* MAX_HERI TYPE I VALUE 1,"              Numero de errores permitidos

     FILAS TYPE I VALUE 10,"                    Numero de filas 

del

 tablero

     COLUMNAS TYPE I VALUE 10,"              Numero de columnas 

del

 tablero

     BOMBA(3) VALUE ' B ',"                           Simbolo para la bomba

     DETECT(3) VALUE ' D ',"                   Simbolo para bomba detectada

     LINE_MSG TYPE I VALUE 25,"           Numero de linea para los mensajes

     LINE_BOTON TYPE I VALUE 27,"             Numero de linea para el boton

     BOTON_ON(17)  VALUE '<pisando  bombas>',

     BOTON_OFF(17) VALUE '<marcando bombas>',

     ICON_ON  LIKE ICONS-L2 VALUE '@1A@',

     ICON_OFF LIKE ICONS-L2 VALUE '@1C@',

     ICON_ERR LIKE ICONT-ID VALUE '@3C@'.


 
   DATA:

     MSG_1(45),"                                                    Mensaje

     GAME_OVER,"                                  Flag de partida terminada

     STR_TMP(255),"                                Variable string temporal

     BOTON(17),"                                            Texto del boton

     ICON_BOTON LIKE ICONT-ID,"                      Icono adjunto al boton

     CONTA_RADAR TYPE I,"          Contador de bombas limitrofes a la celda

     CONTA_HERIDAS TYPE I,"                             Contador de errores

     CONTA_DETECT TYPE I,"      Contador de celdas marcadas 

como

 detectadas

     CONTA_GENERAL TYPE I,"                    conta_detect + conta_heridas

     CELL_NAME LIKE DD03D-FIELDNAME,"                   Nombre de una celda

     FILA      LIKE DATATYPE-INTEGER2,"                   Fila de una celda

     COLUMNA   LIKE DATATYPE-INTEGER2,"                Columna de una celda

     FILA_CHAR2(2),

     COLUMNA_CHAR2(2).


 
   DATA:

     BEGIN OF ITAB_LET,

       1(3), 2(3), 3(3), 4(3), 5(3), 6(3), 7(3), 8(3), 9(3), 10(3),

     END OF ITAB_LET,

* Estructura con todas las celdas 

del

 tablero

     BEGIN OF ITAB,

       1 LIKE ITAB_LET, 2 LIKE ITAB_LET, 3 LIKE ITAB_LET,

       4 LIKE ITAB_LET, 5 LIKE ITAB_LET, 6 LIKE ITAB_LET,

       7 LIKE ITAB_LET, 8 LIKE ITAB_LET, 9 LIKE ITAB_LET,

       10 LIKE ITAB_LET,

     END OF ITAB,

* Estructura con las bombas pisadas

     BIS_ITAB LIKE ITAB,

* Estructura con todas las bombas calculadas iniciales

     BOMB_ITAB LIKE ITAB.


 
   FIELD-SYMBOLS: <fs1>, <fs2>, <fs3>, <fs4>.


 
   SELECTION-SCREEN BEGIN OF BLOCK BLOQUE1 WITH FRAME TITLE TITULO1.

     SELECTION-SCREEN: BEGIN OF LINE,

       COMMENT 1(16) COMENT1,

       POSITION 20.

       PARAMETERS NUM_BOMB(2) TYPE N DEFAULT 15.

     SELECTION-SCREEN END OF LINE.

     SELECTION-SCREEN: BEGIN OF LINE,

       COMMENT 1(18) COMENT2.

       POSITION 20.

       PARAMETERS MAX_HERI(2) TYPE N DEFAULT 1.

     SELECTION-SCREEN END OF LINE.

   SELECTION-SCREEN END OF BLOCK BLOQUE1.


 
************************************************************************

*                             INITIALIZATION                        *

************************************************************************

   INITIALIZATION.

     TITULO1 = 'Opciones de usuario'.

     COMENT1 = 'Numero de bombas'.

     COMENT2 = 'Errores permitidos'.


 
************************************************************************

*                          START-OF-SELECTION                       *

************************************************************************

   START-OF-SELECTION.


 
     PERFORM DISPLAY_TABLERO.

     PERFORM ASIGNAR_BOMBAS.


 
************************************************************************

*                         AT LINE-OF-SELECTION                      *

************************************************************************

   AT LINE-SELECTION.


 
     GET CURSOR FIELD CELL_NAME.

*----------------------------------------------------------------------*

*                      Cambiar el texto 

del

 boton                   *

*----------------------------------------------------------------------*

* Solo se permite si la partida no ha terminado. Cuando una partida ha

* terminado el boton queda permanentemente en estado ON.

     IF CELL_NAME = 'BOTON' AND GAME_OVER IS INITIAL.

       PERFORM CHANGE_BOTON.

     ENDIF.

*----------------------------------------------------------------------*

*     Obtener el valor de la celda seleccionada en todas las tablas *

*----------------------------------------------------------------------*

     CHECK CELL_NAME CS 'ITAB-'.

     ASSIGN (CELL_NAME) TO <fs1>." ------------------- Tabla tablero actual

     CONCATENATE 'BIS_' CELL_NAME INTO STR_TMP.

     ASSIGN (STR_TMP) TO <fs2>." --------------------- Tabla bombas pisadas

     CONCATENATE 'BOMB_' CELL_NAME INTO STR_TMP.

     ASSIGN (STR_TMP) TO <fs3>." --------------- Tabla con todas las bombas


 
     SUBTRACT 1 FROM SY-LSIND.


 
*&====================================================================&*

*&                           Detectar bomba                           &*

*&             Marcar con una 'D' la celda seleccionada               &*

*&====================================================================&*

     IF BOTON = BOTON_OFF.

*   Si el juego ha terminado no permitir detectar mas bombas (para evi-

*   tar mensajes cruzados de la rutina de deteccion). Sobra, porque el

*   boton solo puede estar en OFF si la partida no ha acabado.

*   CHECK GAME_OVER IS INITIAL.

*   Comprobar que no es una bomba ya pisada ni ya detectada

       CHECK <fs1> NE BOMBA AND <fs1> NE DETECT.

       MODIFY LINE SY-LILLI FIELD VALUE  <fs1> FROM DETECT

                            FIELD FORMAT <fs1> COLOR COL_POSITIVE.

       <fs1> = DETECT.

       ADD 1 TO CONTA_DETECT.

       CONTA_GENERAL = CONTA_HERIDAS + CONTA_DETECT.

       IF CONTA_GENERAL = NUM_BOMB.

         PERFORM CHECK_SUCCESS.

       ENDIF.

       EXIT.

     ENDIF.


 
*&====================================================================&*

*&                            Pisar celdas                            &*

*&  Muestra si la celda es una bomba o bien las bombas que la rodean  &*

*&====================================================================&*

     IF <fs1> = DETECT. SUBTRACT 1 FROM CONTA_DETECT. ENDIF.

* Si la celda es una bomba, marcarla con una ' B '

     IF <fs3> = BOMBA.

       PERFORM X_BOMBA.

* Si la celda no es una bomba, mostrar las bombas limitrofes

     ELSE.

       PERFORM OBTAIN_COORDENADAS.

       PERFORM OBTAIN_LIMITS.

     ENDIF.


 
     SET CURSOR 0 0.


 
*&---------------------------------------------------------------------*

*&      Form  DISPLAY_TABLERO

*&---------------------------------------------------------------------*

   FORM DISPLAY_TABLERO.

     DATA: CABLET(255), LONGITUD TYPE I, NUMFILA(2), N TYPE I.

     SKIP TO LINE LINE_INI.

     CABLET = '  | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10|'.

     LONGITUD = STRLEN( CABLET ).


 
     WRITE AT POSINI CABLET.

     ULINE AT /POSINI(LONGITUD).

     NEW-LINE.


 
   DO FILAS TIMES." ------------------------------------------------- Filas

       MOVE SY-INDEX TO NUMFILA.

       ASSIGN COMPONENT SY-INDEX OF STRUCTURE ITAB TO <fs1>.

       POSITION POSINI.

       WRITE: NUMFILA NO-GAP RIGHT-JUSTIFIED.

       WRITE: SY-VLINE NO-GAP.


 
     DO COLUMNAS TIMES." ----------------------------------------- Columnas

         ASSIGN COMPONENT SY-INDEX OF STRUCTURE <fs1> TO <fs2>.

         WRITE: <fs2> HOTSPOT NO-GAP,

                SY-VLINE NO-GAP.

       ENDDO.

       ULINE /POSINI(LONGITUD). NEW-LINE.


 
     ENDDO.


 
     SKIP TO LINE LINE_MSG." -------------------------------------- Mensaje

     MSG_1 = 'Bombas pisadas: 0  '.

     WRITE AT: POSINI MSG_1 INTENSIFIED OFF,

               SY-LINSZ SPACE.


 
     SKIP 1.

     ICON_BOTON = ICON_ON." ------------------------------- Icono del boton

     WRITE AT POSINI ICON_BOTON AS ICON.

     BOTON = BOTON_ON." ----------------------------------- Texto del boton

     CLEAR N.

     N = POSINI + 4.

     WRITE AT N BOTON HOTSPOT COLOR COL_TOTAL.


 
   ENDFORM.                    " DISPLAY_TABLERO


 
*&---------------------------------------------------------------------*

*&      Form  ASIGNAR_BOMBAS

*&---------------------------------------------------------------------*

* Llena la tabla BOMB_ITAB con las bombas calculadas

*&---------------------------------------------------------------------*

   FORM ASIGNAR_BOMBAS.

     DATA: CHAR2(2) TYPE C, FIELDNAME(255), CONTA_BOMBAS TYPE I.


 
     PERFORM INI_SEMILLA.


 
     WHILE CONTA_BOMBAS LT NUM_BOMB.

*------------------------------------------------------------------ Fila

       CALL FUNCTION 'RANDOM_I2'

            EXPORTING RND_MIN = 1   RND_MAX   = 10

            IMPORTING RND_VALUE = FILA.

       MOVE FILA TO CHAR2.

       CONCATENATE 'BOMB_ITAB-' CHAR2 INTO FIELDNAME.

*--------------------------------------------------------------- Columna

       CALL FUNCTION 'RANDOM_I2'

            EXPORTING RND_MIN = 1   RND_MAX   = 10

            IMPORTING RND_VALUE = COLUMNA.

       MOVE COLUMNA TO CHAR2.

       CONCATENATE FIELDNAME '-' CHAR2 INTO FIELDNAME.


 
       ASSIGN (FIELDNAME) TO <fs1>.

       IF <fs1> IS INITIAL.

         <fs1> = BOMBA.

         ADD 1 TO CONTA_BOMBAS.

       ENDIF.

     ENDWHILE.


 
   ENDFORM.                    " ASIGNAR_BOMBAS


 
*&---------------------------------------------------------------------*

*&      Form  INI_SEMILLA

*&---------------------------------------------------------------------*

* Asegura que la semilla sera aleatoria.

*----------------------------------------------------------------------*

   FORM INI_SEMILLA.

     DO 5 TIMES.

       CALL FUNCTION 'RANDOM_I2'

            EXPORTING RND_MIN = 1   RND_MAX   = 10

            IMPORTING RND_VALUE = FILA.

     ENDDO.

   ENDFORM.                    " INI_SEMILLA


 
*&---------------------------------------------------------------------*

*&      Form  OBTAIN_COORDENADAS

*&---------------------------------------------------------------------*

   FORM OBTAIN_COORDENADAS.


 
     DATA  STRING_COMPONENTES LIKE DD03D-FIELDNAME OCCURS 0.


 
     

SPLIT

 CELL_NAME AT '-' INTO TABLE STRING_COMPONENTES.

     READ TABLE STRING_COMPONENTES INDEX 2 INTO FILA.

     READ TABLE STRING_COMPONENTES INDEX 3 INTO COLUMNA.


 
   ENDFORM.                    " OBTAIN_COORDENADAS


 
*&---------------------------------------------------------------------*

*&      Form  OBTAIN_LIMITS

*&---------------------------------------------------------------------*

* Averigua si las celdas limitrofes a la seleccionada tienen una bomba.

*----------------------------------------------------------------------*

   FORM OBTAIN_LIMITS.


 
     CLEAR CONTA_RADAR.

* Celda N

     FILA_CHAR2    = FILA - 1.

     COLUMNA_CHAR2 = COLUMNA.

     PERFORM RADAR.

* Celda NW

     FILA_CHAR2 = FILA - 1.

     COLUMNA_CHAR2 = COLUMNA - 1.

     PERFORM RADAR.

* Celda NE

     FILA_CHAR2 = FILA - 1.

     COLUMNA_CHAR2 = COLUMNA + 1.

     PERFORM RADAR.

* Celda S

     FILA_CHAR2 = FILA + 1.

     COLUMNA_CHAR2 = COLUMNA.

     PERFORM RADAR.

* Celda SW

     FILA_CHAR2 = FILA + 1.

     COLUMNA_CHAR2 = COLUMNA - 1.

     PERFORM RADAR.

* Celda SE

     FILA_CHAR2 = FILA + 1.

     COLUMNA_CHAR2 = COLUMNA + 1.

     PERFORM RADAR.

* Celda E

     FILA_CHAR2 = FILA.

     COLUMNA_CHAR2 = COLUMNA - 1.

     PERFORM RADAR.

* Celda W

     FILA_CHAR2 = FILA.

     COLUMNA_CHAR2 = COLUMNA + 1.

     PERFORM RADAR.


 
     <fs1> = CONTA_RADAR.

*  SY-LILLI = LINE_INI * ( FILA + 1 ).

     MODIFY LINE SY-LILLI FIELD VALUE <fs1>  FROM CONTA_RADAR

                         FIELD FORMAT <fs1> COLOR COL_TOTAL.

   ENDFORM.                    " OBTAIN_LIMITS


 
*&---------------------------------------------------------------------*

*&      Form  RADAR

*&---------------------------------------------------------------------*

* Averigua si la celda pasada es una bomba.

*----------------------------------------------------------------------*

   FORM RADAR.


 
     CHECK FILA_CHAR2 NE '0'  AND COLUMNA_CHAR2 NE '0'  AND

           FILA_CHAR2 NE '11' AND COLUMNA_CHAR2 NE '11'.

     CONCATENATE 'BOMB_ITAB-' FILA_CHAR2 '-' COLUMNA_CHAR2 INTO STR_TMP.

     ASSIGN (STR_TMP) TO <fs3>.

     IF <fs3> = BOMBA. ADD 1 TO CONTA_RADAR. ENDIF.


 
   ENDFORM.                    " RADAR


 
*&---------------------------------------------------------------------*

*&      Form  X_BOMBA

*&---------------------------------------------------------------------*

* Marca la bomba en el tablero y muestra el mensaje correspondiente.

*----------------------------------------------------------------------*

   FORM X_BOMBA.


 
     DATA CONTA_CHAR(3).


 
* Compruebo que la bomba no ha sido pisada con anterioridad

     CHECK <fs1> NE BOMBA.

* Marcar la bomba en el tablero

     <fs1> = BOMBA.

     MODIFY LINE SY-LILLI FIELD VALUE <fs1>  FROM <fs1>

                          FIELD FORMAT <fs1> COLOR COL_NEGATIVE.

* Seguir solo si la partida no esta acabada

     CHECK GAME_OVER IS INITIAL.

     ADD 1 TO CONTA_HERIDAS.

     MOVE CONTA_HERIDAS TO CONTA_CHAR.

     CONCATENATE 'Bombas pisadas: ' CONTA_CHAR INTO MSG_1.

     CLEAR SY-LISEL.

     MODIFY LINE LINE_MSG FIELD VALUE MSG_1.


 
     IF CONTA_HERIDAS = MAX_HERI.

       MSG_1 =  'Has pisado demasiadas bombas!'.

       MODIFY LINE LINE_MSG FIELD VALUE MSG_1

                            FIELD FORMAT MSG_1 COLOR COL_NEGATIVE

                            INVERSE.

       GAME_OVER = 'X'.

     ENDIF.


 
     CONTA_GENERAL = CONTA_HERIDAS + CONTA_DETECT.

     IF CONTA_GENERAL = NUM_BOMB.

       PERFORM CHECK_SUCCESS.

     ENDIF.


 
   ENDFORM.                    " X_BOMBA


 
*&---------------------------------------------------------------------*

*&      Form  CHANGE_BOTON

*&---------------------------------------------------------------------*

* Cambia el titulo 

del

 boton de BOTON_ON a BOTON_OFF y vicevera.

*----------------------------------------------------------------------*

   FORM CHANGE_BOTON.


 
     DATA: BOTON_TMP LIKE BOTON, COLOR_TMP TYPE I, NEW_ICON LIKE ICONS-L2.


 
     CASE BOTON.

       WHEN BOTON_ON.

         BOTON = BOTON_OFF. NEW_ICON = ICON_OFF. COLOR_TMP = 5.

       WHEN BOTON_OFF.

         BOTON = BOTON_ON. NEW_ICON = ICON_ON. COLOR_TMP = 3.

     ENDCASE.


 
     WRITE BOTON TO BOTON_TMP.

     ICON_PREPARE_FOR_MODIFY NEW_ICON.


 
     MODIFY LINE LINE_BOTON FIELD VALUE BOTON FROM BOTON_TMP

                                        ICON_BOTON FROM NEW_ICON

                            FIELD FORMAT BOTON COLOR = COLOR_TMP.


 
     SET CURSOR 1 1.


 
   ENDFORM.                    " CHANGE_BOTON


 
*&---------------------------------------------------------------------*

*&      Form  CHECK_SUCCESS

*&---------------------------------------------------------------------*

* La partida ha terminado. Comprueba si se ha ganado.

*----------------------------------------------------------------------*

   FORM CHECK_SUCCESS.


 
     DATA: N TYPE I, M TYPE I, FILA_TMP TYPE I, COLUMNA_TMP TYPE I,

           FILA_TMP_FLOAT TYPE F, FILA_CHAR3(3), COLUMNA_CHAR3(3),

           NEW_ICON LIKE ICONS-L2.

     FIELD-SYMBOLS: <fs5>, <fs6>.

     N = FILAS * COLUMNAS.


 
* Para mostrar un NUEVO listado con las detecciones incorrectas.

     ADD 1 TO SY-LSIND.


 
* ---------------------------------------------------------------------*

* FILA_TMP y COLUMNA_TMP guardan las coordenadas de la celda a partir de

* su posicion absoluta (SY-INDEX)

* Por ejemplo, el campo 19 esta en la segunda fila, novena columna; para

* un total de 10 filas y 10 columnas.

*----------------------------------------------------------------------*

     DO N TIMES.

       FILA_TMP_FLOAT = SY-INDEX / COLUMNAS.

       FILA_TMP = CEIL( FILA_TMP_FLOAT ).

       COLUMNA_TMP = SY-INDEX - ( COLUMNAS * FILA_TMP ) + COLUMNAS.

       MOVE: FILA_TMP TO FILA_CHAR3, COLUMNA_TMP TO COLUMNA_CHAR3.

       CONCATENATE 'ITAB-' FILA_CHAR3 '-' COLUMNA_CHAR3

       INTO STR_TMP. CONDENSE STR_TMP NO-GAPS.

       ASSIGN (STR_TMP) TO <fs6>.

*   Se comprueba que la celda que se ha se¤alado 

como

 'D' - Detectada,

*   realmente contiene una bomba.

       IF <fs6> = DETECT.

         CONCATENATE 'BOMB_ITAB-' FILA_CHAR3 '-' COLUMNA_CHAR3

         INTO STR_TMP. CONDENSE STR_TMP NO-GAPS.

         ASSIGN (STR_TMP) TO <fs5>.

         IF <fs5> 
NE BOMBA
.

*       Mensaje(s) de celda(s) incorrecta(s) en nuevo listado.

           CONCATENATE 'La celda ' FILA_CHAR3 '-' COLUMNA_CHAR3

           ' no contenia ninguna bomba' INTO STR_TMP. WRITE STR_TMP.

           MSG_1 = 'Has perdido! Juega otra vez'.

           MODIFY LINE LINE_MSG FIELD VALUE MSG_1

                                FIELD FORMAT MSG_1 COLOR COL_NEGATIVE

                                                   INVERSE.

           GAME_OVER = 'X'." ------------------------------ Partida acabada

         ENDIF.

       ENDIF.

     ENDDO.


 
* Se pone el boton a ON (para no permitir detectar mas bombas tanto si

* la partida se ha ganado 

como

 si se ha perdido)

     NEW_ICON = ICON_ON.

     ICON_PREPARE_FOR_MODIFY NEW_ICON.

     BOTON = BOTON_ON.

     CLEAR SY-LISEL.

     MODIFY LINE LINE_BOTON FIELD VALUE  ICON_BOTON FROM NEW_ICON

                                         BOTON

                            FIELD FORMAT BOTON COLOR = 3.


 
* Mensaje de partida ganada (no se erro ninguna celda detectada)

     CHECK GAME_OVER IS INITIAL.

     MSG_1 = 'Enhorabuena! Ganaste la partida'.

     MODIFY LINE LINE_MSG FIELD VALUE  MSG_1

                          FIELD FORMAT MSG_1 COLOR COL_POSITIVE INVERSE.


 
     GAME_OVER = 'X'." ------------------------------------ Partida acabada


 
   ENDFORM.                    " CHECK_SUCCESS

 

Contact Us | Polls | Add URL | Contribute | About | Privacy | Terms | Feedback | Help!

Message Board | Discussion Forum | BLOG | Consultants: Post your resume | Companies: Advertise on ERPGenie.COM | Post Job
Genie Press | ERPTopSites | Financials Consultant | Consultant Review | Gallia Consulting | Supply Chain Project | SAP Financials Forum