|
|
|
5 Most Popular Contributions
|
|
|
|
|
|
|
|
Written by ROMAN LOPEZ NAVARRO
|
|
Sunday, 21 January 2007 |
*&==============================================================
*& 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 |
|
|
Statistics
Contribution ActivityUtilities: 38
Tips and Tricks: 330
Sample Code: 164
Total Contributions: 545
Member ActivityMembers: 6061 since 2/1/2007!
New: 0 since yesterday!
Visitors: 959210
We have 1 guest online
Newest Members
Welcome our newest members: - ddamdoly (ddamdoly)
- dnu (Doina NEAGU)
- ursalien (Joe Carerra)
- ppecka (Petr Pecka)
- marianalarab (Mariana Lara Bottazzini)
Google Ads
|