codeblock的C语言围棋代码,包含吃子和禁手
时间: 2024-05-13 12:18:02 浏览: 51
以下是使用 Code::Blocks IDE 编写的 C语言围棋代码,包括吃子和禁手规则。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BOARD_SIZE 19
#define EMPTY 0
#define BLACK 1
#define WHITE 2
int board[BOARD_SIZE][BOARD_SIZE];
int current_player = BLACK;
void print_board(){
printf(" ");
for(int i=0;i<BOARD_SIZE;++i){
printf("%c ", 'A'+i);
}
printf("\n");
for(int i=0;i<BOARD_SIZE;++i){
printf("%2d", i+1);
for(int j=0;j<BOARD_SIZE;++j){
if(board[i][j] == EMPTY){
printf(" +");
}
else if(board[i][j] == BLACK){
printf(" X");
}
else{
printf(" O");
}
}
printf("\n");
}
}
int is_within_board(int x, int y){
return x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE;
}
int is_surrounded(int x, int y){
if(!is_within_board(x, y) || board[x][y] != EMPTY){
return 0;
}
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for(int i=0;i<4;++i){
int nx = x + dx[i], ny = y + dy[i];
if(is_within_board(nx, ny) && board[nx][ny] == EMPTY){
return 0;
}
}
return 1;
}
int is_legal_move(int x, int y){
if(!is_within_board(x, y) || board[x][y] != EMPTY){
return 0;
}
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for(int i=0;i<4;++i){
int nx = x + dx[i], ny = y + dy[i];
if(is_within_board(nx, ny) && board[nx][ny] == current_player){
if(is_surrounded(nx, ny)){
return 1;
}
}
}
return 0;
}
int is_ko(int x, int y){
int tmp_board[BOARD_SIZE][BOARD_SIZE];
memcpy(tmp_board, board, sizeof(board));
board[x][y] = current_player;
int captured = 0;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for(int i=0;i<4;++i){
int nx = x + dx[i], ny = y + dy[i];
if(is_within_board(nx, ny) && board[nx][ny] == 3 - current_player){
if(is_surrounded(nx, ny)){
captured += 1;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for(int j=0;j<4;++j){
int nnx = nx + dx[j], nny = ny + dy[j];
if(is_within_board(nnx, nny) && board[nnx][nny] == current_player){
if(is_surrounded(nnx, nny)){
board[nx][ny] = EMPTY;
}
}
}
}
}
}
int res = 0;
if(captured == 1){
int cnt = 0;
for(int i=0;i<BOARD_SIZE;++i){
for(int j=0;j<BOARD_SIZE;++j){
if(board[i][j] != tmp_board[i][j]){
cnt += 1;
}
}
}
res = cnt == 1;
}
memcpy(board, tmp_board, sizeof(board));
return res;
}
void do_move(int x, int y){
if(is_legal_move(x, y)){
if(is_ko(x, y)){
printf("Illegal move: ko rule\n");
return;
}
board[x][y] = current_player;
int captured = 0;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for(int i=0;i<4;++i){
int nx = x + dx[i], ny = y + dy[i];
if(is_within_board(nx, ny) && board[nx][ny] == 3 - current_player){
if(is_surrounded(nx, ny)){
captured += 1;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for(int j=0;j<4;++j){
int nnx = nx + dx[j], nny = ny + dy[j];
if(is_within_board(nnx, nny) && board[nnx][nny] == current_player){
if(is_surrounded(nnx, nny)){
board[nx][ny] = EMPTY;
}
}
}
}
}
}
if(captured == 0){
current_player = 3 - current_player;
}
}
else{
printf("Illegal move\n");
}
}
int main(){
memset(board, EMPTY, sizeof(board));
while(1){
print_board();
printf("Current player: %s\n", current_player == BLACK ? "Black(X)" : "White(O)");
printf("Enter move (e.g. A1): ");
char move[10];
scanf("%s", move);
if(strcmp(move, "q") == 0 || strcmp(move, "quit") == 0){
break;
}
if(strlen(move) != 2){
printf("Invalid input\n");
continue;
}
int x = move[1] - '1', y = move[0] - 'A';
do_move(x, y);
}
return 0;
}
```
在这个代码中,我们使用了一个二维数组来表示围棋棋盘,其中 `EMPTY`, `BLACK` 和 `WHITE` 分别代表空位、黑子和白子。我们还定义了一个 `current_player` 变量来表示当前玩家。在 `print_board()` 函数中,我们打印出当前棋盘的状态。
接下来我们定义了一些辅助函数,用于判断一个位置是否在棋盘内、是否被包围、是否可以合法落子等。在 `is_legal_move()` 函数中,我们首先判断目标位置是否在棋盘内且为空位,然后检查该位置周围是否存在己方棋子被包围的情况,如果存在,则说明该位置可以合法落子。
在 `is_ko()` 函数中,我们先判断落子后是否会有对手的棋子被提掉,如果存在,则进一步判断这个提掉的棋子是否唯一。如果唯一,则说明这是一个禁着点,不能落子,否则可以落子。
在 `do_move()` 函数中,我们首先检查目标位置是否可以合法落子,如果合法,则更新棋盘状态,并检查是否有对手的棋子被提掉。如果没有,则交换当前玩家。
最后,在主函数中,我们循环读入玩家的落子,并调用 `do_move()` 函数来更新棋盘状态。如果玩家输入 `q` 或 `quit`,则退出游戏。
阅读全文