home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / xigcv2_8.taz / xigcv2_8 / board.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-08  |  10.8 KB  |  540 lines

  1. /* board.c
  2.  * S.Coffin    USWAT    1/93
  3.  *
  4.  * adapted from adrian@u.washington.edu [with significant changes]
  5.  * keeps local copy of board state, dead stone removal, handicaps, etc
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <time.h>
  10. #include "shared.h"
  11. #include "filter.h"
  12.  
  13. extern int drawStone();
  14. extern int move, currentmove;
  15. extern int boardchanged, mouseflag;
  16. extern int beep();
  17. static int tt;
  18. void removeStones();
  19.  
  20. typedef unsigned char boardtype[20][20];
  21. int prisoners[2], stepprisoners[2];
  22.  
  23. struct movelist {
  24.    int x, y;
  25.    unsigned char flag;
  26. };
  27.  
  28. static struct movelist realmovelist[MAXMOVE], stepmovelist[MAXMOVE];
  29.  
  30. boardtype board, stepboard;
  31.  
  32. #define boolean unsigned char
  33. #define false 0
  34. #define true 1
  35.  
  36. #define piece unsigned char
  37.  
  38. static int boardsize = 19;
  39.  
  40.  
  41. clearboard( b, pris )
  42.     boardtype b;
  43.     int *pris;
  44. {
  45.     int i, j;
  46.     pris[0] = pris[1] = 0;
  47.     for (i = 0; i < boardsize; i++)
  48.     for (j = 0; j < boardsize; j++)
  49.         b[i][j] = EMPTY;
  50. }
  51.  
  52. clear_stepboard() {
  53.     clearboard( stepboard, stepprisoners );
  54. }
  55.  
  56. initboard( size )
  57.     unsigned char size;
  58. {
  59.     boardsize = size;
  60.     clearboard( board, prisoners );
  61.     clearboard( stepboard, stepprisoners );
  62. }
  63.  
  64. unsigned char *stamptime() {
  65.     char *asctime();                /* stuff to get timestamp */
  66.     struct tm *localtime(), *tp;
  67.     struct timeval tv;
  68.     struct timezone tz;
  69.  
  70.     gettimeofday( &tv, &tz );                /* fill in timestamp */
  71.     tp = localtime( (time_t *)&tv.tv_sec );
  72.     return( (unsigned char *)asctime(tp) );
  73. }
  74.  
  75. /* save game in sgf format */
  76. save_game_sgf( s, p1, p2, hcap, type )
  77.     unsigned char *s;    /* file name to save to */
  78.     unsigned char *p1, *p2;    /* player names */
  79.     int hcap;    /* handicap stones or 0 */
  80.     int type;    /* save REALMOVES or STEPMOVES */
  81. {
  82.     FILE *fp;
  83.     int i, x, y;
  84.     unsigned char *str;
  85.     int m;
  86.     struct movelist *ml;
  87.  
  88.     if( type == REALMOVE ) {
  89.         m = move;
  90.         ml = realmovelist;
  91.     }
  92.     else if( type == STEPMOVE ) {
  93.         m = currentmove;
  94.         ml = stepmovelist;
  95.     }
  96.  
  97.     if( (fp = fopen( (char *)s, "a+" )) == NULL ) {
  98.         perror( "savegame" );
  99.         return( 0 );
  100.     }
  101.     fprintf( fp, "(\n;\nPlayerBlack[%s]\nPlayerWhite[%s]\n",
  102.             p2, p1 );
  103.     str = stamptime();
  104.     str[strlen((char *)str)-1] = '\0';
  105.     fprintf( fp, "GaMe[1]\n" );
  106.     fprintf( fp, "VieW[]\n" );
  107.     fprintf( fp, "EVent[]\n" );
  108.     fprintf( fp, "DaTe[%s]\n", str );
  109.     fprintf( fp, "SiZe[%d]\n", boardsize );
  110.     fprintf( fp, "PlaCe[IGS]\n", boardsize );
  111.     if( hcap ) fprintf( fp, "HAndicap[%d]\n", hcap );
  112.     fprintf( fp, "KoMi[??]\n" );
  113.     fprintf( fp, "USer[File created by IGS and xigc]\n" );
  114.  
  115.     if( hcap != 0 ) {
  116.         sgf_hcap( fp, boardsize, hcap );
  117.         i = 1;
  118.     }
  119.     else i = 0;
  120.  
  121.     fprintf( fp, ";\n" );
  122.  
  123.     for( ; i <= m; ++i ) {
  124.         x = ml[i].x + 1;
  125.         y = ml[i].y + 1;
  126.         if( x < 0 ) {        /* pass */
  127.             fprintf( fp, "%s[tt]\n;\n", (i%2) ? "White" : "Black" );
  128.         }
  129.         else {            /* real move */
  130.             fprintf( fp, "%s[%c%c]\n;\n", (i%2) ? "White" : "Black",
  131.                 'a' + (unsigned char)x - 1,
  132.                 'a' + (unsigned char)(boardsize - y) );
  133.         }
  134.     }
  135.  
  136.     fprintf( fp, ")\n" );
  137.  
  138.     fclose( fp );
  139.     return( 1 );
  140. }
  141.  
  142. /* save the moves in a file */
  143. save_game( s, p1, p2, hcap, type )
  144.     unsigned char *s;    /* file name to save to */
  145.     unsigned char *p1, *p2;    /* player names */
  146.     int hcap;    /* handicap stones or 0 */
  147.     int type;    /* save REALMOVE or STEPMOVE */
  148. {
  149.     FILE *fp;
  150.     int i, x, y;
  151.     int m;
  152.     struct movelist *ml;
  153.  
  154.     if( type == REALMOVE ) {
  155.        m = move;
  156.        ml = realmovelist;
  157.     }
  158.     else if( type == STEPMOVE ) {
  159.        m = currentmove;
  160.        ml = stepmovelist;
  161.     }
  162.  
  163.     if( (fp = fopen( (char *)s, "a+" )) == NULL ) {
  164.         perror( "savegame" );
  165.         return( 0 );
  166.     }
  167.  
  168.     fprintf( fp, "\n%s\n", stamptime() );
  169.     fprintf( fp, "White: %s\nBlack: %s\n", p1, p2 );
  170.     fprintf( fp, "Handicap: %d\n\n", hcap );
  171.  
  172.     if( hcap != 0 ) {
  173.         fprintf( fp, "  0 (B): Handicap %d\n", hcap );
  174.         i = 1;
  175.     }
  176.     else i = 0;
  177.  
  178.     for( ; i <= m; ++i ) {
  179.         x = ml[i].x + 1;
  180.         y = ml[i].y + 1;
  181.         fprintf( fp, "%3d (%c):  ", i, (i%2) ? 'W' : 'B' );
  182.         if( x < 0 ) fprintf( fp, "Pass\n" );
  183.         else fprintf( fp, "%c%d\n", 'A' + ((x > 8) ? x + 1 : x) - 1, y );
  184.     }
  185.     fclose( fp );
  186.     return( 1 );
  187. }
  188.  
  189. boolean inRange( i, j )
  190.     int i, j;
  191. {
  192.    return i >= 0 && i < boardsize && j >= 0 && j < boardsize;
  193. }
  194.  
  195. boolean alive0( b, m, i, j, t )
  196.     boardtype b;
  197.     boardtype m;
  198.     int i, j;
  199.     piece t;
  200. {
  201.     piece pt;
  202.  
  203.     pt = b[i][j];
  204.     if ((pt != EMPTY && pt != t) || m[i][j] != EMPTY) return 0;
  205.     m[i][j] = (pt == t) ? (piece) 1 : (piece) 2;
  206.     if (pt == EMPTY) return 1;
  207.     return( j < boardsize - 1 && alive0(b, m, i, j + 1, t)) ||
  208.         (i < boardsize - 1 && alive0(b, m, i + 1, j, t)) ||
  209.         (i && alive0(b, m, i - 1, j, t)) ||
  210.         (j && alive0(b, m, i, j - 1, t));
  211. }
  212.  
  213. /* Does group at i,j have liberties? */
  214. boolean alive( b, i, j )
  215.     boardtype b;
  216.     int i, j;
  217. {
  218.     boardtype m;
  219.     int p[2];
  220.  
  221.     clearboard( m, p );
  222.     return( alive0(b, m, i, j, b[i][j]) );
  223. }
  224.  
  225.  
  226. void removeStones0( b, pris, i, j, t )
  227.     boardtype b;
  228.     int *pris;
  229.     int i, j;
  230.     piece t;
  231. {
  232.     if( b[i][j] != t ) return;
  233.     b[i][j] = EMPTY;
  234.  
  235.     if( tt == REALMOVE ) {
  236.         if( !boardchanged && !mouseflag ) {
  237.             drawStone( i+1, j+1, EMPTY, TRUE );
  238.         }
  239.     }
  240.     else if( tt == STEPMOVE ) {
  241.         if( boardchanged || mouseflag ) {
  242.             drawStone( i+1, j+1, EMPTY, TRUE );
  243.         }
  244.     }
  245.  
  246.     pris[t - 1]++;
  247.     if( j < boardsize - 1 ) removeStones0( b, pris, i, j + 1, t );
  248.     if( i < boardsize - 1 ) removeStones0( b, pris, i + 1, j, t );
  249.     if( i ) removeStones0( b, pris, i - 1, j, t );
  250.     if( j ) removeStones0( b, pris, i, j - 1, t );
  251. }
  252.  
  253. void get_prisoners( x, y )
  254.     int *x, *y;
  255. {
  256.     *x = stepprisoners[0];
  257.     *y = stepprisoners[1];
  258. }
  259.  
  260. void set_prisoners( x, y )
  261.     int x, y;
  262. {
  263.     stepprisoners[0] = x;
  264.     stepprisoners[1] = y;
  265. }
  266.  
  267. void update_prisoners( x, y )
  268.     int x, y;
  269. {
  270.     stepprisoners[0] += x;
  271.     stepprisoners[1] += y;
  272. }
  273.  
  274. void score_it( i, j )
  275.     int i, j;
  276. {
  277.     --i;
  278.     --j;
  279.  
  280.     tt = STEPMOVE;
  281.     boardchanged = TRUE;
  282.     removeStones( stepboard, stepprisoners, i, j );
  283. }
  284.  
  285. void removeStones( b, pris, i, j )
  286.     boardtype b;
  287.     int *pris;
  288.     int i, j;
  289. {
  290.     removeStones0( b, pris, i, j, b[i][j] );
  291. }
  292.  
  293. boolean tryKill( b, pris, i, j, t )
  294.     boardtype b;
  295.     int *pris;
  296.     int i, j;
  297.     piece t;
  298. {
  299.     piece w;
  300.  
  301.     if (!inRange(i, j)) return false;
  302.     w = b[i][j];
  303.     if (w != EMPTY && w != t && !alive(b, i, j)) {
  304.         removeStones(b, pris, i, j);
  305.         return true;
  306.     }
  307.     else return false;
  308. }
  309.  
  310. boolean placeStone( b, pris, i, j, t )
  311.     boardtype b;
  312.     int *pris;
  313.     int i, j;
  314.     piece t;
  315. {
  316.     boolean ret = FALSE;
  317.  
  318.     if (inRange(i, j)) {
  319.         b[i][j] = t;
  320.         if (j) ret = tryKill(b, pris, i, j - 1, t);
  321.         if (j < boardsize - 1) ret |= tryKill(b, pris, i, j + 1, t);
  322.         if (i) ret |= tryKill(b, pris, i - 1, j, t);
  323.         if (i < boardsize - 1) ret |= tryKill(b, pris, i + 1, j, t);
  324.     }
  325.     return( ret );
  326. }
  327.  
  328. /* return the info on move "num"  (real move) */
  329. getmove( num, x, y, f )
  330.     int num;
  331.     int *x, *y, *f;
  332. {
  333.     *x = realmovelist[num].x+1;
  334.     *y = realmovelist[num].y+1;
  335.     *f = (int)realmovelist[num].flag;
  336.     return( num );
  337. }
  338.  
  339. /* delete the move "num" from the movetable */
  340. removemove( num, type )
  341.     int num, type;
  342. {
  343.     int x, y;
  344.  
  345.     if( type == REALMOVE ) {
  346.         x = realmovelist[num].x;
  347.         y = realmovelist[num].y;
  348.         board[x][y] = EMPTY;
  349.         realmovelist[num].x = 0;
  350.         realmovelist[num].y = 0;
  351.         realmovelist[num].flag = FALSE;
  352.     }
  353.     else if( type == STEPMOVE ) {
  354.         x = stepmovelist[num].x;
  355.         y = stepmovelist[num].y;
  356.         stepboard[x][y] = EMPTY;
  357.         stepmovelist[num].x = 0;
  358.         stepmovelist[num].y = 0;
  359.         stepmovelist[num].flag = FALSE;
  360.     }
  361. }
  362.  
  363. makemove( i, j, num, t, type )
  364.     int i, j, num;
  365.     piece t;
  366.     int type;    /* update REALMOVE, STEPMOVE data? */
  367. {
  368.     int x, y, flag;
  369.  
  370.     tt = type;
  371.  
  372.     --i;
  373.     --j;
  374.     if( i < (-1) ) {        /* pass */
  375.         if( type == REALMOVE ) {
  376.             realmovelist[num].x = i;
  377.             realmovelist[num].y = j;
  378.             realmovelist[num].flag = FALSE;
  379.         }
  380.         if( type == STEPMOVE ) {
  381.             stepmovelist[num].x = i;
  382.             stepmovelist[num].y = j;
  383.             stepmovelist[num].flag = FALSE;
  384.         }
  385.     }
  386.     else {                /* place stone */
  387.         if( type == REALMOVE ) {
  388.             realmovelist[num].x = i;
  389.             realmovelist[num].y = j;
  390.             realmovelist[num].flag = placeStone( board, prisoners,
  391.                             i, j, t );
  392.         }
  393.         if( type == STEPMOVE ||
  394.         (type == REALMOVE && (!boardchanged && !mouseflag)) ) {
  395.             stepmovelist[num].x = i;
  396.             stepmovelist[num].y = j;
  397.             stepmovelist[num].flag = placeStone( stepboard,
  398.                     stepprisoners, i, j, t );
  399.         }
  400.         if( type == REALMOVE ) {
  401.         if( !boardchanged && !mouseflag ) drawStone( i+1, j+1, t, TRUE);
  402.             else beep();
  403.         }
  404.         if( type == STEPMOVE && (boardchanged || mouseflag) )
  405.         drawStone( i+1, j+1, t, TRUE );
  406.     }
  407. }
  408.  
  409. static int verts[3][26] = {
  410.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 
  411.     2, 0, 0, 0, 3, 0, 0, 0, 0, 0,  3, 0,  3, 0, 0, 0, 4},
  412.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 
  413.     4, 0, 0, 0, 6, 0, 0, 0, 0, 0,  9, 0, 10, 0, 0, 0, 12},
  414.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 
  415.     6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 17, 0, 0, 0, 20},
  416. };
  417.  
  418. /*
  419.  * Set the handicap of "hand" stones on the board....
  420.  * use "verts" table above....
  421.  */
  422. sethandicap( hand, type )
  423.     int hand;
  424.     int type;
  425. {
  426.     int top, mid, bot;
  427.     piece t;
  428.  
  429.     top = verts[TOP][boardsize] +1;
  430.     mid = verts[MID][boardsize] +1;
  431.     bot = verts[BOT][boardsize] +1;
  432.  
  433.     /* 
  434.      * All of these drop through, '5' checks for odd points.
  435.      */
  436.     t=1;
  437.     switch (hand) {
  438.         case 9:         /* taken care of by handi == 5 */
  439.         case 8: 
  440.         makemove( mid, top, 0, t, type );
  441.         makemove( mid, bot, 0, t, type );
  442.         case 7:         /* taken care of by handi == 5 */
  443.         case 6: 
  444.         makemove( bot, mid, 0, t, type );
  445.         makemove( top, mid, 0, t, type );
  446.         case 5: 
  447.         /* odd points, test because of drop through */
  448.         if (hand & 0x1) {
  449.             makemove( mid, mid, 0, t, type );
  450.         }
  451.         case 4: 
  452.         makemove( bot, top, 0, t, type );
  453.         case 3: 
  454.         makemove( top, bot, 0, t, type );
  455.         case 2: 
  456.         makemove( bot, bot, 0, t, type );
  457.         makemove( top, top, 0, t, type );
  458.         break;
  459.         default: 
  460.         break;
  461.     }
  462. }
  463.  
  464. sgf_hcap( f, s, h )
  465.     FILE *f;
  466.     int s, h;
  467. {
  468.     char *ss = NULL;
  469.  
  470.     switch( s ) {
  471.         case 19:
  472.         switch( h ) {
  473.             case 2:
  474.             ss = "AddBlack[dp][pd]";
  475.             break;
  476.             case 3:
  477.             ss = "AddBlack[dp][pd][dd]";
  478.             break;
  479.             case 4:
  480.             ss = "AddBlack[dd][dp][pd][pp]";
  481.             break;
  482.             case 5:
  483.             ss = "AddBlack[dd][dp][jj][pd][pp]";
  484.             break;
  485.             case 6:
  486.             ss = "AddBlack[dd][dj][dp][pd][pj][pp]";
  487.             break;
  488.             case 7:
  489.             ss = "AddBlack[dd][dj][dp][jj][pd][pj][pp]";
  490.             break;
  491.             case 8:
  492.             ss = "AddBlack[dd][dj][dp][jd][jp][pd][pj][pp]";
  493.             break;
  494.             case 9:
  495.             ss = "AddBlack[dd][dj][dp][jd][jj][jp][pd][pj][pp]";
  496.             break;
  497.             default:
  498.             break;
  499.         }
  500.         break;
  501.         case 13:
  502.         switch( h ) {
  503.             case 2:
  504.             ss = "AddBlack[dj][jd]";
  505.             break;
  506.             case 3:
  507.             ss = "AddBlack[dj][jd][dd]";
  508.             break;
  509.             case 4:
  510.             ss = "AddBlack[dd][dj][jd][jj]";
  511.             break;
  512.             case 5:
  513.             ss = "AddBlack[dd][dj][gg][jd][jj]";
  514.             break;
  515.             default:
  516.             break;
  517.         }
  518.         break;
  519.         case 9:
  520.         switch( h ) {
  521.             case 2:
  522.             ss = "AddBlack[cg][gc]";
  523.             break;
  524.             case 3:
  525.             ss = "AddBlack[cg][gc][cc]";
  526.             break;
  527.             case 4:
  528.             ss = "AddBlack[cc][cg][gc][gg]";
  529.             break;
  530.             default:
  531.             break;
  532.         }
  533.         break;
  534.         default:
  535.         break;
  536.     }
  537.  
  538.     if( ss != NULL ) fprintf( f, ";\n%s\n", ss );
  539. }
  540.