c语言写的超详细的简单的三子棋小游戏(步骤超详细)

  我们要写一个简单的三子棋小游戏,我使用的是vs2022编译器,我们首先要创建一个头文件和两个源文件

像这样的,测试放的是main函数,函数放的的主函数是需要的函数,头文件是函数的声明 

我会一步一步的将三子棋怎么写的代码一步一步的写下来,在最后我将整个的代码发在最后

然后我们要确定我们的写的三子棋是什么样的图形界面

我门要打印的棋盘大概是这样的,

第一步我们先写一个main()函数

int main()
{
	mune();//菜单
	int input = 0;//创建一个变量让我们可以输入
	do//先用一个do-while循环直接运行
	{
		printf("请选择是否参加:>");
		scanf("%d", &input);
		switch (input)//在do-while循环里面我们用一个switch,让我们可以选择,
		{
		case 1:
			printf("三子棋\n");//我们先在这里验证一下整个逻辑是否可以
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);//遇到如果输入的值是0,则循环不执行,直接退出,所以我们要创建一个菜单提示玩家可以选择
	return 0;
}
mune()//菜单
{
	printf("******************************\n");
	printf("******1.play    0.exit  ******\n");
	printf("******************************\n");
}

然后我们验证的的是这样的

 我们的逻辑验证成功

然后将printf(“三子棋\n”);改成game()函数来完成我们接下来的打印棋盘等函数的第一步我们要创建一个数组来储存我们要打印的字符,然后要在测试里面下一个函数

这是写在测试里面的

void game()
{
	//创建存放数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	ChuBoard(board, ROW, COL);
}

接下来是声明里面

#pragma once
#include <stdio.h>
#define ROW 3//在声明里面设立全局变量可以让我们以后改代码的时候更容易
#define COL 3


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

接着我们就要写初始化棋盘的函数部分了

#define _CRT_SECURE_NO_WARNINGS
#include "声明.h"
//初始化棋盘
void ChuBoard(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++)
		{
			board[i][j] = ' ';//将棋盘初始化
		}
	}
}

将棋盘初始化完成后我们就要开始打印棋盘了,在测试game()函数中加入一个打印棋盘的函数

void game()
{
	//创建存放数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	ChuBoard(board, ROW, COL);
	//打印棋盘
	DaBoard(board, ROW, COL);
}

接着就是对打印棋盘函数的声明

#pragma once
#include <stdio.h>
#define ROW 3//在声明里面设立全局变量可以让我们以后改代码的时候更容易
#define COL 3


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



//打印棋盘
void DaBoard(char board[ROW][COL], int row, i

接着就是函数部分的代码

//打印棋盘
//我们要打印的棋盘就在棋盘,对棋盘没有印象的可以看一下上面
void DaBoard(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++)
		{
			printf(" %c ", board[i][j]);//这里的是空格%c空格这样是因为可以让打印出来的棋盘和上面看到的一样
			if (j < col - 1)//设置一个if判断语句是因为我们只需要打印两竖线
			{
				printf("|");
			}
		}
		printf("\n");//打印一个换行符,方便我们接下来的的打印分割线
		//打印分割线
		if (i < row - 1)//因为我们只需要打印两行分隔线,所以我们要设计一个条件
		{
			int j = 0;
			for (j = 0; j < col; j++)//我们要进行一个循环来我们打印一行内的分割线
			{
				printf("---");//一行打印三次
				if (j < col - 1)
				{
					printf("|");//设置一个if判断语句是因为我们只需要打印两竖线
				}
			}
		}
		printf("\n");//打印一个换行
	}	

}

这个时候我们可以验证一下是否是我们想要的棋盘

我们运行一下结果是这样的

 证明我们的代码是没有问题的,我们就可以接着继续写下面的代码了

我们现在写玩家下棋

game()函数里面这样写

void game()
{
	//创建存放数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	ChuBoard(board, ROW, COL);
	//打印棋盘
	DaBoard(board, ROW, COL);
	//玩家下棋
	WanMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
	//打印棋盘
	DaBoard(board, ROW, COL);
}

在去声明一下

#include <stdio.h>
#define ROW 3//在声明里面设立全局变量可以让我们以后改代码的时候更容易
#define COL 3


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



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



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

接下来就是写玩家下棋的函数内容了

void WanMove(char board[ROW][COL], int row, int col)
{
	//首先先创建两个变量
	int x = 0;//x=0是因为我们要将x初始化为0
	int y = 0;
	printf("玩家请输入\n");
	while (1)//我们要使用while循环来让我们进行我们的答错可以重新下棋的机制
	{
		printf("请输入坐标\n");
		scanf("%d %d", &x, &y);
		//要考虑输入的坐标的合法性的问题
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x-1][y-1] == ' ')//当输入的坐标空间上是没有存放字符的时候玩家就可以下棋
			{
				board[x-1][y-1] = '*';//我们让玩家下棋使用*
				break;//跳出循环进行下一步
			}
			else//当我们选择的坐标被占用的时候我们要提示他重新输入
			{
				printf("该坐标被占用,请重新输入");
			}
		}
		else//判断该坐标是否合法
		{
			printf("该坐标非法,请重新输入\n");
		}
	}
}

我们验证一下,结果是这样的

 说明我们的玩家下棋是成功的

接下来就是写电脑下棋,在game()函数中是这样写的

void game()
{
	//创建存放数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	ChuBoard(board, ROW, COL);
	while (1)//我们要写一个循环然后让玩家和电脑可以循环下棋
	{
		//打印棋盘
		DaBoard(board, ROW, COL);
		//玩家下棋
		WanMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
		//打印棋盘
		DaBoard(board, ROW, COL);
		DianMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
		//打印棋盘
		DaBoard(board, ROW, COL);
	}
}
int main()
{
	srand((unsigned int)time(NULL));//生成时间的空指针
	int input = 0;//创建一个变量让我们可以输入
	do//先用一个do-while循环直接运行
	{
		mune();//菜单
		printf("请选择是否参加:>");
		scanf("%d", &input);
		switch (input)//在do-while循环里面我们用一个switch,让我们可以选择,
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);//遇到如果输入的值是0,则循环不执行,直接退出,所以我们要创建一个菜单提示玩家可以选择
	return 0;
}

声明

#pragma once
#include <stdio.h>//调用printf()函数,是scanf()函数
#define ROW 3//在声明里面设立全局变量可以让我们以后改代码的时候更容易
#define COL 3
#include <stdlib.h>//调用srand()函数
#include <time.h>//生成空指针



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



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



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



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

接下来就是写电脑下棋的函数了

//电脑下棋,我这里写的是最简单电脑下棋的函数
//有兴趣的可以使用算法来经行加强电脑赢的概率
void DianMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;//rand()函数生成是一个随机数在32767到0的一个任意整数
		y = rand() % col;//但是我们rand()%row后随机值范围就是0~2
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

测试一下,结果是这样的

我们现在开始写判断输赢函数

//输赢判断
char ShuYin(char board[ROW][COL], int row, int col)//这里不用void是因为我们要有一个字符返回值
{
	//首先我们要判断有赢有几种情况,还有平局的情况,还有继续
	//行
	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];//如果被占用就返回该行的字符
		}
	}
	//列
	int j= 0;
	for (j = 0; j < row; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')//我们判断每一列是否都被同一种字符占用了
		{
			return board[1][j];//如果被占用就返回该列的字符
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')//我们判断对角线是否都被同一种字符占用了
	{
		return board[1][1];//如果被占用就返回该列的字符
	}
	if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')//我们判断对角线是否都被同一种字符占用了
	{
		return board[1][1];//如果被占用就返回该列的字符
	}
	//平局
	if (Ping(board, row,col))//我们再进行一个平局判断函数
	{
		return 'Q';
	}
	//继续
	return 'C';
}

声明

#pragma once
#include <stdio.h>//调用printf()函数,是scanf()函数
#define ROW 3//在声明里面设立全局变量可以让我们以后改代码的时候更容易
#define COL 3
#include <stdlib.h>//调用srand()函数
#include <time.h>//生成空指针



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



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



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



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



//输赢判断
//玩家赢  - ‘*’
//电脑赢  - ‘#’
//平局    -  ‘Q’
//继续    - ‘C’
char ShuYin(char board[ROW][COL], int row, int col);

geme()函数里面的代码

void game()
{
	char ret = 0;//创建一个判断变量
	//创建存放数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	ChuBoard(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		WanMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
		ret = ShuYin(board, ROW, COL);
		if (ret != 'C')//判断棋盘的是否继续出现了任意一个赢,或者平局的情况,如果出现就跳出循环进行判断输出
		{
			break;
		}
		//打印棋盘
		DaBoard(board, ROW, COL);
		DianMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
		ret = ShuYin(board, ROW, COL);
		if (ret != 'C')//判断棋盘的是否继续出现了任意一个赢,或者平局的情况,如果出现就跳出循环进行判断输出
		{
			break;
		}
		//打印棋盘
		DaBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢了\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢了\n");
	}
	else
	{
		printf("平局\n");
	}
	DaBoard(board, ROW, COL);//判断完输赢我们再一次打印棋盘,让我们知道是怎么赢得
}

我们先就只剩下一个平局函数没有写了

平局函数

//平局判断
int Ping(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] == ' ')//我们要判断是否棋盘都被占满,如果没有占满就返回0
			{
				return 0;
			}
		}
	}
	return 1;//占满了就返回1,让输赢函数返回‘Q’
}

现在我们的程序代码全部写完了

我们运行运行看一下能不能成功

结果是这样的

 我们成功的写出来一个简单的三子棋小游戏,能坚持到现在的都是好样的

接下来我就把完整的代码发出来

这是测试源文件

#define _CRT_SECURE_NO_WARNINGS
#include "声明.h"
mune()//菜单
{
	printf("******************************\n");
	printf("******1.play    0.exit  ******\n");
	printf("******************************\n");
}
void game()
{
	char ret = 0;//创建一个判断变量
	//创建存放数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	ChuBoard(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		WanMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
		ret = ShuYin(board, ROW, COL);
		if (ret != 'C')//判断棋盘的是否继续出现了任意一个赢,或者平局的情况,如果出现就跳出循环进行判断输出
		{
			break;
		}
		//打印棋盘
		DaBoard(board, ROW, COL);
		DianMove(board, ROW, COL);//我们要在玩家下完棋后我们再一次打印一下棋盘的函数,让我们可以看到我们下的棋
		ret = ShuYin(board, ROW, COL);
		if (ret != 'C')//判断棋盘的是否继续出现了任意一个赢,或者平局的情况,如果出现就跳出循环进行判断输出
		{
			break;
		}
		//打印棋盘
		DaBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢了\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢了\n");
	}
	else
	{
		printf("平局\n");
	}
	DaBoard(board, ROW, COL);//判断完输赢我们再一次打印棋盘,让我们知道是怎么赢得
}
int main()
{
	srand((unsigned int)time(NULL));//生成时间的空指针
	int input = 0;//创建一个变量让我们可以输入
	do//先用一个do-while循环直接运行
	{
		mune();//菜单
		printf("请选择是否参加:>");
		scanf("%d", &input);
		switch (input)//在do-while循环里面我们用一个switch,让我们可以选择,
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);//遇到如果输入的值是0,则循环不执行,直接退出,所以我们要创建一个菜单提示玩家可以选择
	return 0;
}

这是函数源文件

#define _CRT_SECURE_NO_WARNINGS
#include "声明.h"
//初始化棋盘
void ChuBoard(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++)
		{
			board[i][j] = ' ';//将棋盘初始化
		}
	}
}
//打印棋盘
//我们要打印的棋盘就在棋盘,对棋盘没有印象的可以看一下上面
void DaBoard(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++)
		{
			printf(" %c ", board[i][j]);//这里的是空格%c空格这样是因为可以让打印出来的棋盘和上面看到的一样
			if (j < col - 1)//设置一个if判断语句是因为我们只需要打印两竖线
			{
				printf("|");
			}
		}
		printf("\n");//打印一个换行符,方便我们接下来的的打印分割线
		//打印分割线
		if (i < row - 1)//因为我们只需要打印两行分隔线,所以我们要设计一个条件
		{
			int j = 0;
			for (j = 0; j < col; j++)//我们要进行一个循环来我们打印一行内的分割线
			{
				printf("---");//一行打印三次
				if (j < col - 1)
				{
					printf("|");//设置一个if判断语句是因为我们只需要打印两竖线
				}
			}
		}
		printf("\n");//打印一个换行
	}	
}
//玩家下棋
void WanMove(char board[ROW][COL], int row, int col)
{
	//首先先创建两个变量
	int x = 0;//x=0是因为我们要将x初始化为0
	int y = 0;
	printf("玩家请输入\n");
	while (1)//我们要使用while循环来让我们进行我们的答错可以重新下棋的机制
	{
		printf("请输入坐标\n");
		scanf("%d %d", &x, &y);
		//要考虑输入的坐标的合法性的问题
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x-1][y-1] == ' ')//当输入的坐标空间上是没有存放字符的时候玩家就可以下棋
			{
				board[x-1][y-1] = '*';//我们让玩家下棋使用*
				break;//跳出循环进行下一步
			}
			else//当我们选择的坐标被占用的时候我们要提示他重新输入
			{
				printf("该坐标被占用,请重新输入");
			}
		}
		else//判断该坐标是否合法
		{
			printf("该坐标非法,请重新输入\n");
		}
	}
}
//电脑下棋,我这里写的是最简单电脑下棋的函数
//有兴趣的可以使用算法来经行加强电脑赢的概率
void DianMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;//rand()函数生成是一个随机数在32767到0的一个任意整数
		y = rand() % col;//但是我们rand()%row后随机值范围就是0~2
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
//平局判断
int Ping(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] == ' ')//我们要判断是否棋盘都被占满,如果没有占满就返回0
			{
				return 0;
			}
		}
	}
	return 1;//占满了就返回1,让输赢函数返回‘Q’
}
//输赢判断
char ShuYin(char board[ROW][COL], int row, int col)//这里不用void是因为我们要有一个字符返回值
{
	//首先我们要判断有赢有几种情况,还有平局的情况,还有继续
	//行
	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];//如果被占用就返回该行的字符
		}
	}
	//列
	int j= 0;
	for (j = 0; j < row; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')//我们判断每一列是否都被同一种字符占用了
		{
			return board[1][j];//如果被占用就返回该列的字符
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')//我们判断对角线是否都被同一种字符占用了
	{
		return board[1][1];//如果被占用就返回该列的字符
	}
	if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')//我们判断对角线是否都被同一种字符占用了
	{
		return board[1][1];//如果被占用就返回该列的字符
	}
	//平局
	if (Ping(board, row,col))//我们再进行一个平局判断函数
	{
		return 'Q';
	}
	//继续
	return 'C';
}

最后是声明

#pragma once
#include <stdio.h>//调用printf()函数,是scanf()函数
#define ROW 3//在声明里面设立全局变量可以让我们以后改代码的时候更容易
#define COL 3
#include <stdlib.h>//调用srand()函数
#include <time.h>//生成空指针



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



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



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



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



//输赢判断
//玩家赢  - ‘*’
//电脑赢  - ‘#’
//平局    -  ‘Q’
//继续    - ‘C’
char ShuYin(char board[ROW][COL], int row, int col);

好了这就是使用c语言写的超详细的三子棋,大家可以按照我的步骤写一下,非常简单,容易,上手,小白学习数组必备,不会的话可以多敲几遍增加自己的理解

写的不好的地方,欢迎大家给我批评,指正,可以的话给我点给赞吧,谢谢大家了

猜你喜欢

转载自blog.csdn.net/weixin_73466540/article/details/131142928