三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】

这篇具有很好参考价值的文章主要介绍了三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


㊙️小明博客主页:➡️ 敲键盘的小明 ㊙️
✅关注小明了解更多知识☝️



前言

提示:本篇文章为C语言版的三子棋小游戏的制作,内含超详细讲解和完整源码,以及视频演示,内容如若有误,请联系小明及时更正。

  • 转载请注明原创,谢谢。

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

提示:以下是本篇文章正文内容:

一、三子棋的实现思路

   三子棋游戏,也称为井字游戏,是一种两人对战的棋类游戏。
  玩家轮流在棋盘上划线,目标是在斜方向上连成三个自己的棋子,从而获胜。
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频


实现的思路:
  在开始编写代码之前,我们需要先规划好游戏整体的思路和实现步骤。这样做可以避免我们在编程过程中走弯路,减少出现错误和问题的概率,所以,让我们先来想一想大致的实现思路:

1️⃣ 游戏菜单
  既然是下三子棋,我们在游戏菜单选择开始游戏后,肯定要先打印棋盘。
2️⃣ 打印棋盘
  棋盘打印之后我们开始下棋,但是下棋又分为玩家(我们)下棋和电脑下棋两个棋手。
3️⃣ 玩家下棋
  我们玩家下棋自然是输入我们想下位置的坐标即可落子。
4️⃣电脑下棋
  电脑下棋我们先弄成随机下棋的形式。
5️⃣ 判断胜负
  我们下棋判断胜负自然是每落子一次就得判断一次输赢,若有结果则停止下棋,然后显示输赢情况。
6️⃣ 是否继续
  我们在下完一局的时候可以再提示一下,是否继续游戏,可以重复玩。
7️⃣ 优化
  电脑随机下棋难免有些死板,我们可以试着优化电脑下棋的思路来优化我们的游戏体验。

超前点播:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
想知道这样的三子棋是怎么做出来的嘛,往下看吧


二、三子棋的实现步骤

2.1 先显示游戏的菜单

  按我们刚才的第一点,先准备一个游戏的菜单让我们选择是否开始游戏:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void menu() 
{
	printf("***********************\n");
	printf("******  1.play  *******\n");
	printf("******  0.exit  *******\n");
	printf("***********************\n");
}

int main()
{
	int input = 0;
	menu();
	printf("请选择:");
	scanf("%d", &input);
	
	return 0;
}

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

  当然了,游戏玩完了一局后想要继续玩,我们就可以用循环来实现多次游戏,但是该用哪种循环呢?
说到该用哪种循环,我们就该想哪种更适合:

1. for循环在循环开始之前就已经知道循环的次数。

2. while循环在循环开始之前不知道循环的次数,它会在每次循环结束时检查循环条件。

3. do-while循环和while循环类似,但有一个主要区别:do-while循环会先执行一次循环体,然后再检查循环条件。

  因为我们不知道需要玩几局,我们可能想玩十几局,也可能赢几局后就不玩了,所以for循环肯定不合适,而游戏一开始就需要我们就需要先选择一下菜单,然后进行游戏,按这个逻辑来讲,do-while循环是更为合适的
  所以,让我们在原基础上在加一个do-while循环:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void menu() 
{
	printf("***********************\n");
	printf("******  1.play  *******\n");
	printf("******  0.exit  *******\n");
	printf("***********************\n");
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
	} while(input);

	return 0;
}

添加do-while循环后的菜单效果:

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

用do…while循环后呢,我们的菜单上面说的选择1 玩游戏,0 退出,但是我们上面显示输入2、3等数字也可以进入菜单。我们就需要用选择结构中的switch语句来处理多余数字的输入:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void menu()
{
	printf("***********************\n");
	printf("******  1.play  *******\n");
	printf("******  0.exit  *******\n");
	printf("***********************\n");
}

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

	return 0;
}

添加选择后的效果:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

最后,我们将 case 1 选项改为一个game()函数来进入游戏即可完成初步框架的制作。

2.2 游戏的具体实现

2.2.1 棋盘的初始化

  有了初步的框架,我们就可以开始对棋盘进行初始化,三子棋的棋盘是一个 3×3 (即三行三列)的二维数组。
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
我们写一个循环打印一下:

void InitBoard(char board[3][3], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			board[i][j] = '6';
		}
	}
}

void DisplayBoard(char board[3][3], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			printf(" %c ", board[i][j]);
		}
		printf("\n");
	}
}

void game()
{
	//创建棋盘
	char board[3][3] = { 0 };
	//初始化棋盘
	InitBoard(board, 3, 3);
	//打印棋盘
	DisplayBoard(board, 3, 3);
}

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
  我们可以看到三行三列的棋盘已经做好了,但这里的行和列已经被我们写死了!如果后期如果想整改变行和列,需要修改的地方就太多了!所以我们可以写一个 game.c 的文件来存放 实现游戏的相关代码,再写一个 game.h 的文件来存放 游戏所有头文件和函数的声明,用 #define 定义的自符常量来解决这个问题,效果如图:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

  然后将实现棋盘打印的代码移动到 game.c 中,在此需要注意的是:一般引用库里面的头文件我们用< > 如:#include<stdio.h>,而引用自己的头文件时用" "引用我们自己的头文件。
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

2.2.2 展示棋盘

  做完刚才的文件后,我们就该对棋盘进行展示了,我们刚才创建的棋盘只有九宫格的样式,并没有 “ 井 ” 字的棋盘,所以我们需要制作 “ 井 ” 字的线条:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
  要实现这个 “ 井 ” 字的线条,就不能像刚才一样直接打印内容,需要打印行和列的线条,我们可以分成这么几个部分实现:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
如上所示,我们可以分开打印:

 | |   第一行
—|—|—  第二行
 | |   第三行
—|—|—  第四行
 | |   第五行

在此基础上可以两行为一组打印:
 | |   
—|—|—  前两组为第一行

 | |   
—|—|—  中间两组为第二行

 | |   最后一排为第三行

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		//先打印数据
		printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);

		//再打印分隔行
		printf("---|---|---\n");
	}
}

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
  如上图所示,我们成功的实现了棋盘的打印,但是最后多了一行 “ - - - | - - - | - - - ”,我们可以用 if 语句来判断行数,如果是最后一行则不打印 “ - - - | - - - | - - - ”

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

2.2.3 下棋

有了棋盘,我们就可以进行棋盘落子的操作了

🔴玩家下棋

首先,在 game.h 头文件中声明玩家下棋函数:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
  然后在 game.c 文件中实现玩家下棋的代码,我们的玩家不一定都是程序员,所以对于落子坐标来讲,肯定不会按二维数组下标来下棋,所以我们需要将玩家输入的横坐标 x x x 和纵坐标 y y y 减一:

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

	printf("请输入下棋坐标:");
	scanf("%d %d", &x, &y);
	if (x <= row && x >= 1 && y <= col && y >= 1)
	{
		board[x - 1][y - 1] = 'o';
	}
}

  此处所下的棋子不能超出棋盘,否则坐标非法重新下;并且下的棋子必须在空格子中,否则坐标备占有重新下,然后在加一个 while 循环可以实现玩家下错棋子之后,还能重新下,直到下正确退出循环:

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 <= row && x >= 1 && y <= col && y >= 1)
		{
			if (board[x - 1][y - 1] == ' ')//为空可以落子
			{   //[x-1][y-1]可以让输入的数字变为数组下标
				board[x - 1][y - 1] = 'o';
				break;
			}
			else
			{
				printf("该坐标已占用,请重新输入\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

  当我们在 game.c 中的写完玩家下棋的代码后,需要在 test.c 文件中的game()函数里调用一下:

void game()
{
	//创建棋盘
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//打印棋盘
	}
}

效果如下面的动图:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
至此,玩家下棋的代码已基本完成。


🔴电脑下棋

  有了玩家下棋的基础,电脑下棋的大致框架也同玩家下棋的代码一致,我们先在 game.h 头文件中写一个电脑玩家下棋:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
  玩家下棋时需要修改落子的横纵坐标来符合二维数组,但电脑下棋则不需要修改,我们让电脑随机生成下标即可:

//电脑随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;

	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = 'x';
			break;
		}
	}
}

上面代码因为row和col的值为3,所以 x = rand() % row;和 y = rand() % col;的值一定会在 0~2 之间。

rand()会返回一个范围在 0 到RAND_MAX(32767) 之间的伪随机数(整数)。
srand种子可使用传入时间戳的方式来确定入口。如:

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

我们可以把个代码写在main()函数里
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

效果显示:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

至此,玩家下棋的代码已基本完成。


2.2.4 判断棋盘是否满了

  在写完双方的落子的代码后,我们可以浅试一手:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

  虽然我们还没写判断输赢的代码,但是已经有 Bug 出现了:在棋盘满了之后代码死循环了······
  兵来将挡,水来土掩。有了问题咱们就解决问题,我们写一个函数来判断棋盘是否有空位置:

//判断棋盘是否满了
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;//有位置返回 0
			}
		}
	}
	return 1;//棋盘满了返回 1
}

有空位置返回 0,无空位置返回 1。当棋盘满时没有输赢时则判平局

2.2.5 判断输赢的状态

  既然有了平局的出现,我们也就该写输赢判断的代码了,棋盘满了还没有三子连成一条线时为平局 ,但是如果在棋盘满之前有三子成线则是某一方赢了。
  写一个 IsWin() 函数来判断输赢,在写之前我们可以想一下,如何来判断输赢,都会有哪些情况:
  1. 玩家赢
  2. 电脑赢
  3. 平局
  4. 游戏继续

所以先将 test.c 中的 game() 函数添加判断平局的代码:

void game()
{
	char ret = 0;
	//创建棋盘
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//打印棋盘

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'j')
		{
			break;
		}
	
		ComputerMove(board, ROW, COL);//电脑下棋
		DisplayBoard(board, ROW, COL);//打印棋盘

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'j')
		{
			break;
		}
	}
}

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

  平局的代码写完了,就该写判断玩家赢,还是电脑赢的代码了。

void game()
{
	char ret = 0;
	//创建棋盘
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//打印棋盘

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'j')
		{
			break;
		}
	
		ComputerMove(board, ROW, COL);//电脑下棋
		DisplayBoard(board, ROW, COL);//打印棋盘

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'j')
		{
			break;
		}
	}

	if (ret == 'o') //玩家棋子为 o
	{
		printf("玩家赢\n");
	}
	else if (ret == 'x') //电脑棋子为 x
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
}

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

至此,game()函数中的判断输赢代码已经写完,我们该在 game.c 文件中实现判断输赢的代码了:

首先还是老样子,现在game.h 的头文件里先声明一下:

char IsWin(char board[ROW][COL], int row, int col);

头文件中的效果为:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

🔴行判断

  i 从 0 开始,到 < row(小于3,即0~2下标)时结束,如果三行中的三个元素都一样,则连成一条线,返回三个元素中的一个即可,并且三元素相同时不是三个空值的相等:

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][0] != ' ')
		{
			return board[i][0]; //三个都相等的话,然后其中一个即可
		}
	}
}

🔴列判断

  列的判断和行的判断一样,只不过将数组访问下标的行和列互换:

//列判断
for (i = 0; i < col; i++)
{
	if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
	{
		return board[1][i];
	}
}

🔴对角线判断

  左对角线和右对角线的判断:
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

//对角线判断
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];
}

🔴棋盘满了,但没有人赢,输出平局

//没有人赢,输出平局
if (IsFull(board, row, col) == 1)
{
	return 'p';
}

至此,判断输赢的 IsWin() 函数就写完了:

//玩家赢-----w
//电脑赢-----d
//平局-------p    满了返回1,不满返回0
//游戏继续---j
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][0] != ' ')
		{
			return board[i][0]; //三个都相等的话,然后其中一个即可
		}
	}
	//列判断
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][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];
	}

	//没有人赢,输出平局
	if (IsFull(board, row, col) == 1)
	{
		return 'p';
	}

	//游戏继续
	return 'j';
}

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频


三、游戏的优化

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频
  这是我们制作的三子棋游戏,但是由于电脑落子是随机的,这就导致电脑有时回下一些没用的位置,让我们的游戏体验大幅度下降,那么我们该如何优化呢?

3.1 优化电脑下棋判断

3.1.1 判断连续情况的函数

  如果是两个真人下棋,会是怎样的场景?肯定是看到有两个棋子成一条线时就要去 堵住第三个位置防止落子!
  所以我们需要写一个寻找是否有连续情况的函数 find() 来判断是否有两个棋子连在一起, 并且第三子的位置是空的

//判断连续情况
int find(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][2] == ' ' && board[i][0] != ' ')
		{
			board[i][2] = 'x';
			return 1;
		}
		if (board[i][0] == board[i][2] && board[i][1] == ' ' && board[i][0] != ' ')
		{
			board[i][1] = 'x';
			return 1;
		}
		if (board[i][1] == board[i][2] && board[i][0] == ' ' && board[i][1] != ' ')
		{
			board[i][0] = 'x';
			return 1;
		}
	}
	//列判断
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[2][i] == ' ' && board[0][i] != ' ')
		{
			board[2][i] = 'x';
			return 1;
		}
		if (board[0][i] == board[2][i] && board[1][i] == ' ' && board[0][i] != ' ')
		{
			board[1][i] = 'x';
			return 1;
		}
		if (board[1][i] == board[2][i] && board[0][i] == ' ' && board[1][i] != ' ')
		{
			board[0][i] = 'x';
			return 1;
		}
	}
	//对角线判断
	if (board[1][1] == board[0][0] && board[2][2] == ' ' && board[1][1] != ' ')
	{
		board[2][2] = 'x';
		return 1;
	}
	if (board[0][0] == board[2][2] && board[1][1] == ' ' && board[0][0] != ' ')
	{
		board[1][1] = 'x';
		return 1;
	}
	if (board[1][1] == board[2][2] && board[0][0] == ' ' && board[1][1] != ' ')
	{
		board[0][0] = 'x';
		return 1;
	}
	//斜对角线判断
	if (board[0][2] == board[1][1] && board[2][0] == ' ' && board[0][2] != ' ')
	{
		board[2][0] = 'x';
		return 1;
	}
	if (board[1][1] == board[2][0] && board[0][2] == ' ' && board[1][1] != ' ')
	{
		board[0][2] = 'x';
		return 1;
	}
	if (board[0][2] == board[2][0] && board[1][1] == ' ' && board[0][2] != ' ')
	{
		board[1][1] = 'x';
		return 1;
	}
	return 0;
}

3.1.2 电脑下棋的优化

  我们优化完拦截玩家下棋的代码后,还需要在电脑下棋的代码里优化一个重要的步骤:那就是 抢占中心点!!!中心点是一个极有利的位置,在玩家下完棋后如果中心点还是空的,则可以让电脑抢占一下中心点,提高胜率。

//电脑随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;

	//判断中间,抢中心点
	if (board[1][1] == ' ')
	{
		board[1][1] = 'x';
	}
	else if (find(board, row, col)) //判断是否复合拦截条件,复合进行拦截。
	{
		;
	}
	else
	{
		while (1)
		{
			x = rand() % row;
			y = rand() % col;
			if (board[x][y] == ' ')
			{
				board[x][y] = 'x';
				break;
			}
		}
	}
}

下棋优化后的效果:

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

  做到这里已经将整个三子棋游戏优化的非常智能了,但是对于追求完美的我们来讲显示效果还差那么一丢丢。

3.2 优化屏幕显示效果

3.2.1 延迟打印优化

  现如今可以看到的是,电脑下棋很快,没有那种对弈时思考的感觉,这时我们可以写一个延迟打印的函数:delay() ,用

//延迟打印
void delay(int milliseconds)
{
	int i, j;
	for (i = 0; i < milliseconds; i++)
	{
		for (j = 0; j < 10000; j++)
		{
			// 空循环,用于消耗一定的时间
		}
	}
}

  这个函数接受一个整数参数milliseconds,表示延迟的毫秒数。函数内部有两个嵌套的for循环,通过循环来消耗时间,从而实现延迟打印的效果。
  然后我们将这个函数写在电脑下棋后棋盘打印之前:

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

还可以写在判断输赢之前,显得机器在判断双方输赢时也在思考

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

我们加了延迟打印后的效果为:

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

3.2.2 清屏优化显示

  由上面的效果可以看出,我们的效果已然极佳。但但但是!我们可以明显的看到所有棋盘都堆积到了一起,显得很乱很杂,我们可以在打印完一个棋盘后清理一次屏幕,使得屏幕看起来更舒适。

C语言中,system函数可以用于调用一些DOS命令,比如system(“pause”)可以卡主系统控制台,而另一个常用的system(“cls”)为清屏命令,等于在DOS上使用cls命令。

而我们这里用到的就是清屏代码: system(“cls”) ;

首先我们在我们下棋之后加上清屏代码清除掉游戏菜单,使得屏幕上只有棋盘,然后在电脑下棋后再加一段清屏代码,省的玩家下棋后的棋盘和电脑下棋后的棋盘重叠:

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

优化前

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频

优化后

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频


四、最终效果演示

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频


五、源码


已经看到这里的朋友点个关注来波三连支持一下小明好嘛 QAQ

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

#define ROW 3 //用define定义的二维数组大小
#define COL 3 //在此处可以更方便的修改棋盘的大小

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

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

//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);

//判断输赢
char IsWin(char board[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char board[3][3], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

//void DisplayBoard(char board[3][3], int r, int c)
//{
//	for (int i = 0; i < r; i++)
//	{
//		for (int j = 0; j < c; j++)
//		{
//			printf(" %c ", board[i][j]);
//		}
//		printf("\n");
//	}
//}

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		//先打印数据
		printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);

		//再打印分隔行
		if (i < row - 1)
		{
			printf("---|---|---\n");
		}
	}
}

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 <= row && x >= 1 && y <= col && y >= 1)
		{
			if (board[x - 1][y - 1] == ' ')//为空可以落子
			{   //[x-1][y-1]可以让输入的数字变为数组下标
				board[x - 1][y - 1] = 'o';
				break;
			}
			else
			{
				printf("该坐标已占用,请重新输入\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

//判断连续情况
int find(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][2] == ' ' && board[i][0] != ' ')
		{
			board[i][2] = 'x';
			return 1;
		}
		if (board[i][0] == board[i][2] && board[i][1] == ' ' && board[i][0] != ' ')
		{
			board[i][1] = 'x';
			return 1;
		}
		if (board[i][1] == board[i][2] && board[i][0] == ' ' && board[i][1] != ' ')
		{
			board[i][0] = 'x';
			return 1;
		}
	}
	//列判断
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[2][i] == ' ' && board[0][i] != ' ')
		{
			board[2][i] = 'x';
			return 1;
		}
		if (board[0][i] == board[2][i] && board[1][i] == ' ' && board[0][i] != ' ')
		{
			board[1][i] = 'x';
			return 1;
		}
		if (board[1][i] == board[2][i] && board[0][i] == ' ' && board[1][i] != ' ')
		{
			board[0][i] = 'x';
			return 1;
		}
	}
	//对角线判断
	if (board[1][1] == board[0][0] && board[2][2] == ' ' && board[1][1] != ' ')
	{
		board[2][2] = 'x';
		return 1;
	}
	if (board[0][0] == board[2][2] && board[1][1] == ' ' && board[0][0] != ' ')
	{
		board[1][1] = 'x';
		return 1;
	}
	if (board[1][1] == board[2][2] && board[0][0] == ' ' && board[1][1] != ' ')
	{
		board[0][0] = 'x';
		return 1;
	}
	//斜对角线判断
	if (board[0][2] == board[1][1] && board[2][0] == ' ' && board[0][2] != ' ')
	{
		board[2][0] = 'x';
		return 1;
	}
	if (board[1][1] == board[2][0] && board[0][2] == ' ' && board[1][1] != ' ')
	{
		board[0][2] = 'x';
		return 1;
	}
	if (board[0][2] == board[2][0] && board[1][1] == ' ' && board[0][2] != ' ')
	{
		board[1][1] = 'x';
		return 1;
	}
	return 0;
}

//电脑随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;

	//判断中间,抢中心点
	if (board[1][1] == ' ')
	{
		board[1][1] = 'x';
	}
	else if (find(board, row, col)) //判断是否复合拦截条件,复合进行拦截。
	{
		;
	}
	else
	{
		while (1)
		{
			x = rand() % row;
			y = rand() % col;
			if (board[x][y] == ' ')
			{
				board[x][y] = 'x';
				break;
			}
		}
	}
}

//判断棋盘是否满了
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;//有位置返回 0
			}
		}
	}
	return 1;//棋盘满了返回 1
}

//玩家赢-----w
//电脑赢-----d
//平局-------p    满了返回1,不满返回0
//游戏继续---j
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][0] != ' ')
		{
			return board[i][0]; //三个都相等的话,然后其中一个即可
		}
	}
	//列判断
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][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];
	}

	//没有人赢,输出平局
	if (IsFull(board, row, col) == 1)
	{
		return 'p';
	}

	//游戏继续
	return 'j';
}

//延迟打印
void delay(int milliseconds)
{
	int i, j;
	for (i = 0; i < milliseconds; i++)
	{
		for (j = 0; j < 10000; j++)
		{
			// 空循环,用于消耗一定的时间
		}
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.c"
void menu()
{
	printf("***********************\n");
	printf("******  1.play  *******\n");
	printf("******  0.exit  *******\n");
	printf("***********************\n");
}

void game()
{
	char ret = 0;
	//创建棋盘
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		system("cls");//清屏
		DisplayBoard(board, ROW, COL);//打印棋盘

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'j')
		{
			break;
		}
	
		ComputerMove(board, ROW, COL);//电脑下棋
		delay(300000);
		system("cls");//清屏
		DisplayBoard(board, ROW, COL);//打印棋盘

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'j')
		{
			break;
		}
	}

	if (ret == 'o') //玩家棋子为 o
	{
		delay(300000);
		printf("玩家赢\n");
	}
	else if (ret == 'x') //电脑棋子为 x
	{
		delay(300000);
		printf("电脑赢\n");
	}
	else
	{
		delay(300000);
		printf("平局\n");
	}
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			system("cls");//清屏
			game();
			delay(500000);
			system("cls");//清屏
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("输入错误,请重新输入!!!\n");
			break;
		}
	} while (input);

	return 0;
}

完结

好啦,阅读到这里就已经看完了本期博客的全部内容了
三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】,C语言入门到进阶,游戏,c语言,音视频文章来源地址https://www.toymoban.com/news/detail-851434.html

到了这里,关于三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言图形界面开发(演示视频、完整代码文件)

    C语言初学者开始都是在黑白控制台上开发一些小程序,实现一些小功能,因为基础的C语言可视化效果比较差,所展示的都是黑白的字符和数字,比较单调乏味。一些大学的计算机类专业学生,大一学习C语言,学习基础语法和算法,通过平台刷题提高自己编程能力,一般不专

    2024年02月04日
    浏览(46)
  • 玩转Android10源码开发定制(二)之基于Pixel 3手机超级详细演示recovery刷机

    本节主要内容: Pixel 3通过fastboot方式刷入Android 11.0官方工厂镜像 Pixel 3通过recovery方式刷入LineageOs 18.1 Android主要刷机方式: 线刷 fastboot刷机,比如pixel 3手机刷工厂镜像的时候用的就是fastboot刷机方式。 卡刷 通过recovery刷机。比如要刷入LineageOs官方的刷机包,需要刷入twrp等recove

    2024年02月09日
    浏览(35)
  • C语言——三子棋游戏

    更多C语言实战项目,欢迎浏览C语言——扫雷游戏 控制台实现 游戏提供一个菜单界面,可以根据用户输入来决定“开始游戏”或者“退出游戏” 通过字符‘|’和‘-’来组成一个可视化棋盘 选择开始游戏后,玩家优先落子,落子位置用字符‘X’表示,之后是电脑随机落子,

    2024年02月07日
    浏览(43)
  • C语言之三子棋游戏

    #define _CRT_SECURE_NO_WARNINGS 1 //测试三子棋 #include\\\"game.h\\\" void menu() {          printf(\\\"**********************************n\\\");     printf(\\\"*****  1.play    0.exit       ****n\\\");     printf(\\\"**********************************n\\\"); } void game()//游戏算法实现 {     char ret = 0;     //数组-存放走出的棋盘信息

    2024年01月21日
    浏览(40)
  • C语言之三子棋游戏(棋盘)

    #define _CRT_SECURE_NO_WARNINGS 1 //测试三子棋 #include\\\"game.h\\\" void menu() {          printf(\\\"**********************************n\\\");     printf(\\\"*****  1.play    0.exit       ****n\\\");     printf(\\\"**********************************n\\\"); } void game()//游戏实现 {     //数组-存放走出的棋盘信息     char board[ROW][C

    2024年01月19日
    浏览(86)
  • 【C语言】三子棋游戏——超细教学

    🚩 纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:C语言 🔥该篇将结合之前的知识来实现 三子棋游戏。 通过迭代保证每次玩完游戏后可以再来一局或者退出。 博主将会对上图每一个板块进行函数实现。 选择是否玩游戏 该板块的循环部分将会使用do while

    2024年02月11日
    浏览(43)
  • C语言三子棋小游戏

    哈喽,大家好,今天我们要利用之前所学习的C语言知识来写一个三子棋小游戏。 目录 1.游戏 2.函数部分 2.1.菜单 2.2.初始化棋盘 2.3.打印棋盘 2.4.玩家下棋 2.5.电脑下棋 2.6.判断输赢 2.7.判断棋盘是否已满 3.完整代码展示 今天我们写的代码分为三个文件来写,分别是: game.h 用来

    2024年02月04日
    浏览(41)
  • C语言:三子棋小游戏

    目标很简单:实现一个 三子棋小游戏。三子棋大家都玩过,规则就不提及了。本博文中实现的三子棋在对局中,电脑落子是随机的,不具有智能性,玩家的落子位置使用键盘输入坐标。下面开始详细介绍如何实现一个简单的三子棋游戏。 想要实现一个小游戏,第一件事就是

    2024年02月09日
    浏览(56)
  • 三子棋小游戏---(C语言)

    目录 前言: 1.菜单的打印 2.三子棋构思 3.实现三子棋 3.1使用宏的方式定义数组 3.2打印棋盘 3.3玩家下棋 3.4电脑随机下棋 3.5判断结局 4.源码 4.1test.c 4.2game.c  4.3game.h  ❤博主CSDN:啊苏要学习   ▶专栏分类:C语言◀   C语言的学习,是为我们今后学习其它语言打好基础,C生万物

    2024年02月03日
    浏览(80)
  • C语言之三子棋游戏实现篇

    目录 主函数test.c 菜单函数 选择实现 游戏函数 (函数调用) 打印棋盘数据 打印展示棋盘  玩家下棋 电脑下棋 判断输赢  循环 test.c总代码  头文件函数声明game.h 头文件的包含 游戏符号声明 游戏函数声明 game.h总代码  游戏函数game.c  打印棋盘数据InitBoard 打印展示棋盘Dis

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包