C语言小游戏-三子棋(文图并茂)

        为了学习408,重新拿起了C语言进行全盘的复习,今天做的是关于数组的三子棋小游戏。下面分享一下我做这个游戏的思考过程。

        首先我运用了模块化管理,game.h用来存放函数,game.c用来实现小游戏。

        思考三子棋的原理,无非就是一个3x3的棋盘在里面进行下棋,那么我们只需要建立一个二维数组来作为棋盘就行了,棋手进行下棋的话只需要对相应的位置进行scanf就行了,棋手下棋之后再把棋盘打印出来并且判断输赢,就完成了在三子棋棋盘上下棋的操作,只需要将所有的操作都封装到一个game函数下变可以实现游戏的进行。那么我们就有了以下的逻辑。

        1.初始化棋盘(定义数组)

        2.打印棋盘

        3.玩家(电脑)下棋

        4.打印棋盘

        5.判断输赢

        一直重复............................................

        这里为了后续的开发,把长和宽用#define进行了定义,方便后续的扩展内容,比如五子棋等。

        如此之后,基本的框架已经成型,问题已经解决了大半。那么如何让玩家开始游戏呢?我们可以写一个menu菜单,选择1进入游戏,选择2退出游戏,选择其他则无效。

void menu() {
	printf("******************************************\n");
	printf("***********  1.play  2.exit  *************\n");
	printf("******************************************\n");
}
int input = 0;
	do {
		menu();
		scanf_s("%d", &input);
		if (input == 1) {
			game();
			break;
		}
		if (input == 2) {
			printf("结束游戏\n");
			break;
		}
		else {
			printf("没有这个选项\n");
		}
	} while (1);

        游戏可以开始之后便会进行game()函数的运行,也就是上面提到的五个步骤,接下来只需要对这五个步骤构造函数并且进行代码的编写即可。

        首先便是初始化棋盘,因为是三子棋,建立一个3x3的用‘ ’进行填写的二维数组便可。

//初始化棋盘
void InitBoard(char arr[ROW][COL], int row, int col) {
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			arr[i][j] = ' ';
		}
	}
}

        其次进行打印棋盘,相邻格用---和|分开即可。

//打印棋盘
void DispalyBoard(char arr[ROW][COL], int row, int col) {
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			printf(" %c ", arr[i][j]);
			if (j < col - 1) {
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1) {
				for (int j = 0; j < col; j++) {
					printf("---");
					if (j < col - 1) {
						printf("|");
					}
				}
				printf("\n");
			}
	}
}

        接下来是最关键的几步,玩家和电脑进行下棋已经判断是否输赢。

        我们将玩家的棋子用*代表,电脑的棋子用#代表,那么只需输入二维数组对应的坐标,将字符进行替换即可。

        字符的替换会有三种情况,第一种是该位置为空,直接替换即可。第二种为该位置已经有*或者#,第三种便是超出了棋盘的范围,那么我们需要阻止棋手下棋。因为阻止之后还要让棋手继续下棋,很显然,我们应该使用一个循环语句来进行这一个步骤。

        这里大家要想到数组的定义,数组是从0开始储存内容的,玩家下棋难道还要思考这一点吗?很明显这是反人类的,那么我们应该在判断时对玩家输入的坐标x和y减掉一个1,使得下棋这一步骤适合玩家的使用,那么代码便顺理成章的就敲下来了。

//玩家行动
void userplay(char arr[ROW][COL], int row, int col) {
	int x, y;
	while (1)
	{
		scanf_s("%d %d", &x, &y);
		if (x <= ROW && y <= COL && x >= 0 && y >= 0) {
			if (arr[x - 1][y - 1] == ' ') {
				arr[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("重复\n");
				/*continue;*/
			}
		}
		else {
			printf("出界\n");
			/*continue;*/
		}
	}
}

        电脑下棋更为简单,使得电脑随机生成数进行下棋,并且进行判断是否符合规则即可。随机生成数字用到了rand、srand库函数生成随机数,这里不做详细讲解,给大家相应的文章进行学习C语言rand、srand库函数生成随机数(附时间戳)

void computerplay(char arr[ROW][COL], int row, int col) {
	int x, y;
	while (1)
	{
		x = rand() % ROW;
		y = rand() % COL;
		if (arr[x][y] == ' '){
			arr[x][y] = '#';      
			break;                
		}
	}
}

        最后一步,判断是否获胜。有一方获胜必然是要结束游戏的,不可能一直运行下去。结束游戏这一步是在哪进行break中断循环呢?很显然是整个程序那么游戏结束后我们需要终端game()函数的进行,所以判断胜利的函数应该返回一个值,在game()函数中通过这个值来判断是否要break循环。

        三子连上及为获胜,四种情况,列连上三子,行连上三子,对角连上三子,下满九格平局。那这可太简单了,只需要判断他们是否是相同的就可以了呀,相同就返回一个值告诉game()里的循环进行break,不同就返回一个值让循环继续,直到二维数组里没有空,则为平局。那么代码就出来了。

//判断棋盘是否已经满了
int IsFull(char arr[ROW][COL], int row, int col) {
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (arr[i][j] == ' ') {
				return 0;
			}
		}
	}
	return 1;
}
//判断输赢
char victory(char arr[ROW][COL], int row, int col) {
	//列判断
	int i, j;
	for (i = 0; i < ROW; i++) {
		if (arr[0][i] == arr[1][i]&& arr[2][i] == arr[1][i]&&arr[0][i]!=' ') {
			return arr[0][i];
		}
	}
	for (i = 0; i < COL; i++) {
		if (arr[i][0] == arr[i][1] && arr[i][2] == arr[i][1] && arr[i][0] != ' ') {
			return arr[i][0];
		}
	}
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ') {
		return arr[1][1];
	}
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ') {
		return arr[1][1];
	}

	if (IsFull(arr, ROW, COL)) {
			return 'F';
	}
	return 'C';
}

至此,整个游戏实现完成,进行game函数和main函数的编写

#include "game.h"


void game() {
	char board[ROW][COL];//建立棋盘
	InitBoard(board, ROW, COL);//初始化棋盘
	DispalyBoard(board, ROW, COL);//打印棋盘
	//下棋
	char flag = 'l';//判断输赢
	while (1) {
		userplay(board, ROW, COL);
		DispalyBoard(board, ROW, COL);
		flag = victory(board, ROW, COL);
		if (flag != 'C') {
			break;
		}
		computerplay(board, ROW, COL);
		DispalyBoard(board, ROW, COL);
		flag = victory(board, ROW, COL);
		if (flag != 'C') {
			break;
		}
	}
	if (flag == '*') {
		printf("userwin");
	}
	if (flag == '#') {
		printf("computerwin");
	}
	if (flag == 'F') {
		printf("平局");
	}
}

int main() {
	srand((unsigned int)time(NULL));

	int input = 0;
	do {
		menu();
		scanf_s("%d", &input);
		if (input == 1) {
			game();
			break;
		}
		if (input == 2) {
			printf("结束游戏\n");
			break;
		}
		else {
			printf("没有这个选项\n");
		}
	} while (1);

	return 0;
}

感谢大家的阅读和学习,我在之后会努力学习,争取做到学到知识就进行博客的更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值