C语言实现三子棋


前言

本篇博客主要介绍如何使用C语言实现三子棋游戏。


一、游戏规则

玩家在一张9*9的棋盘上与电脑下棋,玩家使用“X”作为棋子,电脑使用“O”作为棋子。其中一方3个棋子连成一线则获胜;若棋盘铺满仍未有一方获胜,则视为和棋。宏定义如下:

#define ROW 3
#define COL 3

二、游戏流程

1.创建棋盘并初始化

使用字符型数组作为棋盘,初始化即将数组内所有元素设为空字符。代码如下:

void init(char chessBoard[ROW][COL]){
	for (int i = 0; i < ROW; i++){
		for (int j = 0; j < COL; j++){
			chessBoard[i][j] = ' ';
		}
	}
}

2.打印棋盘

利用循环语句,逐行打印棋盘。使用“-”和“+”模拟棋盘格的样式。代码如下:

void printChessBoard(char chessBoard[ROW][COL]){
	printf("+---+---+---+\n");
	for (int i = 0; i < ROW; i++){
			printf("| %c | %c | %c |\n", chessBoard[i][0], chessBoard[i][1], chessBoard[i][2]);
			printf("+---+---+---+\n");
	}
}

3.玩家落子

使用scanf语句读取玩家输入的坐标,若坐标越界或坐标上不为空,则提示重新输入;否则将字符“X”赋给数组的这个元素,完成一次落子。代码如下:

void playerMove(char chessBoard[ROW][COL]){
	int row = 0;
	int col = 0;
	while (1){
		printf("请输入落子坐标(row col)# ");
		scanf("%d %d", &row, &col);
		if ((row < 0 || row >= ROW) || (col < 0 || col >= COL)){
			printf("输入有误!\n");
			continue;
		}
		else if (chessBoard[row][col] != ' '){
			printf("此坐标已经有子了!\n");
			continue;
		}
		chessBoard[row][col] = 'X';
		break;
	}
}

4. 判定胜负关系

检查是否有某一行、某一列或者某一条对角线上存在三个相同棋子,若有,则函数返回这种棋子,用字符“X”或“O”表示。若没有,则检查棋盘是否满了(即数组中不再有空字符),若满了,则返回字符“D”,表示和棋。若没有满,则输出空字符,表示游戏继续。代码如下:

char checkState(char chessBoard[ROW][COL]){
	for (int row = 0; row < ROW; row++) {
		if (chessBoard[row][0] != ' '
			&& chessBoard[row][0] == chessBoard[row][1]
			&& chessBoard[row][0] == chessBoard[row][2]) {
			return chessBoard[row][0];
		}
	}
	for (int col = 0; col < COL; col++) {
		if (chessBoard[0][col] != ' '
			&& chessBoard[0][col] == chessBoard[1][col]
			&& chessBoard[0][col] == chessBoard[2][col]) {
			return chessBoard[0][col];
		}
	}
	if (chessBoard[0][0] != ' '
		&& chessBoard[0][0] == chessBoard[1][1]
		&& chessBoard[0][0] == chessBoard[2][2]) {
		return chessBoard[0][0];
	}
	if (chessBoard[0][2] != ' '
		&& chessBoard[0][2] == chessBoard[1][1]
		&& chessBoard[0][2] == chessBoard[2][0]) {
		return chessBoard[0][2];
	}
	if (isFull(chessBoard)){
		return 'D';
	}
	return ' ';
}
int isFull(char chessBoard[ROW][COL]){
	for (int row = 0; row < ROW; row++) {
		for (int col = 0; col < COL; col++) {
			if (chessBoard[row][col] == ' ') {
				return 0;
			}
		}
	}
	return 1;
}

5. 电脑落子(随机位置落子)

使用rand()函数产生随机数,通过对棋盘行数和列数取余,得到合法坐标值。若此坐标已经落子,则跳过,重新产生随机数;否则在此位置落子。代码如下:

void comMove(char chessBoard[ROW][COL]){
	while (1){
		int row = rand() % ROW;
		int col = rand() % COL;
		if (chessBoard[row][col] != ' '){
			continue;
		}
		chessBoard[row][col] = 'O';
		break;
	}
}

6. 判定胜负关系

电脑落子后也要进行胜负关系的判断。此时若仍胜负未分,则重新从第一步开始循环。

三、game函数、menu函数和主函数

将上文的流程封装成game()函数,代码如下:

void game(){
	char chessBoard[ROW][COL] = { 0 };
	init(chessBoard);
	char state = ' ';
	printChessBoard(chessBoard);
	while (1){
		playerMove(chessBoard);
		state = checkState(chessBoard);
		if (state != ' '){
			break;
		}
		comMove(chessBoard);
		printChessBoard(chessBoard);
		state = checkState(chessBoard);
		if (state != ' '){
			break;
		}
	}
	printChessBoard(chessBoard);
	if (state == 'X'){
		printf("你赢了!\n");
	}
	if (state == 'O'){
		printf("你输了!\n");
	}
	if (state == 'D'){
		printf("和棋!\n");
	}
}

实现一个menu函数,在开始游戏前显示一个菜单,让玩家选择是否玩游戏。代码如下:

int menu(){
	printf("#######################\n");
	printf("####### 1.play ########\n");
	printf("####### 0.exit ########\n");
	printf("#######################\n");
	int option = -1;
	scanf("%d", &option);
	return option;
}

主函数中,加入随机数种子,保证每次游戏电脑落子的位置不同。由于time(0)的返回值是time_t,而srand()的参数应为无符号整形,所以此处使用强制类型转换, 把 time_t 转成 unsigned int。代码如下:

int main(){

	srand((unsigned int)time(0));
	while (1){
		int option = 0;
		option = menu();
		if (option == 1){
			game();
			break;
		}
		else if (option == 0){
			break;
		}
		else{
			printf("输入有误,请重新输入!\n");
			getchar();
			continue;
		}
	}

	system("pause");
	return 0;
}

四、总结

实现三子棋游戏的过程中,主要涉及了分支、循环语句、函数和数组的知识。将大问题分解成小问题,编写多的函数实现不同的功能,最后按照逻辑顺序调用,实现整个游戏的运行。语法上确实难度不大,重点在于理清游戏的运行过程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值