Categorias

Paciência em ABAP

Use o este código para criar e jogar paciência em ABAP!!!

*&---------------------------------------------------------------------*
*& Report  ZSOL                                                        *
*&                                                                     *
*&---------------------------------------------------------------------*
*&                                                                     *
*&                                                                     *
*&---------------------------------------------------------------------*

PROGRAM zsol NO STANDARD PAGE HEADING.

DATA: number LIKE datatype-integer2.
DATA: dummy  LIKE datatype-integer2.
DATA: BEGIN OF cards OCCURS 52 ,
      entry TYPE i,
      row TYPE i,
      col TYPE i,
      vis(1),
      END OF cards.
DATA: card_num TYPE i, suit_num TYPE i, suit(1), card(2), rows TYPE i.
DATA: blank(3) VALUE '***'.
DATA: next-card(4) VALUE 'Next'.
DATA: restart(8) VALUE 'New game'.
DATA: reveal(6) VALUE 'Reveal'.
DATA: test_num TYPE i, to_num TYPE i, moving_num TYPE i,
        pile_num TYPE i.
DATA: curr_c TYPE i, curr_h TYPE i, curr_s TYPE i, curr_d TYPE i.
DATA: moving_suit(1), to_suit(1), moving_card(2), to_card(2),
  pile_suit(1), pile_card(2),moving_type(1)    .
DATA: moving_row TYPE i, moving_col TYPE i,
      to_row TYPE i, to_col TYPE i, test_row TYPE i.
DATA: current_card TYPE i,
       min_card TYPE i , max_card TYPE i.
DATA: currentfield(50).
DATA: disc_c(3),disc_h(3),disc_s(3),disc_d(3).
DATA: rows_out TYPE i, cols_out TYPE i.


PERFORM shuffle.
PERFORM show_screen.

AT LINE-SELECTION.
  GET CURSOR FIELD currentfield.
  PERFORM process-input.

*---------------------------------------------------------------------*
*       FORM SHUFFLE                                                  *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM shuffle.
  min_card = 3.max_card = 24.
  curr_c = -1.curr_d = -1.curr_h = -1.curr_s = -1.
  disc_c = 'CCC'.disc_h = 'HHH'.disc_s = 'SSS'.disc_d = 'DDD'.
  number = sy-uzeit MOD 1000.
  DO number TIMES.
    CALL FUNCTION 'RANDOM_I2'
         IMPORTING
              rnd_value = dummy.
  ENDDO.
  REFRESH cards. CLEAR cards. sy-tabix = 0.

  DATA: v_cont  LIKE sy-tabix.
  DATA: v_flg.
  DATA: v_cont2 LIKE sy-tabix.
  DATA: gambi LIKE sy-tabix.

  DESCRIBE TABLE cards LINES v_cont.

  WHILE v_cont <= 51.
    CLEAR: gambi, v_flg.
    CALL FUNCTION 'RANDOM_I2'
         EXPORTING
              rnd_min   = 0
              rnd_max   = 51
         IMPORTING
              rnd_value = number.
*    READ TABLE cards WITH KEY number TRANSPORTING NO FIELDS.
    READ TABLE cards WITH KEY entry = number.
    IF sy-subrc <> 0.
      cards-vis = 'n'.
      DESCRIBE TABLE cards LINES rows.
      CASE rows.
        WHEN 0.
          cards-vis = 'y'.
          cards-row = 0.
          cards-col = 0.
          v_flg = 'X'.
        WHEN 7.
          cards-vis = 'y'.
          cards-row = 1.
          cards-col = 1.
          v_flg = 'X'.
        WHEN 13.
          cards-vis = 'y'.
          cards-row = 2.
          cards-col = 2.
          v_flg = 'X'.
        WHEN 18.
          cards-vis = 'y'.
          cards-row = 3.
          cards-col = 3.
          v_flg = 'X'.
        WHEN 22.
          cards-vis = 'y'.
          cards-row = 4.
          cards-col = 4.
          v_flg = 'X'.
        WHEN 25.
          cards-vis = 'y'.
          cards-row = 5.
          cards-col = 5.
          v_flg = 'X'.
        WHEN 27.
          cards-vis = 'y'.
          cards-row = 6.
          cards-col = 6.
          v_flg = 'X'.
        WHEN 28.
          cards-row = 20.
          cards-col = 0.
          v_flg = 'X'.
      ENDCASE.
      IF v_flg = 'X'.
        cards-col = cards-col + 1.
        cards-entry = number.
        APPEND cards.
        CLEAR cards.
      ELSE.
        DESCRIBE TABLE cards LINES gambi.
        READ TABLE cards INDEX gambi.
        cards-vis = 'n'.
        cards-col = cards-col + 1.
        cards-entry = number.
        APPEND cards.
        CLEAR cards.
      ENDIF.

    ENDIF.

    CLEAR v_cont.
    DESCRIBE TABLE cards LINES v_cont.

*enddo.
  ENDWHILE.
  current_card = min_card.
ENDFORM.

*---------------------------------------------------------------------*
*       FORM SHOW_SCREEN                                              *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM show_screen.
  rows_out = 1.
  cols_out = 4.
  DO 7 TIMES.
    SKIP TO LINE rows_out.
    POSITION cols_out.
    WRITE blank HOTSPOT.
    cols_out = cols_out + 4.
  ENDDO.
  LOOP AT cards.
    PERFORM make_card.
    IF cards-row < 20.
      rows_out = cards-row + 1.
      SKIP TO LINE rows_out.
      cols_out = cards-col * 4.
      POSITION cols_out.
      IF cards-vis = 'n'.
        WRITE 'XXX' COLOR OFF INTENSIFIED OFF INVERSE OFF.
      ELSE.
        IF suit = 'D' OR suit = 'H'.
          WRITE: suit NO-GAP COLOR 6 INTENSIFIED INVERSE HOTSPOT,
                 card COLOR 6 INTENSIFIED INVERSE HOTSPOT.
        ELSE.
       WRITE: suit NO-GAP COLOR OFF INTENSIFIED OFF INVERSE OFF HOTSPOT,
                     card COLOR OFF INTENSIFIED OFF INVERSE OFF HOTSPOT.
        ENDIF.
      ENDIF.
    ELSE.
      SKIP TO LINE 20.      cols_out =  cards-col  * 4.
      IF cols_out > 48.
        SKIP TO LINE 21.
        cols_out = cols_out - 48.
      ENDIF.
      POSITION cols_out.
      IF cards-col = current_card.
        pile_suit = suit.
        pile_card = card.
        pile_num = card_num.
        IF suit = 'D' OR suit = 'H'.
          WRITE: pile_suit NO-GAP COLOR 6 INTENSIFIED INVERSE HOTSPOT,
                 pile_card COLOR 6 INTENSIFIED INVERSE HOTSPOT.
        ELSE.
          WRITE: pile_suit NO-GAP COLOR OFF INTENSIFIED OFF HOTSPOT,
                 pile_card COLOR OFF INTENSIFIED OFF HOTSPOT.
        ENDIF.
      ELSE.
        IF cards-col < current_card.
          WRITE 'XXX' COLOR OFF INTENSIFIED OFF INVERSE OFF.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDLOOP.
  SKIP TO LINE 4. POSITION 40.WRITE: disc_c
       COLOR OFF INTENSIFIED OFF INVERSE OFF HOTSPOT.
  SKIP TO LINE 4. POSITION 44. WRITE: disc_d
       COLOR 6 INTENSIFIED INVERSE HOTSPOT.
  SKIP TO LINE 4. POSITION 48. WRITE: disc_s
       COLOR OFF INTENSIFIED OFF INVERSE OFF HOTSPOT.
  SKIP TO LINE 4. POSITION 52. WRITE: disc_h
       COLOR 6 INTENSIFIED INVERSE HOTSPOT.
  IF min_card > 0.
    SKIP TO LINE 23. POSITION 1. WRITE next-card HOTSPOT.
  ENDIF.
  SKIP TO LINE 23. POSITION 20. WRITE restart HOTSPOT.
*  skip to line 23. position 40. write reveal hotspot.
  SKIP TO LINE 25. POSITION 1. WRITE currentfield.
  sy-lsind = 0.
ENDFORM.

*---------------------------------------------------------------------*
*       FORM PROCESS-INPUT                                            *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM process-input.
  IF currentfield = 'NEXT-CARD'.
    IF current_card = max_card.
      current_card = min_card.
    ELSE.
      current_card = current_card + 3.
      IF current_card > max_card.
        current_card = max_card.
      ENDIF.
    ENDIF.
    moving_card = space.
    currentfield = space.
    PERFORM show_screen.
    EXIT.
  ENDIF.
  IF currentfield = 'REVEAL'.
    LOOP AT cards.
      cards-vis =  'y'.
      MODIFY cards.
    ENDLOOP.
    PERFORM show_screen.
    EXIT.
  ENDIF.
  IF currentfield = 'RESTART'.
    PERFORM shuffle.
    currentfield = 'Restarting'.
    PERFORM show_screen.
    EXIT.
  ENDIF.
  IF moving_card = space.
    IF currentfield = 'CARD' OR currentfield = 'SUIT'.
      currentfield = space.
      rows_out = sy-curow - 1.
      cols_out = sy-cucol DIV 4.
      LOOP AT cards.
        IF cards-row = rows_out AND cards-col = cols_out.
          currentfield = 'Moving '.
          PERFORM make_card.
          moving_row = cards-row.
          moving_col = cards-col.
          moving_card = card.
          moving_suit = suit.
          moving_type = 'm'.
          moving_num = card_num.
          currentfield+8(1) = suit.
          currentfield+9(2) = card.
        ENDIF.
      ENDLOOP.
    ELSE.
      IF currentfield = 'PILE_CARD' OR currentfield = 'PILE_SUIT'.
        moving_card = pile_card.
        moving_suit = pile_suit.
        moving_type = 'p'.
        moving_num = pile_num.
        currentfield = 'Moving pile card'.
        currentfield+17(1) = pile_suit.
        currentfield+18(2) = pile_card.
      ELSE.
        currentfield = space.
      ENDIF.
    ENDIF.
  ELSE.
    IF currentfield = 'CARD' OR currentfield = 'SUIT' OR
           currentfield = 'BLANK'.
      rows_out = sy-curow - 1.
      cols_out = sy-cucol DIV 4.
      test_row = -1.
      IF currentfield = 'BLANK'.
        to_col = cols_out.
        to_row = rows_out - 1.
        IF moving_card = 'K'.
          PERFORM move_card.
        ELSE.
          currentfield = 'Can only move K to blank'.
          moving_card = space.
        ENDIF.
      ELSE.
        LOOP AT cards.
          IF ( cards-row >= test_row AND cards-row < 20 )
                 AND cards-col = cols_out.
            test_row = cards-row.
            PERFORM make_card.
            to_col = cards-col.
            to_row = cards-row.
            to_card = card.
            to_suit = suit.
            to_num = card_num.
          ENDIF.
        ENDLOOP.
        IF to_col <> moving_col OR moving_type = 'p'.
          IF
             ( ( moving_suit = 'D' OR moving_suit = 'H' ) AND
               ( to_suit = 'D' OR to_suit = 'H' ) )
           OR
             ( ( moving_suit = 'C' OR moving_suit = 'S' ) AND
               ( to_suit = 'S' OR to_suit = 'S' ) ).
            currentfield = 'Can only put black on red or red on black'.
            moving_card = space.
          ELSE.
            test_num = to_num - 1.
            IF test_num = moving_num.
              PERFORM move_card.
            ELSE.
              currentfield = 'Can only put on next higher card'.
              moving_card = space.
            ENDIF.
          ENDIF.
        ELSE.
          currentfield = 'Can only move to another column'.
          moving_card = space.
        ENDIF.
      ENDIF.
    ELSE.
      IF currentfield(4) = 'DISC'.
        to_suit = currentfield+5(1).
        IF moving_type = 'p'.
        ELSE.
          test_row = -1.
          LOOP AT cards.
            IF cards-col = moving_col AND
                    cards-row > test_row AND cards-row < 20.
              test_row = cards-row.
              PERFORM make_card.
              moving_suit = suit.
              moving_card = card.
              moving_row = cards-row.
              moving_col = cards-col.
              moving_num = card_num.
            ENDIF.
          ENDLOOP.
        ENDIF.
        IF moving_suit = to_suit.
          CASE moving_suit.
            WHEN 'C'. test_num = curr_c + 1.
            WHEN 'H'. test_num = curr_h + 1.
            WHEN 'D'. test_num = curr_d + 1.
            WHEN 'S'. test_num = curr_s + 1.
          ENDCASE.
          IF test_num = moving_num.
            PERFORM discard_card.
            CASE moving_suit.
              WHEN 'C'. curr_c = curr_c + 1.
              WHEN 'D'. curr_d = curr_d + 1.
              WHEN 'S'. curr_s = curr_s + 1.
              WHEN 'H'. curr_h = curr_h + 1.
            ENDCASE.
          ELSE.
            currentfield = 'Can only discard on next lower card'.
            moving_card = space.
          ENDIF.
        ELSE.
          moving_card = space.
          currentfield = 'Can only discard on same suit'.
        ENDIF.
      ELSE.
        moving_card = space.
        currentfield = space.
      ENDIF.
    ENDIF.
  ENDIF.
  PERFORM show_screen.
ENDFORM.
*---------------------------------------------------------------------*
*       FORM MAKE_CARD                                                *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM make_card.
  suit_num = cards-entry DIV 13 .
  CASE suit_num.
    WHEN 0.suit = 'D'.
    WHEN 1.suit = 'H'.
    WHEN 2.suit = 'C'.
    WHEN 3.suit = 'S'.
  ENDCASE.
  card_num = cards-entry MOD 13.
  CASE card_num.
    WHEN 0.card = 'A'.
    WHEN 1.card = '2'.
    WHEN 2.card = '3'.
    WHEN 3.card = '4'.
    WHEN 4.card = '5'.
    WHEN 5.card = '6'.
    WHEN 6.card = '7'.
    WHEN 7.card = '8'.
    WHEN 8.card = '9'.
    WHEN 9.card = '10'.
    WHEN 10.card = 'J'.
    WHEN 11.card = 'Q'.
    WHEN 12.card = 'K'.
  ENDCASE.
ENDFORM.
*---------------------------------------------------------------------*
*       FORM MOVE_CARD                                                *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM move_card.
  IF currentfield <> 'BLANK'.
    currentfield = 'Moving xxx to'.
    MOVE moving_suit TO currentfield+7(1).
    MOVE moving_card TO currentfield+8(2).
    MOVE to_suit TO currentfield+14(1).
    MOVE to_card TO currentfield+15(2).
  ELSE.
    currentfield = 'Starting emtpy column'.
  ENDIF.
  IF moving_type = 'p'.
    MOVE 'from pile' TO currentfield+18.
    LOOP AT cards.
      IF cards-row = 20 AND cards-col = current_card.
        cards-col = to_col.
        cards-row = to_row + 1.
        cards-vis = 'y'.
      ENDIF.
      IF cards-row = 20 AND cards-col > current_card.
        cards-col = cards-col - 1.
      ENDIF.
      MODIFY cards.
    ENDLOOP.
    current_card = current_card - 1.
    max_card = max_card - 1.
    IF max_card < min_card.
      min_card = min_card - 1.
      max_card = min_card.
    ENDIF.
    IF current_card < 1.
      current_card = min_card.
    ENDIF.
  ELSE.
    LOOP AT cards.
      IF cards-col = moving_col AND
       ( cards-row >= moving_row AND cards-row < 20 ).
        cards-col = to_col.
        cards-row = to_row + 1 + cards-row - moving_row.
        MODIFY cards.
      ENDIF.
    ENDLOOP.
    test_row = moving_row - 1.
    LOOP AT cards.
      IF cards-col = moving_col AND cards-row = test_row.
        cards-vis = 'y'.
        MODIFY cards.
      ENDIF.
    ENDLOOP.
  ENDIF.
  moving_card = space.
ENDFORM.
*---------------------------------------------------------------------*
*       FORM DISCARD_CARD                                             *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM discard_card.
  MOVE 'Discarding' TO currentfield.
  MOVE moving_suit TO currentfield+13(1).
  MOVE moving_card TO currentfield+14(2).
  CASE to_suit.
    WHEN 'C'.
      disc_c+1(2) = moving_card.
    WHEN 'D'.
      disc_d+1(2) = moving_card.
    WHEN 'H'.
      disc_h+1(2) = moving_card.
    WHEN 'S'.
      disc_s+1(2) = moving_card.
  ENDCASE.
  IF moving_type = 'p'.
    MOVE 'from pile' TO currentfield+18.
    LOOP AT cards.
      IF cards-row = 20 AND cards-col = current_card.
        cards-col = 0.
      ENDIF.
      IF cards-row = 20 AND cards-col > current_card.
        cards-col = cards-col - 1.
      ENDIF.
      MODIFY cards.
    ENDLOOP.
    current_card = current_card - 1.
    max_card = max_card - 1.
    IF max_card < min_card.
      min_card = min_card - 1.
      max_card = min_card.
    ENDIF.
    IF current_card < 1.
      current_card = min_card.
    ENDIF.
  ELSE.
    LOOP AT cards.
      IF cards-row = moving_row AND cards-col = moving_col.
        cards-col = 0.
        MODIFY cards.
      ENDIF.
    ENDLOOP.
    test_row = moving_row - 1.
    LOOP AT cards.
      IF cards-col = moving_col AND cards-row = test_row.
        cards-vis = 'y'.
        MODIFY cards.
      ENDIF.
    ENDLOOP.
  ENDIF.
  moving_card = space.
ENDFORM.

Arquivos para Download:

Tela de Paciência em ABAP.doc