C语言实现五子棋游戏
五子棋是一种简单但富有策略性的棋类游戏,两个玩家在一个棋盘上交替下棋,每次下一个棋子,目的是在水平、垂直或对角线上形成五颗连续的棋子。这个项目的目标是使用C语言来实现一个简单的五子棋游戏,包括棋盘的显示、玩家输入、胜利条件判断以及游戏循环控制。
项目介绍
1. 项目背景
五子棋游戏源于中国,已经有几百年的历史。它的玩法简单,但极具挑战性。该游戏的规则如下:
- 游戏使用的是一个15x15的棋盘。
- 两个玩家轮流在棋盘上放置棋子(黑棋和白棋)。
- 玩家通过横向、纵向或对角线上的连续五颗棋子来获胜。
本项目旨在用C语言编写一个简单的控制台五子棋游戏,包括棋盘的显示、玩家输入棋子、判断胜负、清空棋盘等功能。
2. 项目目标
本项目将包括以下几个功能:
- 显示15x15的棋盘。
- 支持玩家输入棋子的坐标,并在棋盘上标记。
- 判断胜负:当某个玩家在任意一条方向上形成五子连线时,判定为胜利。
- 支持游戏重启功能。
3. 开发工具与环境
本项目使用C语言开发,编译器为GCC(或任何兼容的C语言编译器)。操作系统不限,但建议在Linux或Windows环境下进行开发。
4. 功能概述
- 棋盘显示:实时显示棋盘状态,空白位置用‘+’表示,黑棋用‘X’,白棋用‘O’表示。
- 玩家输入:两名玩家交替输入行列号来放置自己的棋子。
- 胜负判断:每次玩家放置棋子后,检查当前棋盘,判断是否有一方玩家的五颗棋子连成一线。
- 游戏结束:当有玩家胜利或棋盘填满时,游戏结束。
实现思路
1. 数据结构设计
五子棋的棋盘可以使用二维数组来表示。由于棋盘是15x15的,所以我们需要一个15行15列的数组来存储棋盘的状态。
- 棋盘结构: 用二维数组
board[15][15]
来表示棋盘。 - 棋盘符号:
0
表示空位置。1
表示黑棋。2
表示白棋。
2. 游戏循环
游戏会按照以下流程进行:
- 初始化棋盘并显示。
- 轮流让两名玩家输入位置。
- 每次玩家输入后,检查当前棋盘,判断是否有玩家胜利。
- 如果胜利,宣布结果并结束游戏。如果没有胜利,继续下一轮。
3. 功能实现
- 棋盘初始化和显示:用一个函数初始化棋盘,并定期显示棋盘的当前状态。
- 玩家输入:获取玩家输入的行列位置,判断位置是否有效(即是否为空)。
- 胜利判断:每次玩家下棋后,检查其放置的棋子是否成线(横、纵、斜)。
- 游戏重启功能:游戏结束后,可以选择是否重新开始。
实现代码
以下是完整的五子棋游戏代码:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15 // 棋盘的大小
#define EMPTY 0 // 空位置
#define BLACK 1 // 黑棋
#define WHITE 2 // 白棋
// 声明函数
void initBoard(int board[SIZE][SIZE]);
void printBoard(int board[SIZE][SIZE]);
int isValidMove(int board[SIZE][SIZE], int row, int col);
int checkWin(int board[SIZE][SIZE], int player);
int checkDirection(int board[SIZE][SIZE], int row, int col, int dRow, int dCol, int player);
void playGame();
int main() {
playGame();
return 0;
}
// 初始化棋盘
void initBoard(int board[SIZE][SIZE]) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
board[i][j] = EMPTY;
}
}
}
// 打印棋盘
void printBoard(int board[SIZE][SIZE]) {
printf(" ");
for (int i = 0; i < SIZE; i++) {
printf("%2d ", i + 1);
}
printf("\n");
for (int i = 0; i < SIZE; i++) {
printf("%2d ", i + 1);
for (int j = 0; j < SIZE; j++) {
if (board[i][j] == EMPTY) {
printf(" + ");
} else if (board[i][j] == BLACK) {
printf(" X ");
} else {
printf(" O ");
}
}
printf("\n");
}
}
// 判断是否是有效的棋步
int isValidMove(int board[SIZE][SIZE], int row, int col) {
if (row < 0 || row >= SIZE || col < 0 || col >= SIZE || board[row][col] != EMPTY) {
return 0; // 无效的棋步
}
return 1;
}
// 检查是否有玩家胜利
int checkWin(int board[SIZE][SIZE], int player) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (board[i][j] == player) {
if (checkDirection(board, i, j, 1, 0, player) || // 横向
checkDirection(board, i, j, 0, 1, player) || // 纵向
checkDirection(board, i, j, 1, 1, player) || // 斜向 /
checkDirection(board, i, j, 1, -1, player)) { // 斜向 \
return 1; // 玩家胜利
}
}
}
}
return 0;
}
// 检查某个方向是否有五子连成一线
int checkDirection(int board[SIZE][SIZE], int row, int col, int dRow, int dCol, int player) {
int count = 0;
for (int i = 0; i < 5; i++) {
int newRow = row + i * dRow;
int newCol = col + i * dCol;
if (newRow >= 0 && newRow < SIZE && newCol >= 0 && newCol < SIZE && board[newRow][newCol] == player) {
count++;
} else {
break;
}
}
return count == 5;
}
// 游戏主循环
void playGame() {
int board[SIZE][SIZE];
int currentPlayer = BLACK; // 从黑棋开始
int row, col;
int gameOver = 0;
initBoard(board);
while (!gameOver) {
printBoard(board);
printf("玩家 %d 轮到你下棋,请输入行和列 (1-%d): ", (currentPlayer == BLACK) ? 1 : 2, SIZE);
scanf("%d %d", &row, &col);
row--; col--; // 转换为数组索引
if (isValidMove(board, row, col)) {
board[row][col] = currentPlayer;
if (checkWin(board, currentPlayer)) {
printBoard(board);
printf("玩家 %d 获胜!\n", (currentPlayer == BLACK) ? 1 : 2);
gameOver = 1;
} else {
currentPlayer = (currentPlayer == BLACK) ? WHITE : BLACK; // 换玩家
}
} else {
printf("无效的棋步,请重新输入。\n");
}
}
}
代码解读
1. initBoard()
函数
该函数负责初始化棋盘,设置所有位置为空(0
)。我们使用一个15x15的二维数组来表示棋盘,空位置用0
表示。
2. printBoard()
函数
用于打印当前的棋盘状态。根据棋盘的值,打印+
表示空位,X
表示黑棋,O
表示白棋。通过行列号打印每行的坐标,方便玩家查看。
3. isValidMove()
函数
检查玩家输入的棋步是否合法。首先检查坐标是否在棋盘范围内,其次确保该位置为空。若合法返回1,否则返回0。
4. checkWin()
函数
每次玩家落子后,调用该函数检查是否有玩家胜利。遍历棋盘,针对每个棋子检查其周围的四个方向(横、纵、斜)。如果某个方向连续五颗棋子是同一方玩家的棋子,则判定为胜利。
5. checkDirection()
函数
辅助函数,检查某个方向(横、纵或斜)上是否存在五颗相同棋子。如果存在五颗连续的棋子,返回1,表示胜利条件成立。
6. playGame()
函数
游戏的主控制函数。初始化棋盘后,进入一个循环,轮流让玩家输入棋步。如果某玩家胜利或棋盘满了,则游戏结束。
项目总结
本项目成功实现了一个简单的五子棋游戏。通过使用二维数组来表示棋盘,并通过函数模块化的设计,使得代码结构清晰且易于扩展。在实现过程中,主要完成了棋盘的显示、玩家输入的验证、胜负判断和游戏流程的控制等核心功能。
项目收获:
- 学会了如何使用二维数组表示棋盘。
- 熟悉了函数的模块化设计,增强了代码的可维护性。
- 提升了C语言编程能力,尤其是在条件判断和循环控制方面。
扩展思路:
- 可以添加悔棋功能,让玩家可以撤回上一步棋。
- 可以使用图形化界面(如SDL)来增加用户体验。
- 可以设计AI对战模式,允许玩家与计算机对战。
通过这个项目,我们能够更好地理解如何在C语言中处理二维数据,如何设计游戏逻辑,并通过实际应用增强自己的编程能力。
这个项目涉及的功能较为简单,但可以通过不断扩展和优化,逐渐形成一个完整且富有挑战的五子棋游戏系统。