codeblocks的C语言围棋双人对战程序包含吃子,计算外气,禁手规则,自动点目以及自动提子的代码
时间: 2023-06-24 11:06:25 浏览: 137
围棋C语言程序的设计.docx
5星 · 资源好评率100%
以下是一个简单的围棋双人对战程序,包含吃子、计算外气、禁手规则、自动点目以及自动提子的代码。这个程序使用Code::Blocks和C语言编写。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 15
#define COL 15
#define BLACK 'B'
#define WHITE 'W'
#define EMPTY '+'
#define PLAYER1 1
#define PLAYER2 2
char board[ROW][COL]; // 存放棋盘的数组
int player = PLAYER1; // 当前玩家
int black_score = 0; // 黑方得分
int white_score = 0; // 白方得分
// 初始化棋盘
void init_board() {
int i, j;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
board[i][j] = EMPTY;
}
}
}
// 显示棋盘
void print_board() {
int i, j;
printf(" ");
for (i = 0; i < COL; i++) {
printf("%c ", 'A' + i);
}
printf("\n");
for (i = 0; i < ROW; i++) {
printf("%2d", i + 1);
for (j = 0; j < COL; j++) {
printf("%c ", board[i][j]);
}
printf("%2d", i + 1);
if (i == 4) {
printf(" 黑方得分:%d", black_score);
} else if (i == 9) {
printf(" 白方得分:%d", white_score);
}
printf("\n");
}
printf(" ");
for (i = 0; i < COL; i++) {
printf("%c ", 'A' + i);
}
printf("\n");
}
// 判断落子是否合法
int is_valid_move(int row, int col) {
if (row < 0 || row >= ROW || col < 0 || col >= COL) {
return 0;
}
if (board[row][col] != EMPTY) {
return 0;
}
if (row > 0 && board[row - 1][col] == EMPTY) {
return 0;
}
if (row < ROW - 1 && board[row + 1][col] == EMPTY) {
return 0;
}
if (col > 0 && board[row][col - 1] == EMPTY) {
return 0;
}
if (col < COL - 1 && board[row][col + 1] == EMPTY) {
return 0;
}
return 1;
}
// 判断一个棋子所处的气数
int count_liberties(int row, int col) {
int liberties = 0;
if (row > 0 && board[row - 1][col] == EMPTY) {
liberties++;
}
if (row < ROW - 1 && board[row + 1][col] == EMPTY) {
liberties++;
}
if (col > 0 && board[row][col - 1] == EMPTY) {
liberties++;
}
if (col < COL - 1 && board[row][col + 1] == EMPTY) {
liberties++;
}
return liberties;
}
// 删除一个棋子所属的连
void remove_group(int row, int col) {
board[row][col] = EMPTY;
if (row > 0 && board[row - 1][col] == BLACK) {
remove_group(row - 1, col);
}
if (row < ROW - 1 && board[row + 1][col] == BLACK) {
remove_group(row + 1, col);
}
if (col > 0 && board[row][col - 1] == BLACK) {
remove_group(row, col - 1);
}
if (col < COL - 1 && board[row][col + 1] == BLACK) {
remove_group(row, col + 1);
}
if (row > 0 && board[row - 1][col] == WHITE) {
remove_group(row - 1, col);
}
if (row < ROW - 1 && board[row + 1][col] == WHITE) {
remove_group(row + 1, col);
}
if (col > 0 && board[row][col - 1] == WHITE) {
remove_group(row, col - 1);
}
if (col < COL - 1 && board[row][col + 1] == WHITE) {
remove_group(row, col + 1);
}
}
// 落子
void make_move(int row, int col) {
int i, j, k;
int liberties = 0;
char opponent;
if (player == PLAYER1) {
board[row][col] = BLACK;
opponent = WHITE;
} else {
board[row][col] = WHITE;
opponent = BLACK;
}
if (row > 0 && board[row - 1][col] == opponent && count_liberties(row - 1, col) == 0) {
remove_group(row - 1, col);
}
if (row < ROW - 1 && board[row + 1][col] == opponent && count_liberties(row + 1, col) == 0) {
remove_group(row + 1, col);
}
if (col > 0 && board[row][col - 1] == opponent && count_liberties(row, col - 1) == 0) {
remove_group(row, col - 1);
}
if (col < COL - 1 && board[row][col + 1] == opponent && count_liberties(row, col + 1) == 0) {
remove_group(row, col + 1);
}
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (board[i][j] == opponent && count_liberties(i, j) == 0) {
remove_group(i, j);
}
}
}
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (board[i][j] == EMPTY) {
int flag = 0;
for (k = 0; k < ROW; k++) {
if (board[k][j] == BLACK) {
flag |= 1;
} else if (board[k][j] == WHITE) {
flag |= 2;
}
if (board[i][k] == BLACK) {
flag |= 4;
} else if (board[i][k] == WHITE) {
flag |= 8;
}
}
if ((flag == 1 || flag == 8) && player == PLAYER1) {
board[i][j] = 'X';
} else if ((flag == 2 || flag == 4) && player == PLAYER2) {
board[i][j] = 'X';
}
}
}
}
}
// 判断是否有禁手
int is_ko_rule(int row, int col) {
char temp_board[ROW][COL];
int i, j;
memcpy(temp_board, board, ROW * COL);
make_move(row, col);
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (board[i][j] != EMPTY && board[i][j] != 'X') {
if (memcmp(temp_board, board, ROW * COL) == 0) {
return 1;
}
}
}
}
memcpy(board, temp_board, ROW * COL);
return 0;
}
// 判断是否有禁手
int is_ko(int row, int col) {
int temp_player = player;
int ko_rule = is_ko_rule(row, col);
player = temp_player;
return ko_rule;
}
// 计算得分
void calculate_score() {
int i, j;
black_score = 0;
white_score = 0;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (board[i][j] == BLACK) {
black_score++;
} else if (board[i][j] == WHITE) {
white_score++;
}
}
}
}
// 主函数
int main() {
int row, col;
init_board();
while (1) {
system("clear");
print_board();
printf("玩家 %d 落子:", player);
scanf("%d %d", &row, &col);
row--;
col--;
if (!is_valid_move(row, col)) {
printf("这个位置不能落子!\n");
continue;
}
if (is_ko(row, col)) {
printf("禁手!\n");
continue;
}
make_move(row, col);
calculate_score();
if (player == PLAYER1) {
player = PLAYER2;
} else {
player = PLAYER1;
}
if (black_score >= 180 || white_score >= 180) {
break;
}
}
system("clear");
printf("游戏结束!\n");
if (black_score > white_score) {
printf("黑方胜利!\n");
} else if (white_score > black_score) {
printf("白方胜利!\n");
} else {
printf("平局!\n");
}
print_board();
return 0;
}
```
这个程序使用了一个二维数组来存放棋盘,每个位置上可以是黑子、白子或空位。在落子时,程序会自动计算所落子所属的连是否被吃掉,以及其它连是否被吃掉。程序还会自动计算棋盘上每个空位的气数以及是否有禁手。最后,程序会计算双方得分并输出胜负结果。
阅读全文