// 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; }
///< === 更新棋盤 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; }
///< === 產生合法步 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; }
///< === 更新棋盤,並會判斷是否為合法步 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; }