C语言实现简单三子棋小游戏

目录

游戏思路:

1. 打印菜单

2. 定义棋盘-----定义一个二维数组

3. 初始化棋盘------初始化为空格

4. 打印棋盘 -------首先需要看到棋盘叭

5. 玩家下棋

6. 电脑下棋

7. 判断游戏结束

8. 游戏总函数主体

 9. 完整代码

test.c

 game.h

game.c


首先我们看一下实现的效果:

C语言实现简单三子棋小游戏_第1张图片

首先 我们建立两个.c文件和一个.h文件

test.c --- 用于测试游戏逻辑

game.c ---用于实现游戏功能 

game.h----包含各种头文件 和 宏定义

game.h 里面我们包含所有的函数声明  头文件  利用define定义的行和列

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#define ROW 3
#define COL 3
#include
#include
#include

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

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

// 声明 玩家下棋函数

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

//声明 电脑下棋

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


//判断输赢函数 声明
char is_win(char board[ROW][COL], int row, int col);

test.c 和 game.c 只需要包含 game.h 这个头文件 就可以包含 其包含的所有东西了
 由于是 自己定义的头文件 所以用引号  “ ” 而不用 <>

#include"game.h"

游戏思路:

1. 打印菜单

/* 打印菜单函数 */
void menu()
{
	printf("*********************************\n");
	printf("******** 1.play   ***************\n");
	printf("******** 0.exit   ***************\n");
	printf("*********************************\n");
}
/* 主函数部分  */
int main()
{

	srand((unsigned)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//调用游戏函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入:");
			break;
		}

	} while (input);
	return 0;
}

为方便起见 具体游戏功能 我们都利用函数实现

2. 定义棋盘-----定义一个二维数组

棋盘的定义在 总游戏函数里里面实现

char board[ROW][COL] = { 0 };

3. 初始化棋盘------初始化为空格

//定义 初始化棋盘 函数 

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] = ' ';//把每一个坐标位置都初始化为空格
		}
	}
}

4. 打印棋盘 -------首先需要看到棋盘叭

首先我们观察一下棋盘的结构

C语言实现简单三子棋小游戏_第2张图片

C语言实现简单三子棋小游戏_第3张图片

下面是具体代码  ---- 注意细节(第几行的时候不打印什么)

//定义打印棋盘函数
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++)//内部由列控制
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)//第三列不打印竖线
				printf("|");
				
		}
		printf("\n");//打印一行换行
		//打印分割线---打印次数为行数-1
		if (i < col - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

到这里我们可以测试一下是否可以正常打印棋盘 

5. 玩家下棋

  需要注意的是:

1. 玩家输入一个坐标 x , y 首先要对x 和 y的合法性进行判断

2. 考虑到如果是小白玩家 不知道数组坐标从0开始 我们规定x和y从1开始

3. 然后判断 x y坐标处是否被占用 如果没有被占用 那么输入 ” * “ 表示玩家下棋

4. 玩家下棋应该在一个循环中 如果坐标输入不合适 应该重新输  成功下棋则跳出循环

代码:

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	//x y 要满足范围!
	while (1)
	{
		printf("玩家下棋:\n");
		printf("请输入坐标\n");
		scanf("%d%d", &x, &y);//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("该坐标已经有棋,请重新输入\n");
			}
		}
		else {
			printf("坐标非法,请重新输入\n");
		}
	}
}

6. 电脑下棋

1. 首先电脑下棋 需要让电脑随机生成一个坐标 这就用到了 随机数rand()

2. 然后判断 随机生成的坐标处是否已经有棋    有则重新生成 

//定义 电脑随机下棋
void computer_move(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;
		}
	}
	
}

7. 判断游戏结束

每一次 玩家或者电脑下完棋之后 都要进行输赢的判断

那么就会有四种情况:

1. 玩家赢   -----我们规定返回  * 

2. 电脑赢  ------我们规定返回 #

3. 平局(即 棋盘下满) ------我们规定返回 q

4. 没有结束 --------我们规定返回 c

 那么什么时候赢呢?

 当  相同棋子三个相连 那么就赢了 ! 

而这包括  一行  一列  对角线  副对角线

判断是否满盘 我们利用一个 is_full() 函数  这个函数是我们针对 is_win()函数定义的 所以

可以将其用static修饰   这样别的.c文件就无法利用该函数!(私人专属!)

char is_win(char board[ROW][COL], int row, int col)
{
	//检查行 
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//检查列
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 1][j] == board[i + 2][j] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//检查主对角线
	for (int i = 0; i <= row-2; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i][i] != ' ')
		{
			return board[i][i];
		}
	}
	//检查副对角线
	 // 从左下角开始
	for (int i = row - 1; i >= 2; i--)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//检查是否满盘
	if (is_full(board, row, col))
	{
		//如果返回真--满盘
		return 'q';
	}
	return 'c';
}

 然后我们根据is_win()函数的返回值 就可以判断是谁赢啦!

8. 游戏总函数主体

void game()
{
	char ret = 0;
	//定义棋盘
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		// 玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'c')//如果 返回值是c 说明继续 返回值不是c  说明游戏已经结束
		{
			break;
		}
		// 电脑下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断 输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
		// 判断ret是否等于c 是为了减少代码冗余 如果说已经跳出循环 那么单独判断即可
	}

	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else 
	{
		printf("平局\n");
	}
	//游戏结束之后 打印一下棋盘
	DisplayBoard(board, ROW, COL); 
}
	//什么时候游戏结束
	// 玩家赢 --返回*
	// 电脑赢--返回#
	// 平局 --棋盘满了----返回q
	//    没结束  --返回c

 9. 完整代码

test.c

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include"game.h"
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)
	{
		// 玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'c')//如果 返回值是c 说明继续 返回值不是c  说明游戏已经结束
		{
			break;
		}
		// 电脑下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断 输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
		// 判断ret是否等于c 是为了减少代码冗余 如果说已经跳出循环 那么单独判断即可
	}

	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else 
	{
		printf("平局\n");
	}
	//游戏结束之后 打印一下棋盘
	DisplayBoard(board, ROW, COL); 
}
	//什么时候游戏结束
	// 玩家赢 --返回*
	// 电脑赢--返回#
	// 平局 --棋盘满了----返回q
	//    没结束  --返回c


int main()
{

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

	} while (input);
	return 0;
}

 game.h

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#define ROW 3
#define COL 3
#include
#include
#include

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

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

// 声明 玩家下棋函数

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

//声明 电脑下棋

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


//判断输赢函数 声明
char is_win(char board[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)

#include"game.h"

//定义 初始化棋盘 函数 

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] = ' ';
		}
	}
}

//定义打印棋盘函数
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++)//内部由列控制
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)//第三列不打印竖线
				printf("|");
				
		}
		printf("\n");//打印一行换行
		//打印分割线---打印次数为行数-1
		if (i < col - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}


//定义 玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	//x y 要满足范围!
	while (1)
	{
		printf("玩家下棋:\n");
		printf("请输入坐标\n");
		scanf("%d%d", &x, &y);//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("该坐标已经有棋,请重新输入\n");
			}
		}
		else {
			printf("坐标非法,请重新输入\n");
		}
	}
}


//定义 电脑随机下棋
void computer_move(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;
		}
	}
	
}

//定义判断满盘函数
static int is_full(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;
}

//定义 判断输赢函数

char is_win(char board[ROW][COL], int row, int col)
{
	//检查行 
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//检查列
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 1][j] == board[i + 2][j] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//检查主对角线
	for (int i = 0; i <= row-2; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i][i] != ' ')
		{
			return board[i][i];
		}
	}
	//检查副对角线
	 // 从左下角开始
	for (int i = row - 1; i >= 2; i--)
	{
		for (int j = 0; j < col-2; j++)
		{
			if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//检查是否满盘
	if (is_full(board, row, col))
	{
		//如果返回真--满盘
		return 'q';
	}
	return 'c';
}

你可能感兴趣的:(C,c语言,开发语言,后端,游戏程序)