Пример #1
0
// put stone. success returns 0. in playout, fill_eye_err = 1.
int put_stone(int tz, int color, int fill_eye_err)
{
	int around[4][3];
	int un_col = flip_color(color);
	int space = 0;
	int wall = 0;
	int mycol_safe = 0;
	int capture_sum = 0;
	int ko_maybe = 0;
	int liberty, stone;
	int i;

	if (tz == 0) { ko_z = 0; return 0; }  // pass

	// count 4 neighbor's liberty and stones.
	for (i = 0; i<4; i++) {
		int z, c, liberty, stone;
		around[i][0] = around[i][1] = around[i][2] = 0;
		z = tz + dir4[i];
		c = board[z];  // color
		if (c == 0) space++;
		if (c == 3) wall++;
		if (c == 0 || c == 3) continue;
		count_liberty(z, &liberty, &stone);
		around[i][0] = liberty;
		around[i][1] = stone;
		around[i][2] = c;
		if (c == un_col && liberty == 1) { capture_sum += stone; ko_maybe = z; }
		if (c == color  && liberty >= 2) mycol_safe++;
	}

	if (capture_sum == 0 && space == 0 && mycol_safe == 0) return 1; // suicide
	if (tz == ko_z) return 2; // ko
	if (wall + mycol_safe == 4 && fill_eye_err) return 3; // eye
	if (board[tz] != 0) return 4;

	for (i = 0; i<4; i++) {
		int lib = around[i][0];
		int c = around[i][2];
		if (c == un_col && lib == 1 && board[tz + dir4[i]]) {
			take_stone(tz + dir4[i], un_col);
		}
	}

	board[tz] = color;

	count_liberty(tz, &liberty, &stone);
	if (capture_sum == 1 && stone == 1 && liberty == 1) ko_z = ko_maybe;
	else ko_z = 0;
	return 0;
}
Пример #2
0
///< === 更新棋盤
void update_board(int Board[BOUNDARYSIZE][BOUNDARYSIZE], int X, int Y, int turn) 
{
    int num_neighborhood_self = 0;
    int num_neighborhood_oppo = 0;
    int num_neighborhood_empt = 0;
    int num_neighborhood_boun = 0;
    int Liberties[4];
    int NeighboorhoodState[4];

    count_neighboorhood_state(Board, X, Y, turn,
	    &num_neighborhood_empt,
	    &num_neighborhood_self,
	    &num_neighborhood_oppo,
	    &num_neighborhood_boun, NeighboorhoodState);
    
	
    if (num_neighborhood_oppo != 0) 
	{
		count_liberty(X, Y, Board, Liberties);
		for (int d = 0 ; d < MAXDIRECTION; ++d) 
		{
			///< === 對手只有一氣
			if (NeighboorhoodState[d] == OPPONENT && Liberties[d] == 1 && 
				Board[ X + DirectionX[ d ] ][ Y + DirectionY[ d ] ] != EMPTY) 
			{
				remove_piece(Board, X + DirectionX[ d ], Y + DirectionY[ d ], 
					Board[ X + DirectionX[ d ] ][ Y + DirectionY[ d ] ]);
			}
		}
    }
    Board[X][Y] = turn;
}
Пример #3
0
///< === 產生合法步
int gen_legal_move(int Board[BOUNDARYSIZE][BOUNDARYSIZE], int turn, int game_length, 
	int GameRecord[MAXGAMELENGTH][BOUNDARYSIZE][BOUNDARYSIZE], int MoveList[NUMINTERSECTION]) 
{
    int NextBoard[BOUNDARYSIZE][BOUNDARYSIZE];
    int num_neighborhood_self = 0;
    int num_neighborhood_oppo = 0;
    int num_neighborhood_empt = 0;
    int num_neighborhood_boun = 0;
    int legal_moves = 0;
    int next_x, next_y;
    int Liberties[4];
    int NeighboorhoodState[4];
    bool eat_move = 0;

    for (int x = 1 ; x <= BOARDSIZE; ++x) 
	{
		for (int y = 1 ; y <= BOARDSIZE; ++y) 
		{
			///< --- 判斷現在狀態
			if (Board[x][y] == 0) 
			{
				///< --- 檢查氣
				num_neighborhood_self = 0;
				num_neighborhood_oppo = 0;
				num_neighborhood_empt = 0;
				num_neighborhood_boun = 0;
				
				///< --- 判斷周圍的格點
				count_neighboorhood_state(Board, x, y, turn,
					&num_neighborhood_empt,
					&num_neighborhood_self,
					&num_neighborhood_oppo,
					&num_neighborhood_boun, NeighboorhoodState);
		
				///< --- 空的:合法步
				next_x = next_y = 0;
				eat_move = 0;
				count_liberty(x, y, Board, Liberties);
		
				///< --- Case 1: 周圍都是空的點
				if (num_neighborhood_empt > 0) 
				{
					next_x = x;
					next_y = y;
		     
					///< --- 可否提子
					for (int d = 0 ; d < MAXDIRECTION; ++d) 
					{
						if (NeighboorhoodState[d] == OPPONENT && Liberties[d] == 1) 
						{
							eat_move = 1;
						}
					}
				}

				///< --- Case 2: 沒有周圍都是空的點
				else 
				{
					///< --- Case 2.1: 找自己的 string
					if (num_neighborhood_self + num_neighborhood_boun == MAXDIRECTION) 
					{
						int check_flag = 0;
						for (int d = 0 ; d < MAXDIRECTION; ++d) 
						{
							///< --- 自己的 string 是否超過一氣
							if (NeighboorhoodState[d]==SELF && Liberties[d] > 1) 
							{
								check_flag = 1;
							}
						}
						if (check_flag == 1) 
						{
							next_x = x;
							next_y = y;
						}
					}	
		    
					///< --- Case 2.2: 是否被對手圍繞
					else if (num_neighborhood_oppo > 0) 
					{
						int check_flag = 0;
						int eat_flag = 0;
						for (int d = 0 ; d < MAXDIRECTION; ++d) 
						{
							///< --- 對手超過一氣
							if (NeighboorhoodState[d]==SELF && Liberties[d] > 1) 
							{
								check_flag = 1;
							}
							///< --- 對手只有一氣
							if (NeighboorhoodState[d]==OPPONENT && Liberties[d] == 1) 
							{
								eat_flag = 1;
							}
						}
						if (check_flag == 1) 
						{
							next_x = x;
							next_y = y;
							if (eat_flag == 1) 
							{
								eat_move = 1;
							}
						}
						else 
						{ 
							if (eat_flag == 1) 
							{
								next_x = x;
								next_y = y;
								eat_move = 1;
							}
						}
					}	
				}
				if (next_x !=0 && next_y !=0) 
				{
					///< --- 把現在的棋盤做複製
					for (int i = 0 ; i < BOUNDARYSIZE; ++i) 
					{
						for (int j = 0 ; j < BOUNDARYSIZE; ++j) 
						{
							NextBoard[i][j] = Board[i][j];
						}
					}
					///< --- 更新棋盤
					if (eat_move == 1) 
					{
						update_board(NextBoard, next_x, next_y, turn);
					}
					else 
					{
						NextBoard[x][y] = turn;
					}
					///< --- 避免 重複盤面
					bool repeat_move = 0;
					for (int t = 0 ; t < game_length; ++t) 
					{
						bool repeat_flag = 1;
						for (int i = 1; i <=BOARDSIZE; ++i) 
						{
							for (int j = 1; j <=BOARDSIZE; ++j) 
							{
								if (NextBoard[i][j] != GameRecord[t][i][j]) 
								{
									repeat_flag = 0;
								}
							}
						}
						if (repeat_flag == 1) 
						{
							repeat_move = 1;
							break;
						}
					}
					if (repeat_move == 0) 
					{
						///< -- 3 數子 zxy, z 代表吃子 ,  位置為 (x, y)
						MoveList[legal_moves] = eat_move * 100 + next_x * 10 + y ;
						legal_moves++;
					}
				}
			}
		}
    }
    return legal_moves;
}
Пример #4
0
///< === 更新棋盤,並會判斷是否為合法步
int update_board_check(int Board[BOUNDARYSIZE][BOUNDARYSIZE], int X, int Y, int turn) 
{
    if ( X < 1 || X > 7 || Y < 1 || Y > 7 || Board[X][Y]!=EMPTY)
		return 0;

	int num_neighborhood_self = 0;
    int num_neighborhood_oppo = 0;
    int num_neighborhood_empt = 0;
    int num_neighborhood_boun = 0;
    int Liberties[4];
    int NeighboorhoodState[4];

    count_neighboorhood_state(Board, X, Y, turn,
	    &num_neighborhood_empt,
	    &num_neighborhood_self,
	    &num_neighborhood_oppo,
	    &num_neighborhood_boun, NeighboorhoodState);
    
	///< --- 判斷是否為合法步
    ///< --- Condition 1 : 空的格點
    int legal_flag = 0;

    count_liberty(X, Y, Board, Liberties);

    if (num_neighborhood_empt != 0) 
	{
		legal_flag = 1;
    }
    else 
	{
		///< --- Condition 2: 有自己的 string,且超過一氣
		for (int d = 0; d < MAXDIRECTION; ++d) 
		{
			if (NeighboorhoodState[d] == SELF && Liberties[d] > 1) 
			{
				legal_flag = 1;
			}
		}
		if (legal_flag == 0) 
		{
			///< --- Condition 3: 對方的子只有一氣
			for (int d = 0; d < MAXDIRECTION; ++d) 
			{
				if (NeighboorhoodState[d] == OPPONENT && Liberties[d] == 1) 
				{
					legal_flag = 1;
				}
			}
		}
    }

    if (legal_flag == 1) 
	{
		///< --- 判斷是否有對手的棋子在附近
		if (num_neighborhood_oppo != 0) 
		{
			for (int d = 0 ; d < MAXDIRECTION; ++d) 
			{
				///< --- 如果,對手的棋子只有一氣
				if (NeighboorhoodState[d] == OPPONENT && Liberties[d] == 1 &&
					Board[X+DirectionX[d]][Y+DirectionY[d]]!=EMPTY) 
				{
					remove_piece(Board, X + DirectionX[ d ], Y + DirectionY[ d ], 
						Board[ X + DirectionX[ d ] ][ Y + DirectionY[ d ] ]);
				}
			}
		}
		Board[X][Y] = turn;
    }
    return (legal_flag==1)?1:0;
}