哇 C语言的三子棋实现只需要这样?(Amazing)

菜鸟第一次写博客和三子棋,如有错误的地方请大家多多建议与指导

目录

整体思路(兵分三路)

游戏菜单界面

菜单实现选择

游戏核心内容

1. 声明初始化和打印函数

2. 玩家下棋

3. 电脑下棋

4. 判断对局输赢

游戏运行实现 (打游戏咯)

                  结果示例


整体思路(兵分三路)

需三个文件来实现

                                             1. 测试游戏的逻辑     -----     test.c

   三子棋实现的模块             2. 游戏函数的声明     -----     game.h                         

                                             3. 游戏函数的实现     -----     game.c


游戏菜单界面

        众所周知,一个游戏的菜单界面必不可少,内容无非就有 玩 和 退出 ,这时候,我们可以通过自定义一个函数来实现我们的菜单。

void menu()
{
	printf("*******************************\n");
	printf("*******   1. 开始游戏   *******\n");
	printf("*******   0. 退出游戏   *******\n");
	printf("*******************************\n");
}

        我们可以通过选择数字来确认自己想玩还是不想玩,这时候就要用到 switch 语句来实现。

        但假如玩完了一个对局后还想玩怎么办,可以通过使用 do while 来实现。我们可以将输入的数字来作为循环判断的条件,只要输入的数字为非零(即我们不想退出游戏),系统就判定循环条件为真,那么while就自然判定为继续循环。

int main()
{
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始三子棋游戏\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);

}

菜单实现选择

     a. 输入1即开始游戏

     b. 0退出游戏

     c. 非零则会让你重新选择

代码执行截图:

哇 C语言的三子棋实现只需要这样?(Amazing)_第1张图片


游戏核心内容

       我们知道,三子棋棋盘本质上是一个二维数组,我们可以通过其来实现棋盘的初始化和打印,即将棋盘初始化为空格。

1. 声明初始化和打印函数

      通过char board[ ][ ] 来存储二维数组的数据, 通过全局定义ROW 和COL,提高代码的效率,后期还需多次使用行列值,或者作为修改代码的基础,如五子棋的实现。  

//符号的定义
#define ROW 3 //定义几行
#define COL 3 //定义几列

// 函数的声明

// 初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);

// 打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);

然后在game.c 文件中对函数进行实现


// 1. 初始化空格
void InitBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}
// 2. 打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			// 将  " %c |" 作为数组每一项
			printf(" %c ", board[i][j]);
			if (j < col - 1)//除去最后一列 | 的打印
				printf("|");
		}
		printf("\n");
		if (i < row - 1)//除去最后一行 ---| 的打印
		{
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)//除去最后一列 | 的打印
					printf("|");
			}
			printf("\n");
		}
	}
}

代码执行截图:

哇 C语言的三子棋实现只需要这样?(Amazing)_第2张图片


2. 玩家下棋

 接下来实现 玩家下棋

       我们首先要知道,棋盘的坐标与二维数组的坐标并不相同,我们下棋时是使用棋盘的坐标,而不是数组的坐标。即棋盘的(1,1)对应于数组的(0,0),所以我们要判断输入坐标的合法性。首先,我们要判断其输入范围,并且还要考虑到坐标被占用坐标超出输入范围这两种情况。

1. 可以通过判断棋盘是否有 "  "(空格)来输入 "  *  " 棋子。

2. 棋盘的行跟列坐标的是从 1 开始,到 定义过后的 ROW COL 结束。 即可以分析出其坐标范围为 1 —— row , 1 —— col  。

3. 可以通过对棋盘坐标进行减一的运算存储到对应的二维数组坐标。

在此之前,要对相关函数在game.h进行声明,之后开始实现。

// 玩家下棋
void PlayerMove(char board [ROW][COL],int row,int col);
// 3. 玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋:>\n");

	while (1)
	{
		printf("请输入棋子的坐标:>");
		scanf("%d %d", &x, &y);
		
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//坐标是否被占用 - 即判断输入的坐标是否是已经输入过的
			if (board[x - 1][y - 1] == ' ')// (1,1) 坐标对应的是 board[0][0]
			{
				board[x - 1][y - 1] = '*';//玩家下 * 
				break;
			}
			else
			{
				printf("坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("坐标有误,请重新输入\n");
		}
	}
}

代码执行截图:

哇 C语言的三子棋实现只需要这样?(Amazing)_第3张图片

哇 C语言的三子棋实现只需要这样?(Amazing)_第4张图片


3. 电脑下棋 

       要实现电脑下棋,可以引用 rand()随机生成函数(随机字面理解就可以下哪就下哪,不会判断对局情况,即不会阻碍你棋路,老夫目前只会创建小白痴电脑,还不会创建大神级别电脑的算法,请大家多多包涵哈),引用这个函数前还需引用 srand((unsigned int)time(NULL))对其进行初始化。两个函数实现分别需引用   

       坐标占用情况同 玩家下棋 一致

       电脑的落子也需要范围。我们不妨用 rand() 对 row 和 col 进行取余,%row、%col 生成的范围就为 0 - row、0 - col ,生成的下标不会大于其行列数本身,所以也就不需要判断其合法性。

在此之前,要对相关函数在game.h进行声明,之后开始实现。

//电脑下棋
 void ComputerMove(char board[ROW][COL], int row,int col);
//4. 电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;

		if (board[x][y] == ' ')
		{
			board[x][y] = '#';//电脑下 #
			break;
		}
	}
}

代码执行截图:哇 C语言的三子棋实现只需要这样?(Amazing)_第5张图片


4. 判断对局输赢

对局结果情况无非就三种:

  1. 玩家赢    ----    三行三列、两条对角线
  2. 电脑赢    ----    三行三列、两条对角线
  3. 平局        ----    棋盘状态满了

我们先定义一下不同的对局结果该返回什么
 1. 玩家获得胜利 - *
 2. 电脑获得胜利 - #
 3. 平局 - D

我们可以自定义一个函数确认棋盘是否满了。满了返回 0,没满返回 1

int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;//棋盘没满
			}
		}
	}
	return 1;//棋盘满了
}

在此之前,要对相关函数在game.h进行声明,之后开始实现。

//判断游戏是否有输赢
 char IsWin(char board[ROW][COL], int row,int col);
char IsWin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//判断三行
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')//除去三个空格连成一线的情况
		{
			return board[i][1];
		}
	}

	//判断三列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')//除去三个空格连成一线的情况
		{
			return board[1][i];
		}
	}

	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')//除去三个空格连成一线的情况
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//除去三个空格连成一线的情况
	{
		return board[1][1];
	}

	//判断平局 - 判断棋盘是否满了
	//如果棋盘满了返回1,不满返回0
	int ret = IsFull(board, row, col);
	if (ret == 1)
	{
		return 'D';
	}
	//继续
	return 'C';
}

 


游戏运行实现 (打游戏咯)

void game()
{
	char board[ROW][COL]; 
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	char ret = 0;//接收游戏状态
	while (1)
	{
		//a.玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);// 下棋成功后打印棋盘
		//判断玩家是否赢得游戏
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;

		//b.电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);// 下棋成功后打印棋盘
		//判断电脑是否赢得游戏
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
	{
		printf("恭喜你,打败了最强AI! (^ O ^)\n");
	}
	else if (ret == '#')
	{
		printf("不会吧,连小白痴人机也打不过? (——_——)||\n");
	}
	else
	{
		printf("高手过招,旗鼓相当\n");
	}
	DisplayBoard(board, ROW, COL);// 对局结果展示打印棋盘
}

代码执行截图:

 哇 C语言的三子棋实现只需要这样?(Amazing)_第6张图片

 哇 C语言的三子棋实现只需要这样?(Amazing)_第7张图片

 哇 C语言的三子棋实现只需要这样?(Amazing)_第8张图片


以上就是三子棋的全部内容,老夫水平限制,目前实现不了高阶的棋盘游戏,本人也是第一次写博客和实现三子棋,若有什么错误也望请大佬们多多建议与指导。

 

你可能感兴趣的:(c语言)