codeblocks的C语言围棋双人对战程序包含吃子,计算外气,禁手规则以及自动提子的代码
时间: 2023-06-24 12:06:40 浏览: 167
围棋对弈程序
以下是一个简单的围棋双人对战程序,包含吃子、计算外气、禁手规则以及自动提子的代码。这个程序使用Code::Blocks和C语言编写。
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define BOARD_SIZE 9
#define EMPTY 0
#define BLACK 1
#define WHITE 2
int board[BOARD_SIZE][BOARD_SIZE];
int current_player = BLACK;
bool is_legal_move(int x, int y) {
if (board[x][y] != EMPTY) {
return false;
}
// 判断是否为自杀
board[x][y] = current_player;
bool has_liberty = false;
if (x > 0 && board[x-1][y] != EMPTY) {
has_liberty = true;
}
if (y > 0 && board[x][y-1] != EMPTY) {
has_liberty = true;
}
if (x < BOARD_SIZE-1 && board[x+1][y] != EMPTY) {
has_liberty = true;
}
if (y < BOARD_SIZE-1 && board[x][y+1] != EMPTY) {
has_liberty = true;
}
if (!has_liberty) {
board[x][y] = EMPTY;
return false;
}
// 判断是否为禁手
if (x > 1 && board[x-1][y] == current_player && board[x-2][y] == current_player) {
board[x][y] = EMPTY;
return false;
}
if (y > 1 && board[x][y-1] == current_player && board[x][y-2] == current_player) {
board[x][y] = EMPTY;
return false;
}
if (x < BOARD_SIZE-2 && board[x+1][y] == current_player && board[x+2][y] == current_player) {
board[x][y] = EMPTY;
return false;
}
if (y < BOARD_SIZE-2 && board[x][y+1] == current_player && board[x][y+2] == current_player) {
board[x][y] = EMPTY;
return false;
}
// 判断是否吃子
if (x > 0 && board[x-1][y] == 3-current_player) {
bool has_liberty = false;
if (x > 1 && board[x-2][y] != EMPTY) {
has_liberty = true;
}
if (y > 0 && board[x-1][y-1] != EMPTY) {
has_liberty = true;
}
if (y < BOARD_SIZE-1 && board[x-1][y+1] != EMPTY) {
has_liberty = true;
}
if (!has_liberty) {
board[x][y] = EMPTY;
board[x-1][y] = EMPTY;
return true;
}
}
if (y > 0 && board[x][y-1] == 3-current_player) {
bool has_liberty = false;
if (x > 0 && board[x-1][y-1] != EMPTY) {
has_liberty = true;
}
if (x < BOARD_SIZE-1 && board[x+1][y-1] != EMPTY) {
has_liberty = true;
}
if (y > 1 && board[x][y-2] != EMPTY) {
has_liberty = true;
}
if (!has_liberty) {
board[x][y] = EMPTY;
board[x][y-1] = EMPTY;
return true;
}
}
if (x < BOARD_SIZE-1 && board[x+1][y] == 3-current_player) {
bool has_liberty = false;
if (x < BOARD_SIZE-2 && board[x+2][y] != EMPTY) {
has_liberty = true;
}
if (y > 0 && board[x+1][y-1] != EMPTY) {
has_liberty = true;
}
if (y < BOARD_SIZE-1 && board[x+1][y+1] != EMPTY) {
has_liberty = true;
}
if (!has_liberty) {
board[x][y] = EMPTY;
board[x+1][y] = EMPTY;
return true;
}
}
if (y < BOARD_SIZE-1 && board[x][y+1] == 3-current_player) {
bool has_liberty = false;
if (x > 0 && board[x-1][y+1] != EMPTY) {
has_liberty = true;
}
if (x < BOARD_SIZE-1 && board[x+1][y+1] != EMPTY) {
has_liberty = true;
}
if (y < BOARD_SIZE-2 && board[x][y+2] != EMPTY) {
has_liberty = true;
}
if (!has_liberty) {
board[x][y] = EMPTY;
board[x][y+1] = EMPTY;
return true;
}
}
board[x][y] = EMPTY;
return true;
}
int count_liberties(int x, int y) {
if (board[x][y] == EMPTY) {
return 0;
}
int liberties = 0;
if (x > 0 && board[x-1][y] == EMPTY) {
liberties++;
}
if (y > 0 && board[x][y-1] == EMPTY) {
liberties++;
}
if (x < BOARD_SIZE-1 && board[x+1][y] == EMPTY) {
liberties++;
}
if (y < BOARD_SIZE-1 && board[x][y+1] == EMPTY) {
liberties++;
}
return liberties;
}
bool has_liberties(int x, int y) {
if (x > 0 && board[x-1][y] == EMPTY) {
return true;
}
if (y > 0 && board[x][y-1] == EMPTY) {
return true;
}
if (x < BOARD_SIZE-1 && board[x+1][y] == EMPTY) {
return true;
}
if (y < BOARD_SIZE-1 && board[x][y+1] == EMPTY) {
return true;
}
return false;
}
void remove_group(int x, int y) {
board[x][y] = EMPTY;
if (x > 0 && board[x-1][y] == current_player) {
remove_group(x-1, y);
}
if (y > 0 && board[x][y-1] == current_player) {
remove_group(x, y-1);
}
if (x < BOARD_SIZE-1 && board[x+1][y] == current_player) {
remove_group(x+1, y);
}
if (y < BOARD_SIZE-1 && board[x][y+1] == current_player) {
remove_group(x, y+1);
}
}
void remove_captured_stones(int x, int y) {
if (x > 0 && board[x-1][y] == 3-current_player && !has_liberties(x-1, y)) {
remove_group(x-1, y);
}
if (y > 0 && board[x][y-1] == 3-current_player && !has_liberties(x, y-1)) {
remove_group(x, y-1);
}
if (x < BOARD_SIZE-1 && board[x+1][y] == 3-current_player && !has_liberties(x+1, y)) {
remove_group(x+1, y);
}
if (y < BOARD_SIZE-1 && board[x][y+1] == 3-current_player && !has_liberties(x, y+1)) {
remove_group(x, y+1);
}
}
void play_move(int x, int y) {
board[x][y] = current_player;
remove_captured_stones(x, y);
current_player = 3 - current_player;
}
void print_board() {
printf(" ");
for (int i = 0; i < BOARD_SIZE; i++) {
printf("%c ", 'A'+i);
}
printf("\n");
for (int y = 0; y < BOARD_SIZE; y++) {
printf("%d ", y+1);
for (int x = 0; x < BOARD_SIZE; x++) {
if (board[x][y] == EMPTY) {
printf(". ");
} else if (board[x][y] == BLACK) {
printf("X ");
} else {
printf("O ");
}
}
printf("%d\n", y+1);
}
printf(" ");
for (int i = 0; i < BOARD_SIZE; i++) {
printf("%c ", 'A'+i);
}
printf("\n");
}
int main() {
for (int x = 0; x < BOARD_SIZE; x++) {
for (int y = 0; y < BOARD_SIZE; y++) {
board[x][y] = EMPTY;
}
}
print_board();
while (true) {
int x, y;
printf("%c's turn:\n", current_player == BLACK ? 'X' : 'O');
scanf("%c%d", &x, &y);
getchar(); // 吃掉回车符
x -= 'A';
y--;
if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE) {
printf("Invalid move!\n");
continue;
}
if (!is_legal_move(x, y)) {
printf("Illegal move!\n");
continue;
}
play_move(x, y);
print_board();
}
return 0;
}
```
这个程序使用了一个二维数组来表示棋盘,其中0表示空,1表示黑子,2表示白子。程序使用了一个while循环,一直等待用户输入,然后调用is_legal_move函数来判断是否为合法的落子。该函数会检查:是否为自杀、是否为禁手、是否吃子。如果是合法的落子,程序会调用play_move函数来更新棋盘,然后打印出新的棋盘状态。
需要注意的是,目前这个程序只支持命令行输入,用户需要输入类似A1这样的坐标来落子。如果想要添加GUI,需要使用相应的图形库来实现。
阅读全文