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 -> Battleships

*&=============================================================*
*&                Developed by ROMAN LOPEZ NAVARRO                     *
*&           http://personales.com/espana/madrid/abap/                 *
*&           http://www.geocities.com/romlopabap/                      *
*&=============================================================*
   REPORT ZBARCOS NO STANDARD PAGE HEADING.
   DATA:
para imprimir la pantalla
     POS      TYPE I,
     POSINI   TYPE I VALUE 4,
     FILAS    TYPE I VALUE 10,
     LONGITUD TYPE I,
     CABLET(255),
     NUMFILA(2),
* Variables para las funciones RANDOM
     INTEGER2 LIKE DATATYPE-INTEGER2,
     CHAR0128 LIKE DATATYPE-CHAR0128,
* Atributos de celda
    N   * Variable UMERO   LIKE DATATYPE-INTEGER2, " Numero de la casilla actual
     LETRA    TYPE C,                 " Letra de la casilla actual
     NUMLETRA TYPE I,                 " Letra convertida a numero
     CELL_NAME(25),                   " Nombre de la celda
* Limites de la celda seleccionada
     CELLS_EAST  TYPE I,    " Casillas libres a la derecha
     CELLS_WEST  TYPE I,    " Casillas libres a la izquierda
     CELLS_NORTH TYPE I,    " Casillas libres arriba
     CELLS_SOUTH TYPE I,    " Casillas libres abajo
* Variables para contar los aciertos
     CONTA_P1 TYPE I,
     CONTA_C1 TYPE I,
     CONTA_D1 TYPE I,
     CONTA_D2 TYPE I,
     CONTA_S1 TYPE I,
     CONTA_S2 TYPE I,
     CONTA_TOTAL(3) TYPE N,
* Variables varias
    NOREPEAT_OBTAINCELL,
     COPY_SYINDEX LIKE SY-INDEX,
     ALPHABET(26) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
     INT_TMP TYPE I,
     CHAR1_TMP,
     CHAR2_TMP(2),
     STR_TMP(255),
     PLACED_SHIP,
     SHIPNAME(2),
     LENSHIP TYPE I.
* Estructuras con todas las celdas
   DATA:
     BEGIN OF ITAB_LET,
       A(3), B(3), C(3), D(3), E(3), F(3), G(3), H(3), I(3), J(3),
     END OF ITAB_LET,
     BEGIN OF ITAB_NUM,
       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_NUM,
     BIS_ITAB_NUM LIKE ITAB_NUM.
   FIELD-SYMBOLS: <fs1>, <fs2>, <fs3>, <fs4>.
************************************************************************
*                            START-OF-SELECTION                        *
************************************************************************
   START-OF-SELECTION.
   PERFORM WRITE_TABLA.
   PERFORM PLACE_SHIPS.
   WRITE SPACE." Linea 26 donde se mostraran los mensajes (por ahora vacia)
   SKIP 1.
   WRITE '   Turno: 000' INTENSIFIED OFF." Linea 27
************************************************************************
*                           AT LINE-SELECTION                          *
************************************************************************
   AT LINE-SELECTION.
   GET CURSOR FIELD STR_TMP.
   ASSIGN (STR_TMP) TO <fs3>.
   SUBTRACT 1 FROM SY-LSIND.
   SET CURSOR 1 1." 
   CONCATENATE 'BIS_' STR_TMP INTO STR_TMP.
   ASSIGN (STR_TMP) TO <fs4>.
   CHECK <fs4> IS INITIAL.
   MOVE 'X' TO <fs4>.
   ADD 1 TO CONTA_TOTAL.
   CONCATENATE '   Turno:' CONTA_TOTAL INTO STR_TMP SEPARATED BY SPACE.
   MODIFY LINE 27 LINE VALUE FROM STR_TMP LINE FORMAT INTENSIFIED OFF.
*------------------------------------------------------------------ Agua
   IF <fs3> IS INITIAL.
     MODIFY LINE SY-LILLI FIELD VALUE <fs3> FROM ' X'
                          FIELD FORMAT <fs3> COLOR COL_POSITIVE.
     STR_TMP = '   Agua'.
     MODIFY LINE 26 LINE VALUE FROM STR_TMP.
*--------------------------------------------------------------- Tocado!
   ELSE.
     STR_TMP = '   Tocado!'.
     MODIFY LINE 26 LINE VALUE FROM STR_TMP.
*------------------------------------------------------------ Hundido!!!
    CASE <fs3>.
       WHEN 'P1'. ADD 1 TO CONTA_P1.
         IF CONTA_P1 = 5. STR_TMP = '   Hundido!!!'.
          MODIFY LINE 26 LINE VALUE FROM STR_TMP.
         ENDIF.
       WHEN 'C1'. ADD 1 TO CONTA_C1.
         IF CONTA_C1 = 4. STR_TMP = '   Hundido!!!'.
           MODIFY LINE 26 LINE VALUE FROM STR_TMP.
         ENDIF.
       WHEN 'D1'. ADD 1 TO CONTA_D1.
         IF CONTA_D1 = 3. STR_TMP = '   Hundido!!!'.
           MODIFY LINE 26 LINE VALUE FROM STR_TMP.
         ENDIF.
       WHEN 'D2'. ADD 1 TO CONTA_D2.
         IF CONTA_D2 = 3. STR_TMP = '   Hundido!!!'.
           MODIFY LINE 26 LINE VALUE FROM STR_TMP.
         ENDIF.
       WHEN 'S1'. ADD 1 TO CONTA_S1.
         IF CONTA_S1 = 2. STR_TMP = '   Hundido!!!'.
           MODIFY LINE 26 LINE VALUE FROM STR_TMP.
         ENDIF.
       WHEN 'S2'. ADD 1 TO CONTA_S2.
         IF CONTA_S2 = 2. STR_TMP = '   Hundido!!!'.
           MODIFY LINE 26 LINE VALUE FROM STR_TMP.
         ENDIF.
     ENDCASE.
     MODIFY LINE SY-LILLI FIELD VALUE <fs3> FROM ' X'
                          FIELD FORMAT <fs3> COLOR COL_NEGATIVE.
   ENDIF.
*--------------------------------------------------------- Fin del juego
   IF CONTA_P1 = 5 AND CONTA_C1 = 4 AND CONTA_D1  = 3 AND CONTA_D2 = 3 AND
      CONTA_S1 = 2 AND CONTA_S2 = 2.
     STR_TMP = '   Hundiste la flota enemiga!'.
     MODIFY LINE 26 LINE VALUE FROM STR_TMP.
   ENDIF.

*&---------------------------------------------------------------------*
*&      Form  PLACE_SHIPS
*&---------------------------------------------------------------------*
   FORM PLACE_SHIPS.
*---------------------------------------------------------- Portaaviones
     CLEAR PLACED_SHIP.
     WHILE PLACED_SHIP IS INITIAL.
       LENSHIP = 5. SHIPNAME = 'P1'. PERFORM PLACE_SHIP.
     ENDWHILE.
*--------------------------------------------------------------- Crucero
     CLEAR PLACED_SHIP.
     WHILE PLACED_SHIP IS INITIAL.
       LENSHIP = 4. SHIPNAME = 'C1'. PERFORM PLACE_SHIP.
     ENDWHILE.
*---------------------------------------------------------- Destructor 1
     CLEAR PLACED_SHIP.
     WHILE PLACED_SHIP IS INITIAL.
       LENSHIP = 3. SHIPNAME = 'D1'. PERFORM PLACE_SHIP.
     ENDWHILE.
*---------------------------------------------------------- Destructor 2
     CLEAR PLACED_SHIP.
     WHILE PLACED_SHIP IS INITIAL.
       LENSHIP = 3. SHIPNAME = 'D2'. PERFORM PLACE_SHIP.
     ENDWHILE.
*----------------------------------------------------------- Submarino 1
     CLEAR PLACED_SHIP.
     WHILE PLACED_SHIP IS INITIAL.
       LENSHIP = 2. SHIPNAME = 'S1'. PERFORM PLACE_SHIP.
    ENDWHILE.
*----------------------------------------------------------- Submarino 2
     CLEAR PLACED_SHIP.
     WHILE PLACED_SHIP IS INITIAL.
       LENSHIP = 2. SHIPNAME = 'S2'. PERFORM PLACE_SHIP.
     ENDWHILE.

   ENDFORM.                    " PLACE_SHIPS

*&---------------------------------------------------------------------*
*&      Form  PLACE_SHIP
*&---------------------------------------------------------------------*
* Coloca el barco actual en proceso
*----------------------------------------------------------------------*
   FORM PLACE_SHIP.

* Obtencion de una celda vacia (NOREPEAT_OBTAINCELL es un flag que sir-
* ve para saber si la celda no esta vacia en cuyo caso hay que repetir
* la llamada al form OBTAIN_CELL) y de sus limites.
     CLEAR NOREPEAT_OBTAINCELL.
     WHILE NOREPEAT_OBTAINCELL IS INITIAL.
       PERFORM OBTAIN_CELL.
     ENDWHILE.
     PERFORM OBTAIN_LIMITS.

* Valor aleatorio (1-4) para decidir la secuencia de orientaciones.
    CLEAR INTEGER2.
     CALL FUNCTION 'RANDOM_I2'
         EXPORTING RND_MIN = 1   RND_MAX = 4
         IMPORTING RND_VALUE = INTEGER2.

* Colocacion del barco siguiendo la secuencia de orientaciones. Se
* empieza con la primera; si no es posible se prueba con la segunda,
* sino con la tercera y por ultimo con la cuarta.
     CLEAR PLACED_SHIP.
     CASE INTEGER2.
       WHEN 1. " Norte-Sur-Este-Oeste
         PERFORM ADJUST_NORTH. CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_SOUTH. CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_EAST.  CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_WEST.  CHECK PLACED_SHIP IS INITIAL.
       WHEN 2. " Sur-Este-Oeste-Norte
         PERFORM ADJUST_SOUTH. CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_EAST.  CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_WEST.  CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_NORTH. CHECK PLACED_SHIP IS INITIAL.
       WHEN 3. " Este-Oeste-Norte-Sur
         PERFORM ADJUST_EAST.  CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_WEST.  CHECK PLACED_SHIP IS INITIAL.
        PERFORM ADJUST_NORTH. CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_SOUTH. CHECK PLACED_SHIP IS INITIAL.
       WHEN 4. " Oeste-Norte-Sur-Este
         PERFORM ADJUST_WEST.  CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_NORTH. CHECK PLACED_SHIP IS INITIAL.
        PERFORM ADJUST_SOUTH. CHECK PLACED_SHIP IS INITIAL.
         PERFORM ADJUST_EAST.  CHECK PLACED_SHIP IS INITIAL.
     ENDCASE.

   ENDFORM.                    " PLACE_SHIP

*&---------------------------------------------------------------------*
*&      Form  OBTAIN_CELL
*&---------------------------------------------------------------------*
* Obtiene aleatoriamente las coordenadas de una celda
*----------------------------------------------------------------------*
 FORM OBTAIN_CELL.
*---------------------------------------------------------------- Numero
    CLEAR INTEGER2.
* Llamo 5 veces a la funcion para que el numero sea realmente aleatorio,
* si solo la llamo una o dos veces los dos primeros numeros de la
* secuencia son siempre los mismos.
     DO 5 TIMES.
       CALL FUNCTION 'RANDOM_I2'
            EXPORTING RND_MIN = 1 RND_MAX = 10
            IMPORTING RND_VALUE = INTEGER2.
     ENDDO.
     NUMERO = INTEGER2.
*----------------------------------------------------------------- Letra
     CLEAR CHAR0128.
     CALL FUNCTION 'RANDOM_C'
          EXPORTING LEN_MIN = 1 LEN_MAX = 1 CHAR_MIN = 64 CHAR_MAX = 73
          IMPORTING RND_VALUE = CHAR0128.
          LETRA = CHAR0128.
*-------------------------------------------- Conversion Letra -> Numero
     SEARCH ALPHABET FOR LETRA.
     NUMLETRA = SY-FDPOS.
     ADD 1 TO NUMLETRA.
*------------------------------------- Comprobar que la celda esta vacia
     MOVE NUMERO TO CHAR2_TMP.
     CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' LETRA INTO CELL_NAME.
    ASSIGN (CELL_NAME) TO <fs3>.
     IF <fs3> IS INITIAL.
       NOREPEAT_OBTAINCELL = 'X'.
     ENDIF.

   ENDFORM.                    " OBTAIN_CELL
 
*&---------------------------------------------------------------------*
*&      Form  OBTAIN_LIMITS
*&---------------------------------------------------------------------*
* Obtiene las celdas vacias o libres alrededor de la seleccionada
*----------------------------------------------------------------------*
   FORM OBTAIN_LIMITS.
*------------------------------------------------ Celdas libres al Norte
     CLEAR COPY_SYINDEX.
    INT_TMP = NUMERO.
     DO FILAS TIMES.
       SUBTRACT 1 FROM INT_TMP.
       IF INT_TMP = 0. CELLS_NORTH = SY-INDEX - 1. EXIT. ENDIF.
       CHAR2_TMP = INT_TMP.
       CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' LETRA INTO CELL_NAME.
       ASSIGN (CELL_NAME) TO <fs3>.
       IF NOT <fs3> IS INITIAL. CELLS_NORTH = SY-INDEX - 1. EXIT. ENDIF.
     ENDDO.
*-------------------------------------------------- Celdas libres al Sur
     CLEAR COPY_SYINDEX.
     INT_TMP = NUMERO.
     DO FILAS TIMES.
       ADD 1 TO INT_TMP.
      IF INT_TMP = 11. CELLS_SOUTH = SY-INDEX - 1. EXIT. ENDIF.
       CHAR2_TMP = INT_TMP.
       CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' LETRA INTO CELL_NAME.
       ASSIGN (CELL_NAME) TO <fs3>.
       IF NOT <fs3> IS INITIAL. CELLS_SOUTH = SY-INDEX - 1. EXIT. ENDIF.
     ENDDO.
*------------------------------------------------- Celdas libres al Este
     CLEAR COPY_SYINDEX.
     INT_TMP = NUMLETRA - 1.
     DO FILAS TIMES.
       ADD 1 TO INT_TMP.
       IF INT_TMP = 10. CELLS_EAST = SY-INDEX - 1. EXIT. ENDIF.
       MOVE: ALPHABET+INT_TMP(1) TO CHAR1_TMP,
             NUMERO TO CHAR2_TMP.
       CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' CHAR1_TMP INTO CELL_NAME.
       ASSIGN (CELL_NAME) TO <fs3>.
       IF NOT <fs3> IS INITIAL. CELLS_EAST = SY-INDEX - 1. EXIT. ENDIF.
     ENDDO.
*------------------------------------------------ Celdas libres al Oeste
     CLEAR COPY_SYINDEX.
     INT_TMP = NUMLETRA - 1.
     DO FILAS TIMES.
       SUBTRACT 1 FROM INT_TMP.
       IF INT_TMP = -1. CELLS_WEST = SY-INDEX - 1. EXIT. ENDIF.
       MOVE: ALPHABET+INT_TMP(1) TO CHAR1_TMP,
             NUMERO TO CHAR2_TMP.
       CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' CHAR1_TMP INTO CELL_NAME.
      ASSIGN (CELL_NAME) TO <fs3>.
       IF NOT <fs3> IS INITIAL. CELLS_WEST = SY-INDEX - 1. EXIT. ENDIF.
     ENDDO.

   ENDFORM.                    " OBTAIN_LIMITS

*&---------------------------------------------------------------------*
*&      Form  ADJUST_NORTH
*&---------------------------------------------------------------------*
* Intenta colocar el barco orientado al Norte
*----------------------------------------------------------------------*
   FORM ADJUST_NORTH.
     ADD 1 TO CELLS_NORTH." 
     IF CELLS_NORTH GE LENSHIP.
       MOVE NUMERO TO INT_TMP.
       DO LENSHIP TIMES.
         MOVE INT_TMP TO CHAR2_TMP.
         CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' LETRA INTO CELL_NAME.
         CONDENSE CELL_NAME.
         ASSIGN (CELL_NAME) TO <fs3>.
         <fs3> = SHIPNAME.
         SUBTRACT 1 FROM INT_TMP.
       ENDDO.
      PLACED_SHIP = 'X'.
     ENDIF.

  ENDFORM.                    " ADJUST_NORTH

*&---------------------------------------------------------------------*
*&      Form  ADJUST_SOUTH
*&---------------------------------------------------------------------*
* Intenta colocar el barco orientado al Sur
*----------------------------------------------------------------------*
 FORM ADJUST_SOUTH.

    ADD 1 TO CELLS_SOUTH." Para incluir la propia celda seleccionada
     IF CELLS_SOUTH GE LENSHIP.
       MOVE NUMERO TO INT_TMP.
       DO LENSHIP TIMES.
         MOVE INT_TMP TO CHAR2_TMP.
         CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' LETRA INTO CELL_NAME.
         CONDENSE CELL_NAME.
         ASSIGN (CELL_NAME) TO <fs3>.
         <fs3> = SHIPNAME.
         ADD 1 TO INT_TMP.
       ENDDO.
       PLACED_SHIP = 'X'.
     ENDIF.

   ENDFORM.                    " ADJUST_SOUTH

*&---------------------------------------------------------------------*
*&      Form  ADJUST_EAST
*&---------------------------------------------------------------------*
* Intenta colocar el barco orientado al Este
*----------------------------------------------------------------------*
  FORM ADJUST_EAST.

     ADD 1 TO CELLS_EAST." Para incluir la propia celda seleccionada
     IF CELLS_EAST GE LENSHIP.
       MOVE NUMLETRA TO INT_TMP.
       SUBTRACT 1 FROM INT_TMP.
       DO LENSHIP TIMES.
         MOVE: ALPHABET+INT_TMP(1) TO CHAR1_TMP,
               NUMERO               TO CHAR2_TMP.
         CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' CHAR1_TMP INTO CELL_NAME.
        CONDENSE CELL_NAME.
         ASSIGN (CELL_NAME) TO <fs3>.
         <fs3> = SHIPNAME.
         ADD 1 TO INT_TMP.
       ENDDO.
       PLACED_SHIP = 'X'.
     ENDIF.
 
   ENDFORM.                    " ADJUST_EAST

*&---------------------------------------------------------------------*
*&      Form  ADJUST_WEST
*&---------------------------------------------------------------------*
* Intenta colocar el barco orientado al Oeste
*----------------------------------------------------------------------*
   FORM ADJUST_WEST.

    ADD 1 TO CELLS_WEST." 
     IF CELLS_WEST GE LENSHIP.
       MOVE NUMLETRA TO INT_TMP.
       SUBTRACT 1 FROM INT_TMP.
       DO LENSHIP TIMES.
         MOVE: ALPHABET+INT_TMP(1) TO CHAR1_TMP,
               NUMERO               TO CHAR2_TMP.
         CONCATENATE 'ITAB_NUM-' CHAR2_TMP '-' CHAR1_TMP INTO CELL_NAME.
         CONDENSE CELL_NAME.
         ASSIGN (CELL_NAME) TO <fs3>.
         <fs3> = SHIPNAME.
         SUBTRACT 1 FROM INT_TMP.
      ENDDO.
       PLACED_SHIP = 'X'.
     ENDIF.
   ENDFORM.                    " ADJUST_WEST

*&---------------------------------------------------------------------*
*&      Form  WRITE_TABLA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
   FORM WRITE_TABLA.

    SKIP 3.
     CABLET = '  | A | B | C | D | E | F | G | H | I | J |'.
     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_NUM TO <fs1>.
       POSITION POSINI.
       WRITE: NUMFILA NO-GAP RIGHT-JUSTIFIED.
       WRITE: SY-VLINE NO-GAP.
     DO FILAS 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.
   ENDFORM.                    " WRITE_TABLA 

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