home *** CD-ROM | disk | FTP | other *** search
- #include "comment.header"
-
- /* $Id: score.c,v 1.3 1997/07/06 19:35:06 ergo Exp $ */
-
- /*
- * $Log: score.c,v $
- * Revision 1.3 1997/07/06 19:35:06 ergo
- * actual version
- *
- * Revision 1.2 1997/05/04 18:57:11 ergo
- * added time control for moves
- *
- */
-
- /* Define the following to debug the scoring routine. */
- /* #define _DEBUG_SCORING_ */
-
- #define EMPTY 0
- #define WHITESTONE 1
- #define BLACKSTONE 2
- #define NEUTRAL_TERR 3
- #define WHITE_TERR 4
- #define BLACK_TERR 5
-
- extern unsigned char p[19][19];
- extern int MAXX, MAXY;
- extern int blackCaptured, whiteCaptured, blackTerritory, whiteTerritory;
- unsigned char mark[19][19], ownermat[19][19], scoringmat[19][19];
- unsigned char newpatternmat[19][19], tempmat[19][19], patternmat[19][19];
-
- #ifdef _DEBUG_SCORING_
- #include <stdio.h>
-
- void display_board(void)
- {
- int i, j;
-
- printf("\n\n");
- for (i = 0; i < MAXX; i++)
- {
- for (j = 0; j < MAXY; j++)
- switch (p[i][j])
- {
- case 0:
- printf("+");
- break;
- case 1:
- printf("O");
- break;
- case 2:
- printf("X");
- }
- printf("\n");
- }
- }
- #endif
-
- void set_temp_to_patternmat(void)
- {
- int i, j;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- newpatternmat[i][j] = patternmat[i][j];
- }
-
- void set_patternmat_to_temp(void)
- {
- int i, j;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- patternmat[i][j] = newpatternmat[i][j];
- }
-
- void set_p_to_temp(void)
- /* Copy the board to a temporary array. */
- {
- int i, j;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- p[i][j] = tempmat[i][j];
- }
-
- void set_temp_to_p(void)
- /* Copy the temporary array to the board. */
- {
- int i, j;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- tempmat[i][j] = p[i][j];
- }
-
- void find_pattern_in_board(int x, int y)
- /* Find a pattern of stones or blank spots in the board. */
- {
- int i, j, changes = 1, minx, maxx, miny, maxy;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- patternmat[i][j] = EMPTY;
-
- patternmat[x][y] = 1;
- minx = (x>0)?x-1:0;
- maxx = (x<MAXX-1)?x+1:MAXX-1;
- miny = (y>0)?y-1:0;
- maxy = (y<MAXY-1)?y+1:MAXY-1;
-
- while (changes)
- {
- changes = 0;
- set_temp_to_patternmat();
- for (i = minx; i <= maxx; i++)
- for (j = miny; j <= maxy; j++)
- if (patternmat[i][j] == EMPTY)
- {
- /* Check northern neighbor. */
- if (i > 0)
- {
- if ((patternmat[i-1][j]) && (p[i][j] == p[i-1][j]))
- {
- changes++;
- if (i + 1 > maxx)
- maxx = (i+1<MAXX-1)?i+1:MAXX-1;
- newpatternmat[i][j] = 1;
- }
- }
-
- /* Check eastern neighbor. */
- if (j < MAXY - 1)
- {
- if ((patternmat[i][j+1]) && (p[i][j] == p[i][j+1]))
- {
- changes++;
- if (j - 1 < miny)
- miny = (j-1>0)?j-1:0;
- newpatternmat[i][j] = 1;
- }
- }
-
- /* Check southern neighbor. */
- if (i < MAXX - 1)
- {
- if ((patternmat[i+1][j]) && (p[i][j] == p[i+1][j]))
- {
- changes++;
- if (i - 1 < minx)
- minx = (i-1>0)?i-1:0;
- newpatternmat[i][j] = 1;
- }
- }
-
- /* Check western neighbor. */
- if (j > 0)
- {
- if ((patternmat[i][j-1]) && (p[i][j] == p[i][j-1]))
- {
- changes++;
- if (j + 1 > maxy)
- maxy = (j+1<MAXY-1)?j+1:MAXY-1;
- newpatternmat[i][j] = 1;
- }
- }
- }
- set_patternmat_to_temp();
- }
- }
-
- void find_owner0(int x, int y)
- /* Routine to the find the owner of the blank spot at x, y. */
- {
- int i, j, changes = 1, owner = 0, minx, maxx, miny, maxy;
-
- /* clear_mat(patternmat); */
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- patternmat[i][j] = EMPTY;
-
- patternmat[x][y] = mark[x][y] = 1;
- minx = (x>0)?x-1:0;
- maxx = (x<MAXX-1)?x+1:MAXX-1;
- miny = (y>0)?y-1:0;
- maxy = (y<MAXY-1)?y+1:MAXY-1;
-
- while (changes)
- {
- changes = 0;
- set_temp_to_patternmat();
- for (i = minx; i <= maxx; i++)
- for (j = miny; j <= maxy; j++)
- if (patternmat[i][j] == EMPTY)
- {
- /* Check northern neighbor. */
- if (i > 0)
- {
- if (patternmat[i-1][j])
- {
- if (p[i][j] == EMPTY)
- {
- changes++;
- if (i + 1 > maxx)
- maxx = (i+1<MAXX-1)?i+1:MAXX-1;
- newpatternmat[i][j] = mark[i][j] = 1;
- }
- else
- {
- if (owner == 0)
- owner = p[i][j];
- else if (owner != p[i][j])
- owner = NEUTRAL_TERR;
- }
- }
- }
-
- /* Check eastern neighbor. */
- if (j < MAXY - 1)
- {
- if (patternmat[i][j+1])
- {
- if (p[i][j] == 0)
- {
- changes++;
- if (j - 1 < miny)
- miny = (j-1>0)?j-1:0;
- newpatternmat[i][j] = mark[i][j] = 1;
- }
- else
- {
- if (owner == 0)
- owner = p[i][j];
- else if (owner != p[i][j])
- owner = NEUTRAL_TERR;
- }
- }
- }
-
- /* Check southern neighbor. */
- if (i < MAXX - 1)
- {
- if (patternmat[i+1][j])
- {
- if (p[i][j] == 0)
- {
- changes++;
- if (i - 1 < minx)
- minx = (i-1>0)?i-1:0;
- newpatternmat[i][j] = mark[i][j] = 1;
- }
- else
- {
- if (owner == 0)
- owner = p[i][j];
- else if (owner != p[i][j])
- owner = NEUTRAL_TERR;
- }
- }
- }
-
- /* Check western neighbor. */
- if (j > 0)
- {
- if (patternmat[i][j-1])
- {
- if (p[i][j] == 0)
- {
- changes++;
- if (j + 1 > maxy)
- maxy = (j+1<MAXY-1)?j+1:MAXY-1;
- newpatternmat[i][j] = mark[i][j] = 1;
- }
- else
- {
- if (owner == 0)
- owner = p[i][j];
- else if (owner != p[i][j])
- owner = NEUTRAL_TERR;
- }
- }
- }
- }
- set_patternmat_to_temp();
- }
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXX; j++)
- if (patternmat[i][j])
- ownermat[i][j] = owner;
- }
-
- void find_owner(void)
- /* Determine ownership of all empty points. */
- {
- int i, j;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- {
- mark[i][j] = EMPTY;
- ownermat[i][j] = EMPTY;
- }
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- if ((p[i][j] == EMPTY) && (mark[i][j] == EMPTY))
- find_owner0(i, j);
- }
-
- int surrounds_territory(int x, int y)
- /* Determine if the stones at x, y surround any territory. */
- {
- int i, j, currentcolor = p[x][y], changes = 1, minx, maxx, miny, maxy;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- patternmat[i][j] = EMPTY;
-
- patternmat[x][y] = 1;
- minx = (x>0)?x-1:0;
- maxx = (x<MAXX-1)?x+1:MAXX-1;
- miny = (y>0)?y-1:0;
- maxy = (y<MAXY-1)?y+1:MAXY-1;
-
- while (changes)
- {
- changes = 0;
- set_temp_to_patternmat();
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- if (patternmat[i][j] == 0)
- {
- /* Check northern neighbor. */
- if (i > 0)
- {
- if (patternmat[i-1][j])
- {
- if (p[i][j] == 0)
- {
- if (ownermat[i][j] == currentcolor)
- return 1;
- }
- else
- {
- if (p[i][j] == currentcolor)
- {
- changes++;
- if (i + 1 > maxx)
- maxx = (i+1<MAXX-1)?i+1:MAXX-1;
- newpatternmat[i][j] = 1;
- }
- }
- }
- }
-
- /* Check eastern neighbor. */
- if (j < MAXY - 1)
- {
- if (patternmat[i][j+1])
- {
- if (p[i][j] == 0)
- {
- if (ownermat[i][j] == currentcolor)
- return 1;
- }
- else
- {
- if (p[i][j] == currentcolor)
- {
- changes++;
- if (j - 1 < miny)
- miny = (j-1>0)?j-1:0;
- newpatternmat[i][j] = 1;
- }
- }
- }
- }
-
- /* Check southern neighbor. */
- if (i < MAXX - 1)
- {
- if (patternmat[i+1][j])
- {
- if (p[i][j] == 0)
- {
- if (ownermat[i][j] == currentcolor)
- return 1;
- }
- else
- {
- if (p[i][j] == currentcolor)
- {
- changes++;
- if (i - 1 < minx)
- minx = (i-1>0)?i-1:0;
- newpatternmat[i][j] = 1;
- }
- }
- }
- }
-
- /* Check western neighbor. */
- if (j > 0)
- {
- if (patternmat[i][j-1])
- {
- if (p[i][j] == 0)
- {
- if (ownermat[i][j] == currentcolor)
- return 1;
- }
- else
- {
- if (p[i][j] == currentcolor)
- {
- changes++;
- if (j + 1 > maxy)
- maxy = (j+1<MAXY-1)?j+1:MAXY-1;
- newpatternmat[i][j] = 1;
- }
- }
- }
- }
- }
- set_patternmat_to_temp();
- }
-
- return 0;
- }
-
- void score_game(void)
- /* Score the game and remove dead stones. */
- {
- int i, j, k, l, changes = 1, num_in_pattern;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- scoringmat[i][j] = EMPTY;
-
- while (changes)
- {
- changes = 0;
- find_owner();
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- if ((p[i][j] != EMPTY) && (scoringmat[i][j] == EMPTY))
- {
- if (surrounds_territory(i, j))
- {
- find_pattern_in_board(i, j);
-
- for (k = 0; k < MAXX; k++)
- for (l = 0; l < MAXY; l++)
- if (patternmat[k][l])
- scoringmat[k][l] = p[k][l];
- }
- else
- {
- find_pattern_in_board(i, j);
- set_temp_to_p();
- num_in_pattern = 0;
-
- for (k = 0; k < MAXX; k++)
- for (l = 0; l < MAXY; l++)
- if (patternmat[k][l])
- {
- p[k][l] = EMPTY;
- num_in_pattern++;
- }
-
- find_owner();
-
- if ((ownermat[i][j] != NEUTRAL_TERR) &&
- (ownermat[i][j] != tempmat[i][j]))
- {
- if (tempmat[i][j] == BLACKSTONE)
- blackCaptured += num_in_pattern;
- else
- whiteCaptured += num_in_pattern;
- changes++;
- }
- else
- {
- set_p_to_temp();
- find_owner();
- }
- }
- }
- }
-
- blackTerritory = 0;
- whiteTerritory = 0;
-
- for (i = 0; i < MAXX; i++)
- for (j = 0; j < MAXY; j++)
- {
- if (ownermat[i][j] == BLACKSTONE)
- blackTerritory++;
- if (ownermat[i][j] == WHITESTONE)
- whiteTerritory++;
- }
- }
-