Foro -Documentación -Código fuente -Contacto -Empleo

Buscar

Traducir

Amazon

ZBUSCAMINAS PDF Imprimir E-mail
Usar puntuación: / 0
MaloBueno 
Código fuente - Juegos
Martes, 08 de Julio de 2003 21:43
Buscaminas
*&=====================================================================*
   *&                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.-  : La casilla se marca con el numero de bombas que
   *                        rodean a dicha casilla.
   * 2.- : 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 ''.
   *&---------------------------------------------------------------------*
   REPORT ZBUSCAMIN NO STANDARD PAGE HEADING.
   INCLUDE .

   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 '',
     BOTON_OFF(17) VALUE '',
     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: , , , .

   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 ." ------------------- Tabla tablero actual
     CONCATENATE 'BIS_' CELL_NAME INTO STR_TMP.
     ASSIGN (STR_TMP) TO ." --------------------- Tabla bombas pisadas
     CONCATENATE 'BOMB_' CELL_NAME INTO STR_TMP.
     ASSIGN (STR_TMP) TO ." --------------- 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  NE BOMBA AND  NE DETECT.
       MODIFY LINE SY-LILLI FIELD VALUE   FROM DETECT
                            FIELD FORMAT  COLOR COL_POSITIVE.
        = 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  = DETECT. SUBTRACT 1 FROM CONTA_DETECT. ENDIF.
   * Si la celda es una bomba, marcarla con una ' B '
     IF  = 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 .
       POSITION POSINI.
       WRITE: NUMFILA NO-GAP RIGHT-JUSTIFIED.
       WRITE: SY-VLINE NO-GAP.

     DO COLUMNAS TIMES." ----------------------------------------- Columnas
         ASSIGN COMPONENT SY-INDEX OF STRUCTURE  TO .
         WRITE:  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 .
       IF  IS INITIAL.
          = 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.

      = CONTA_RADAR.
   *  SY-LILLI = LINE_INI * ( FILA + 1 ).
     MODIFY LINE SY-LILLI FIELD VALUE   FROM CONTA_RADAR
                         FIELD FORMAT  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 .
     IF  = 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  NE BOMBA.
   * Marcar la bomba en el tablero
      = BOMBA.
     MODIFY LINE SY-LILLI FIELD VALUE   FROM 
                          FIELD FORMAT  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: , .
     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 .
   *   Se comprueba que la celda que se ha se¤alado como 'D' - Detectada,
   *   realmente contiene una bomba.
       IF  = DETECT.
         CONCATENATE 'BOMB_ITAB-' FILA_CHAR3 '-' COLUMNA_CHAR3
         INTO STR_TMP. CONDENSE STR_TMP NO-GAPS.
         ASSIGN (STR_TMP) TO .
         IF  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




Comentarios
Buscar
¡Sólo los usuarios registrados pueden escribir comentarios!

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 
home search