home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / Games / NeXTGo-3.0-MIS / score.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-06  |  9.5 KB  |  504 lines

  1. #include "comment.header"
  2.  
  3. /* $Id: score.c,v 1.3 1997/07/06 19:35:06 ergo Exp $ */
  4.  
  5. /*
  6.  * $Log: score.c,v $
  7.  * Revision 1.3  1997/07/06 19:35:06  ergo
  8.  * actual version
  9.  *
  10.  * Revision 1.2  1997/05/04 18:57:11  ergo
  11.  * added time control for moves
  12.  *
  13.  */
  14.  
  15. /*  Define the following to debug the scoring routine.  */
  16. /*  #define _DEBUG_SCORING_  */
  17.  
  18. #define EMPTY        0
  19. #define WHITESTONE   1
  20. #define BLACKSTONE   2
  21. #define NEUTRAL_TERR 3
  22. #define WHITE_TERR   4
  23. #define BLACK_TERR   5
  24.  
  25. extern unsigned char p[19][19];
  26. extern int MAXX, MAXY;
  27. extern int blackCaptured, whiteCaptured, blackTerritory, whiteTerritory;
  28. unsigned char mark[19][19], ownermat[19][19], scoringmat[19][19];
  29. unsigned char newpatternmat[19][19], tempmat[19][19], patternmat[19][19];
  30.  
  31. #ifdef _DEBUG_SCORING_
  32. #include <stdio.h>
  33.  
  34. void display_board(void)
  35. {
  36.   int i, j;
  37.  
  38.   printf("\n\n");
  39.   for (i = 0; i < MAXX; i++)
  40.     {
  41.       for (j = 0; j < MAXY; j++)
  42.     switch (p[i][j])
  43.       {
  44.       case 0: 
  45.         printf("+");
  46.         break;
  47.       case 1:
  48.         printf("O");
  49.         break;
  50.       case 2:
  51.         printf("X");
  52.       }
  53.       printf("\n");
  54.     }
  55. }
  56. #endif
  57.  
  58. void set_temp_to_patternmat(void)
  59. {
  60.   int i, j;
  61.  
  62.   for (i = 0; i < MAXX; i++)
  63.     for (j = 0; j < MAXY; j++)
  64.       newpatternmat[i][j] = patternmat[i][j];
  65. }
  66.  
  67. void set_patternmat_to_temp(void)
  68. {
  69.   int i, j;
  70.  
  71.   for (i = 0; i < MAXX; i++)
  72.     for (j = 0; j < MAXY; j++)
  73.       patternmat[i][j] = newpatternmat[i][j];
  74. }
  75.  
  76. void set_p_to_temp(void)
  77. /*  Copy the board to a temporary array.  */
  78. {
  79.   int i, j;
  80.  
  81.   for (i = 0; i < MAXX; i++)
  82.     for (j = 0; j < MAXY; j++)
  83.       p[i][j] = tempmat[i][j];
  84. }
  85.  
  86. void set_temp_to_p(void)
  87. /*  Copy the temporary array to the board.  */
  88. {
  89.   int i, j;
  90.  
  91.   for (i = 0; i < MAXX; i++)
  92.     for (j = 0; j < MAXY; j++)
  93.       tempmat[i][j] = p[i][j];
  94. }
  95.  
  96. void find_pattern_in_board(int x, int y)
  97. /*  Find a pattern of stones or blank spots in the board.  */
  98. {
  99.   int i, j, changes = 1, minx, maxx, miny, maxy;
  100.  
  101.   for (i = 0; i < MAXX; i++)
  102.     for (j = 0; j < MAXY; j++)
  103.       patternmat[i][j] = EMPTY;
  104.  
  105.   patternmat[x][y] = 1;
  106.   minx = (x>0)?x-1:0;
  107.   maxx = (x<MAXX-1)?x+1:MAXX-1;
  108.   miny = (y>0)?y-1:0;
  109.   maxy = (y<MAXY-1)?y+1:MAXY-1;
  110.  
  111.   while (changes)
  112.     {
  113.       changes = 0;
  114.       set_temp_to_patternmat();
  115.       for (i = minx; i <= maxx; i++)
  116.     for (j = miny; j <= maxy; j++)
  117.       if (patternmat[i][j] == EMPTY)
  118.       {
  119.         /*  Check northern neighbor.  */
  120.         if (i > 0)
  121.           {
  122.         if ((patternmat[i-1][j]) && (p[i][j] == p[i-1][j]))
  123.           {
  124.             changes++;
  125.             if (i + 1 > maxx)
  126.               maxx = (i+1<MAXX-1)?i+1:MAXX-1;
  127.             newpatternmat[i][j] = 1;
  128.           }
  129.           }
  130.  
  131.         /*  Check eastern neighbor.  */
  132.         if (j < MAXY - 1)
  133.           {
  134.         if ((patternmat[i][j+1]) && (p[i][j] == p[i][j+1]))
  135.           {
  136.             changes++;
  137.             if (j - 1 < miny)
  138.               miny = (j-1>0)?j-1:0;
  139.             newpatternmat[i][j] = 1;
  140.           }
  141.           }
  142.  
  143.         /*  Check southern neighbor.  */
  144.         if (i < MAXX - 1)
  145.           {
  146.         if ((patternmat[i+1][j]) && (p[i][j] == p[i+1][j]))
  147.           {
  148.             changes++;
  149.             if (i - 1 < minx)
  150.               minx = (i-1>0)?i-1:0;
  151.             newpatternmat[i][j] = 1;
  152.           }
  153.           }
  154.  
  155.         /*  Check western neighbor.  */
  156.         if (j > 0)
  157.           {
  158.         if ((patternmat[i][j-1]) && (p[i][j] == p[i][j-1]))
  159.           {
  160.             changes++;
  161.             if (j + 1 > maxy)
  162.               maxy = (j+1<MAXY-1)?j+1:MAXY-1;
  163.             newpatternmat[i][j] = 1;
  164.           }
  165.           }
  166.       }
  167.       set_patternmat_to_temp();
  168.     }
  169. }
  170.  
  171. void find_owner0(int x, int y)
  172. /*  Routine to the find the owner of the blank spot at x, y.  */
  173. {
  174.   int i, j, changes = 1, owner = 0, minx, maxx, miny, maxy;
  175.  
  176. /*  clear_mat(patternmat);  */
  177.   for (i = 0; i < MAXX; i++)
  178.     for (j = 0; j < MAXY; j++)
  179.       patternmat[i][j] = EMPTY;
  180.  
  181.   patternmat[x][y] = mark[x][y] = 1;
  182.   minx = (x>0)?x-1:0;
  183.   maxx = (x<MAXX-1)?x+1:MAXX-1;
  184.   miny = (y>0)?y-1:0;
  185.   maxy = (y<MAXY-1)?y+1:MAXY-1;
  186.  
  187.   while (changes)
  188.     {
  189.       changes = 0;
  190.       set_temp_to_patternmat();
  191.       for (i = minx; i <= maxx; i++)
  192.     for (j = miny; j <= maxy; j++)
  193.       if (patternmat[i][j] == EMPTY)
  194.       {
  195.         /*  Check northern neighbor.  */
  196.         if (i > 0)
  197.           {
  198.         if (patternmat[i-1][j])
  199.           {
  200.             if (p[i][j] == EMPTY)
  201.               {
  202.             changes++;
  203.             if (i + 1 > maxx)
  204.               maxx = (i+1<MAXX-1)?i+1:MAXX-1;
  205.             newpatternmat[i][j] = mark[i][j] = 1;
  206.               }
  207.             else
  208.               {
  209.             if (owner == 0)
  210.               owner = p[i][j];
  211.             else if (owner != p[i][j])
  212.               owner = NEUTRAL_TERR;
  213.               }
  214.           }
  215.           }
  216.  
  217.         /*  Check eastern neighbor.  */
  218.         if (j < MAXY - 1)
  219.           {
  220.         if (patternmat[i][j+1])
  221.           {
  222.             if (p[i][j] == 0)
  223.               {
  224.             changes++;
  225.             if (j - 1 < miny)
  226.               miny = (j-1>0)?j-1:0;
  227.             newpatternmat[i][j] = mark[i][j] = 1;
  228.               }
  229.             else
  230.               {
  231.             if (owner == 0)
  232.               owner = p[i][j];
  233.             else if (owner != p[i][j])
  234.               owner = NEUTRAL_TERR;
  235.               }
  236.           }
  237.           }
  238.  
  239.         /*  Check southern neighbor.  */
  240.         if (i < MAXX - 1)
  241.           {
  242.         if (patternmat[i+1][j])
  243.           {
  244.             if (p[i][j] == 0)
  245.               {
  246.             changes++;
  247.             if (i - 1 < minx)
  248.               minx = (i-1>0)?i-1:0;
  249.             newpatternmat[i][j] = mark[i][j] = 1;
  250.               }
  251.             else
  252.               {
  253.             if (owner == 0)
  254.               owner = p[i][j];
  255.             else if (owner != p[i][j])
  256.               owner = NEUTRAL_TERR;
  257.               }
  258.           }
  259.           }
  260.  
  261.         /*  Check western neighbor.  */
  262.         if (j > 0)
  263.           {
  264.         if (patternmat[i][j-1])
  265.           {
  266.             if (p[i][j] == 0)
  267.               {
  268.             changes++;
  269.             if (j + 1 > maxy)
  270.               maxy = (j+1<MAXY-1)?j+1:MAXY-1;
  271.             newpatternmat[i][j] = mark[i][j] = 1;
  272.               }
  273.             else
  274.               {
  275.             if (owner == 0)
  276.               owner = p[i][j];
  277.             else if (owner != p[i][j])
  278.               owner = NEUTRAL_TERR;
  279.               }
  280.           }
  281.           }
  282.       }
  283.       set_patternmat_to_temp();
  284.     }
  285.  
  286.   for (i = 0; i < MAXX; i++)
  287.     for (j = 0; j < MAXX; j++)
  288.       if (patternmat[i][j])
  289.     ownermat[i][j] = owner;
  290. }
  291.  
  292. void find_owner(void)
  293. /*  Determine ownership of all empty points.  */
  294. {
  295.   int i, j;
  296.  
  297.   for (i = 0; i < MAXX; i++)
  298.     for (j = 0; j < MAXY; j++)
  299.       {
  300.     mark[i][j] = EMPTY;
  301.     ownermat[i][j] = EMPTY;
  302.       }
  303.  
  304.   for (i = 0; i < MAXX; i++)
  305.     for (j = 0; j < MAXY; j++)
  306.       if ((p[i][j] == EMPTY) && (mark[i][j] == EMPTY))
  307.     find_owner0(i, j);
  308. }
  309.  
  310. int surrounds_territory(int x, int y)
  311. /*  Determine if the stones at x, y surround any territory.  */
  312. {
  313.   int i, j, currentcolor = p[x][y], changes = 1, minx, maxx, miny, maxy;
  314.  
  315.   for (i = 0; i < MAXX; i++)
  316.     for (j = 0; j < MAXY; j++)
  317.       patternmat[i][j] = EMPTY;
  318.  
  319.   patternmat[x][y] = 1;
  320.   minx = (x>0)?x-1:0;
  321.   maxx = (x<MAXX-1)?x+1:MAXX-1;
  322.   miny = (y>0)?y-1:0;
  323.   maxy = (y<MAXY-1)?y+1:MAXY-1;
  324.  
  325.   while (changes)
  326.     {
  327.       changes = 0;
  328.       set_temp_to_patternmat();
  329.       for (i = 0; i < MAXX; i++)
  330.     for (j = 0; j < MAXY; j++)
  331.       if (patternmat[i][j] == 0)
  332.       {
  333.         /*  Check northern neighbor.  */
  334.         if (i > 0)
  335.           {
  336.         if (patternmat[i-1][j])
  337.           {
  338.             if (p[i][j] == 0)
  339.               {
  340.             if (ownermat[i][j] == currentcolor)
  341.               return 1;
  342.               }
  343.             else
  344.               {
  345.             if (p[i][j] == currentcolor)
  346.               {
  347.                 changes++;
  348.                 if (i + 1 > maxx)
  349.                   maxx = (i+1<MAXX-1)?i+1:MAXX-1;
  350.                 newpatternmat[i][j] = 1;
  351.               }
  352.               }
  353.           }
  354.           }
  355.  
  356.         /*  Check eastern neighbor.  */
  357.         if (j < MAXY - 1)
  358.           {
  359.         if (patternmat[i][j+1])
  360.           {
  361.             if (p[i][j] == 0)
  362.               {
  363.             if (ownermat[i][j] == currentcolor)
  364.               return 1;
  365.               }
  366.             else
  367.               {
  368.             if (p[i][j] == currentcolor)
  369.               {
  370.                 changes++;
  371.                 if (j - 1 < miny)
  372.                   miny = (j-1>0)?j-1:0;
  373.                 newpatternmat[i][j] = 1;
  374.               }
  375.               }
  376.           }
  377.           }
  378.  
  379.         /*  Check southern neighbor.  */
  380.         if (i < MAXX - 1)
  381.           {
  382.         if (patternmat[i+1][j])
  383.           {
  384.             if (p[i][j] == 0)
  385.               {
  386.             if (ownermat[i][j] == currentcolor)
  387.               return 1;
  388.               }
  389.             else
  390.               {
  391.             if (p[i][j] == currentcolor)
  392.               {
  393.                 changes++;
  394.                 if (i - 1 < minx)
  395.                   minx = (i-1>0)?i-1:0;
  396.                 newpatternmat[i][j] = 1;
  397.               }
  398.               }
  399.           }
  400.           }
  401.  
  402.         /*  Check western neighbor.  */
  403.         if (j > 0)
  404.           {
  405.         if (patternmat[i][j-1])
  406.           {
  407.             if (p[i][j] == 0)
  408.               {
  409.             if (ownermat[i][j] == currentcolor)
  410.               return 1;
  411.               }
  412.             else
  413.               {
  414.             if (p[i][j] == currentcolor)
  415.               {
  416.                 changes++;
  417.                 if (j + 1 > maxy)
  418.                   maxy = (j+1<MAXY-1)?j+1:MAXY-1;
  419.                 newpatternmat[i][j] = 1;
  420.               }
  421.               }
  422.           }
  423.           }
  424.       }
  425.       set_patternmat_to_temp();
  426.     }
  427.  
  428.   return 0;
  429. }
  430.  
  431. void score_game(void)
  432. /*  Score the game and remove dead stones.  */
  433. {
  434.   int i, j, k, l, changes = 1, num_in_pattern;
  435.  
  436.   for (i = 0; i < MAXX; i++)
  437.     for (j = 0; j < MAXY; j++)
  438.       scoringmat[i][j] = EMPTY;
  439.  
  440.   while (changes)
  441.     {
  442.       changes = 0;
  443.       find_owner();
  444.  
  445.       for (i = 0; i < MAXX; i++)
  446.     for (j = 0; j < MAXY; j++)
  447.       if ((p[i][j] != EMPTY) && (scoringmat[i][j] == EMPTY))
  448.         {
  449.           if (surrounds_territory(i, j))
  450.         {
  451.           find_pattern_in_board(i, j);
  452.  
  453.           for (k = 0; k < MAXX; k++)
  454.             for (l = 0; l < MAXY; l++)
  455.               if (patternmat[k][l])
  456.             scoringmat[k][l] = p[k][l];
  457.         }
  458.           else
  459.         {
  460.           find_pattern_in_board(i, j);
  461.           set_temp_to_p();
  462.           num_in_pattern = 0;
  463.  
  464.           for (k = 0; k < MAXX; k++)
  465.             for (l = 0; l < MAXY; l++)
  466.               if (patternmat[k][l])
  467.             {
  468.               p[k][l] = EMPTY;
  469.               num_in_pattern++;
  470.             }
  471.  
  472.           find_owner();
  473.  
  474.           if ((ownermat[i][j] != NEUTRAL_TERR) &&
  475.               (ownermat[i][j] != tempmat[i][j]))
  476.             {
  477.               if (tempmat[i][j] == BLACKSTONE)
  478.             blackCaptured += num_in_pattern;
  479.               else
  480.             whiteCaptured += num_in_pattern;
  481.               changes++;
  482.             }
  483.           else
  484.             {
  485.               set_p_to_temp();
  486.               find_owner();
  487.             }
  488.         }
  489.         }
  490.     }
  491.  
  492.   blackTerritory = 0;
  493.   whiteTerritory = 0;
  494.  
  495.   for (i = 0; i < MAXX; i++)
  496.     for (j = 0; j < MAXY; j++)
  497.       {
  498.     if (ownermat[i][j] == BLACKSTONE)
  499.       blackTerritory++;
  500.     if (ownermat[i][j] == WHITESTONE)
  501.       whiteTerritory++;
  502.       }
  503. }
  504.