home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / MANCALA.ZIP / mancala.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-24  |  4.0 KB  |  169 lines

  1. #include <stdio.h>
  2. #include "mancala.h"
  3. #include "rnd.h"
  4.  
  5.  
  6. static int  owner[14] = {0,0,0,0,0,0,2,1,1,1,1,1,1,2};
  7. static int  opposite[14] = {12,11,10, 9, 8, 7,0, 5, 4, 3, 2, 1, 0,0};
  8.  
  9. static void  player_move(ab_position_t *pos, ab_move_t *move);
  10. static void  print_board(ab_position_t  *pos);
  11.  
  12.  
  13. static rnd_t  rndset;
  14.  
  15.  
  16. main(int argc, char *argv[])  {
  17.     ab_position_t  board;
  18.     int  i, sdepth[2];
  19.     ab_move_t  move;
  20.     ab_storage_t  useless_storage;
  21.  
  22.     rnd_init(&rndset, getpid() + time(0L));
  23.     rnd_use(&rndset);
  24.     if (argc != 3)  {
  25.         fprintf(stderr, "Usage: mancala <Search depth 1> <search depth 2>\n");
  26.         exit(1);
  27.     }
  28.     sdepth[0] = atoi(argv[1]);
  29.     sdepth[1] = atoi(argv[2]);
  30.     for (i = 0;  i < 14;  ++i)
  31.         board.pits[i] = 4;
  32.     board.pits[6] = board.pits[13] = 0;
  33.     board.player_to_move = 0;
  34.     print_board(&board);
  35.     do  {
  36.         if (sdepth[board.player_to_move] > 0)  {
  37.             move = ab_search(&board, sdepth[board.player_to_move]);
  38.             printf("Comp move: %d\n",
  39.                          (move.pit+1)%7, move.score);
  40.         } else
  41.             player_move(&board, &move);
  42.         ab_do_move(&board, &move, &useless_storage);
  43.         print_board(&board);
  44.     } while (board.pits[6] + board.pits[13] < 48);
  45. }
  46.  
  47.  
  48. static void  player_move(ab_position_t *pos, ab_move_t *move)  {
  49.     if (ab_generate_moves(pos, NULL) == 0)
  50.         move->pit = -1;
  51.     else  {
  52.         do  {
  53.             printf("Move--> ");
  54.             scanf("%d", &move->pit);
  55.             move->pit = move->pit - 1 + 7*pos->player_to_move;
  56.         } while ((owner[move->pit] != pos->player_to_move) ||
  57.                          (pos->pits[move->pit] == 0));
  58.     }
  59. }
  60.  
  61.  
  62. int  ab_generate_moves(ab_position_t *pos, ab_move_t *moves)  {
  63.     int  nmoves = 0, i, pitnum;
  64.     ab_storage_t  storage;
  65.  
  66.     pitnum = pos->player_to_move * 7;
  67.     for (i = 0;  i < 6;  ++i)  {
  68.         if (pos->pits[pitnum + i] != 0)  {
  69.             if (moves != NULL)  {
  70.                 moves[nmoves].pit = pitnum + i;
  71.                 moves[nmoves].score = ab_do_move(pos, &moves[nmoves], &storage) +
  72.                     (rnd() & 1023);
  73.                 ab_undo_move(pos, &storage);
  74.             }
  75.             ++nmoves;
  76.         }
  77.     }
  78.     if ((nmoves == 0) && (moves != NULL))  {
  79.         moves[nmoves].pit = -1;
  80.         moves[nmoves].score = 0;
  81.         ++nmoves;
  82.     }
  83.     return(nmoves);
  84. }
  85.  
  86.  
  87. ab_score_t  ab_do_move(ab_position_t *pos, ab_move_t *move,
  88.                                              ab_storage_t *storage)  {
  89.     int  i, pitnum, stones, skip_pit, score_pit, orig_pit, dead_pit;
  90.     int  score = 0;
  91.  
  92.     for (i = 0;  i < 14;  ++i)  {
  93.         storage->oldpits[i] = pos->pits[i];
  94.     }
  95.     storage->old_tomove = pos->player_to_move;
  96.     pitnum = orig_pit = move->pit;
  97.     if (pitnum == -1)  {
  98.         /* The null move.  Only possible when there is no legal move. */
  99.         pos->player_to_move ^= 1;
  100.         return(0);
  101.     }
  102.     stones = pos->pits[pitnum];
  103.     pos->pits[pitnum] = 0;
  104.     if (pitnum < 7)  {
  105.         skip_pit = 13;
  106.         score_pit = 6;
  107.     } else  {
  108.         skip_pit = 6;
  109.         score_pit = 13;
  110.     }
  111.     while (stones > 0)  {
  112.         ++pitnum;
  113.         if (pitnum == skip_pit)
  114.             ++pitnum;
  115.         if (pitnum == 14)
  116.             pitnum = 0;
  117.         ++pos->pits[pitnum];
  118.         if (pitnum == score_pit)
  119.             ++score;
  120.         --stones;
  121.     }
  122.     if ((pos->pits[pitnum] == 1) &&
  123.             (owner[pitnum] == owner[orig_pit]))  {
  124.         dead_pit = opposite[pitnum];
  125.         if (dead_pit > 13)
  126.             dead_pit -= 14;
  127.         score += pos->pits[dead_pit];
  128.         pos->pits[score_pit] += pos->pits[dead_pit];
  129.         pos->pits[dead_pit] = 0;
  130.     }
  131.     if (pitnum != score_pit)
  132.         pos->player_to_move ^= 1;
  133.     return(score * 1024);
  134. }
  135.  
  136.  
  137. void  ab_undo_move(ab_position_t *pos, ab_storage_t *storage)  {
  138.     int  i;
  139.  
  140.     for (i = 0;  i < 14;  ++i)  {
  141.         pos->pits[i] = storage->oldpits[i];
  142.         pos->player_to_move = storage->old_tomove;
  143.     }
  144. }
  145.  
  146.  
  147. int  ab_move_cmp(ab_move_t *mv1, ab_move_t *mv2)  {
  148.     if (mv1->score == mv2->score)
  149.         return(mv2->pit - mv1->pit);
  150.     else
  151.         return(mv2->score - mv1->score);
  152. }
  153.  
  154.  
  155. static void  print_board(ab_position_t  *pos)  {
  156.     printf("    6  5  4  3  2  1\n");
  157.     printf("   -- -- -- -- -- --\n");
  158.     printf("   %2d|%2d|%2d|%2d|%2d|%2d\n",
  159.                  pos->pits[5], pos->pits[4], pos->pits[3],
  160.                  pos->pits[2], pos->pits[1], pos->pits[0]);
  161.     printf(" %2d--+--+--+--+--+--%2d\n",
  162.                  pos->pits[6], pos->pits[13]);
  163.     printf("   %2d|%2d|%2d|%2d|%2d|%2d\n",
  164.                  pos->pits[7], pos->pits[8], pos->pits[9],
  165.                  pos->pits[10], pos->pits[11], pos->pits[12]);
  166.     printf("   -- -- -- -- -- --\n");
  167.     printf("    1  2  3  4  5  6\n\n");
  168. }
  169.