home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume6 / sokoban2 / part01 / play.c < prev    next >
C/C++ Source or Header  |  1989-03-15  |  7KB  |  239 lines

  1. #include <ctype.h>
  2. #include <curses.h>
  3. #include "sokoban.h"
  4.  
  5. /* defining the types of move */
  6. #define MOVE         1
  7. #define PUSH         2
  8. #define SAVE         3
  9. #define UNSAVE         4
  10. #define STOREMOVE     5
  11. #define STOREPUSH     6
  12.  
  13. /* defines for control characters */
  14. #define CNTL_L        '\014'
  15. #define CNTL_K        '\013'
  16. #define CNTL_H        '\010'
  17. #define CNTL_J        '\012'
  18. #define CNTL_R        '\022'
  19. #define CNTL_U        '\025'
  20.  
  21. extern char  map[MAXROW+1][MAXCOL+1];
  22. extern short rows, cols, level, moves, pushes, savepack, packets;
  23. extern short scorelevel, scoremoves, scorepushes;
  24. extern POS   ppos;
  25.  
  26. static POS   tpos1,           /* testpos1: 1 pos. over/under/left/right */
  27.              tpos2,           /* testpos2: 2 pos.  "                    */
  28.              lastppos,           /* the last player position (for undo)    */
  29.              lasttpos1, lasttpos2; /* last test positions (for undo)         */
  30. static char lppc, ltp1c, ltp2c;    /* the char for the above pos. (for undo) */
  31. static short action, lastaction;
  32.  
  33. /** For the temporary save **/
  34. static char  tmp_map[MAXROW+1][MAXCOL+1];
  35. static short tmp_pushes, tmp_moves, tmp_savepack;
  36. static POS   tmp_ppos;
  37.  
  38. short play() {
  39.  
  40.    short c;
  41.    short ret;
  42.    short undolock = 1;        /* locked for undo */
  43.  
  44.    showscreen();
  45.    tmpsave();
  46.    ret = 0;
  47.    while( ret == 0) {
  48.       switch( (c = getch())) {
  49.      case 'q':    /* quit the game                     */
  50.                   ret = E_ENDGAME; 
  51.                   break;
  52.      case 's':    /* save the games                    */
  53.               if( (ret = savegame()) == 0)
  54.              ret = E_SAVED;
  55.               break;
  56.      case '?':    /* show the help file                */
  57.               showhelp();
  58.               showscreen();
  59.               break;
  60.      case CNTL_R: /* refresh the screen                 */
  61.               clear();
  62.               showscreen();
  63.               break;
  64.      case 'c':    /* temporary save                    */
  65.               tmpsave();
  66.               break;
  67.      case CNTL_U: /* reset to temporary save             */
  68.               tmpreset();
  69.               undolock = 1;
  70.               showscreen();
  71.               break;
  72.      case 'U':    /* undo this level                 */
  73.               moves = pushes = 0;
  74.               if( (ret = readscreen()) == 0) {
  75.                  showscreen();
  76.              undolock = 1;
  77.               }
  78.               break;
  79.      case 'u':    /* undo last move                 */
  80.               if( ! undolock) {
  81.                  undomove();
  82.                  undolock = 1;
  83.               }
  84.               break;
  85.      case 'k':    /* up                         */
  86.      case 'K':    /* run up                     */
  87.      case CNTL_K: /* run up, stop before object             */
  88.      case 'j':    /* down                         */
  89.      case 'J':    /* run down                     */
  90.      case CNTL_J: /* run down, stop before object             */
  91.      case 'l':    /* right                         */
  92.      case 'L':    /* run right                     */
  93.      case CNTL_L: /* run right, stop before object             */
  94.      case 'h':    /* left                         */
  95.      case 'H':    /* run left                     */
  96.      case CNTL_H: /* run left, stop before object             */
  97.               do {
  98.                  if( (action = testmove( c)) != 0) {
  99.                 lastaction = action;
  100.                     lastppos.x = ppos.x; lastppos.y = ppos.y;
  101.                     lppc = map[ppos.x][ppos.y];
  102.                     lasttpos1.x = tpos1.x; lasttpos1.y = tpos1.y; 
  103.                     ltp1c = map[tpos1.x][tpos1.y];
  104.                     lasttpos2.x = tpos2.x; lasttpos2.y = tpos2.y; 
  105.                     ltp2c = map[tpos2.x][tpos2.y];
  106.                     domove( lastaction); 
  107.                     undolock = 0;
  108.                  }
  109.               } while( (action != 0) && (! islower( c))
  110.                   && (packets != savepack));
  111.               break;
  112.      default:     helpmessage(); break;
  113.       }
  114.       if( (ret == 0) && (packets == savepack)) {
  115.      scorelevel = level;
  116.      scoremoves = moves;
  117.      scorepushes = pushes;
  118.      break;
  119.       }
  120.    }
  121.    return( ret);
  122. }
  123.  
  124. testmove( action)
  125. register short action;
  126. {
  127.    register short ret;
  128.    register char  tc;
  129.    register short stop_at_object;
  130.  
  131.    if( (stop_at_object = iscntrl( action))) action = action + 'A' - 1;
  132.    action = (isupper( action)) ? tolower( action) : action;
  133.    if( (action == 'k') || (action == 'j')) {
  134.       tpos1.x = (action == 'k') ? ppos.x-1 : ppos.x+1;
  135.       tpos2.x = (action == 'k') ? ppos.x-2 : ppos.x+2;
  136.       tpos1.y = tpos2.y = ppos.y;
  137.    }
  138.    else {
  139.       tpos1.y = (action == 'h') ? ppos.y-1 : ppos.y+1;
  140.       tpos2.y = (action == 'h') ? ppos.y-2 : ppos.y+2;
  141.       tpos1.x = tpos2.x = ppos.x;
  142.    }
  143.    tc = map[tpos1.x][tpos1.y];
  144.    if( (tc == packet.obj_intern) || (tc == save.obj_intern)) {
  145.       if( ! stop_at_object) {
  146.          if( map[tpos2.x][tpos2.y] == ground.obj_intern)
  147.             ret = (tc == save.obj_intern) ? UNSAVE : PUSH;
  148.          else if( map[tpos2.x][tpos2.y] == store.obj_intern)
  149.             ret = (tc == save.obj_intern) ? STOREPUSH : SAVE;
  150.          else ret = 0;
  151.       }
  152.       else ret = 0;
  153.    }
  154.    else if( tc == ground.obj_intern)
  155.       ret = MOVE;
  156.    else if( tc == store.obj_intern)
  157.       ret = STOREMOVE;
  158.    else ret = 0;
  159.    return( ret);
  160. }
  161.  
  162. domove( moveaction) 
  163. register short moveaction;
  164. {
  165.    map[ppos.x][ppos.y] = (map[ppos.x][ppos.y] == player.obj_intern) 
  166.                    ? ground.obj_intern 
  167.                    : store.obj_intern;
  168.    switch( moveaction) {
  169.       case MOVE:      map[tpos1.x][tpos1.y] = player.obj_intern;     break;
  170.       case STOREMOVE: map[tpos1.x][tpos1.y] = playerstore.obj_intern;     break;
  171.       case PUSH:      map[tpos2.x][tpos2.y] = map[tpos1.x][tpos1.y];
  172.               map[tpos1.x][tpos1.y] = player.obj_intern;    
  173.               pushes++;                        break;
  174.       case UNSAVE:    map[tpos2.x][tpos2.y] = packet.obj_intern;
  175.               map[tpos1.x][tpos1.y] = playerstore.obj_intern;        
  176.               pushes++; savepack--;                 break;
  177.       case SAVE:      map[tpos2.x][tpos2.y] = save.obj_intern;
  178.               map[tpos1.x][tpos1.y] = player.obj_intern;            
  179.               savepack++; pushes++;                break;
  180.       case STOREPUSH: map[tpos2.x][tpos2.y] = save.obj_intern;
  181.               map[tpos1.x][tpos1.y] = playerstore.obj_intern;        
  182.               pushes++;                        break;
  183.    }
  184.    moves++;
  185.    dispmoves(); disppushes(); dispsave();
  186.    mapchar( map[ppos.x][ppos.y], ppos.x, ppos.y);
  187.    mapchar( map[tpos1.x][tpos1.y], tpos1.x, tpos1.y);
  188.    mapchar( map[tpos2.x][tpos2.y], tpos2.x, tpos2.y);
  189.    move( MAXROW+1, 0);
  190.    refresh();
  191.    ppos.x = tpos1.x; ppos.y = tpos1.y;
  192. }
  193.  
  194. undomove() {
  195.  
  196.    map[lastppos.x][lastppos.y] = lppc;
  197.    map[lasttpos1.x][lasttpos1.y] = ltp1c;
  198.    map[lasttpos2.x][lasttpos2.y] = ltp2c;
  199.    ppos.x = lastppos.x; ppos.y = lastppos.y;
  200.    switch( lastaction) {
  201.       case MOVE:      moves--;                break;
  202.       case STOREMOVE: moves--;                break;
  203.       case PUSH:      moves--; pushes--;        break;
  204.       case UNSAVE:    moves--; pushes--; savepack++;    break;
  205.       case SAVE:      moves--; pushes--; savepack--;    break;
  206.       case STOREPUSH: moves--; pushes--;        break;
  207.    }
  208.    dispmoves(); disppushes(); dispsave();
  209.    mapchar( map[ppos.x][ppos.y], ppos.x, ppos.y);
  210.    mapchar( map[lasttpos1.x][lasttpos1.y], lasttpos1.x, lasttpos1.y);
  211.    mapchar( map[lasttpos2.x][lasttpos2.y], lasttpos2.x, lasttpos2.y);
  212.    move( MAXROW+1, 0);
  213.    refresh();
  214. }
  215.  
  216. tmpsave() {
  217.  
  218.    register short i, j;
  219.  
  220.    for( i = 0; i < rows; i++) for( j = 0; j < cols; j++)
  221.       tmp_map[i][j] = map[i][j];
  222.    tmp_pushes = pushes;
  223.    tmp_moves = moves;
  224.    tmp_savepack = savepack;
  225.    tmp_ppos.x = ppos.x; tmp_ppos.y = ppos.y;
  226. }
  227.  
  228. tmpreset() {
  229.  
  230.    register short i, j;
  231.  
  232.    for( i = 0; i < rows; i++) for( j = 0; j < cols; j++)
  233.       map[i][j] = tmp_map[i][j];
  234.    pushes = tmp_pushes;
  235.    moves = tmp_moves;
  236.    savepack = tmp_savepack;
  237.    ppos.x = tmp_ppos.x; ppos.y = tmp_ppos.y;
  238. }
  239.