Game(三子棋 & 扫雷)

发布时间:2023-08-09 10:30

只要你愿意 开始总比放弃好。 Roman.

愿我们都有自己的目标并正在为其不懈努力。

---------------------------------------------------------------------------------------

一、三子棋

一)分析与准备

1、

test.c  //测试三子棋游戏逻辑

game.c   //游戏的实现

game.h   //函数的声明(需要 分号;) 以及符号的定义

(因为 #include 在三个文件中均使用,所以直接包含在头文件中引用头文件即可)

2、游戏part

游戏布局:

菜单 选择(至少进行一次循环)

设计游戏:

存放下棋的数据:字符的二维数组(为了便于改变值,在头文件中进行定义行和列)

棋盘:初始化棋盘为全空格

打印棋盘:数据 分割行

玩家下棋:PlayerMove( )

输入坐标 --》 判断坐标是否合法(循环) --》 判断是否被占用 --》 下棋

打印棋盘DisplayBoard( )

判断输赢:Iswin( )

  •  用返回值来判断输赢--玩家赢*  电脑赢#  平局Q  继续C
  •  赢 or 平局IsFull( ):平局只存在于 game.c 中,其他函数不可使用,则 static修饰

电脑下棋:ComputerMove( )   //随机下棋

随机值rand( )的获取需要srand((unsigned int)time(NuLL))放在test.c 文件中,注意随机值得范围,需要头文件 stdlib.h  time.h

打印棋盘

判断输赢

(注:玩家与电脑下棋是循环的,直到一方获胜 or 出现平局才结束)

最后打印一遍棋盘(可有可无)

3、一些命名习惯

初始化:InitBoard( )

打印:DisplayBoard( )

行:int row

列:int col

二)代码实现

1、test.c 文件

#include\"game.h\"

//菜单
void menu()
{
	printf(\"*****************************************************\\n\");
	printf(\"*********     Welcome to my game word!     **********\\n\");
	printf(\"*********            1. play               **********\\n\");
	printf(\"*********            0. exit               **********\\n\");
	printf(\"*****************************************************\\n\");
}

int main()
{

	//创建数组
	char chess[Row][Col] = { 0 };

	int row = 3;
	int col = 3;//注意是在main函数中定义

	int choi = 0;
	do
	{
        srand((unsigned int)time(NULL));//每次一更新
		//菜单
		menu();
		printf(\"请输入您的选择:\\n\");
		scanf(\"%d\", &choi);
		//判断输入
		switch (choi)
		{
		case 1:
			printf(\"Game Start!\\n\");
			//游戏
			game();
			break;
		case 0:
			printf(\"退出游戏!\\n\");
			break;
		default:
			printf(\"非法输入 请重新输入!\\n\");
			break;
		}
	} while (choi);
	return 0;
}

2、game.c 文件

#include\"game.h\"

//初始化棋盘:数据全为0
void InitBoard(char chess[Row][Col], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			chess[i][j] = \' \';
		}
	}
}

//打印棋盘
void DisplayBoard(char chess[Row][Col], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		//打印数据
		for (j = 0; j < col; j++)
		{
			if (j < col - 1)
			{
				printf(\" %c |\", chess[i][j]);
			}
			else
			{
				printf(\" %c \", chess[i][j]);
			}
		}
		printf(\"\\n\");
		//打印分割行
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf(\"___\");
				if (j < col - 1)
				{
					printf(\"|\");
				}
			}
			printf(\"\\n\");
		}
		else
		{
			for (j = 0; j < col; j++)
			{
				printf(\"   \");
				if (j < col - 1)
				{
					printf(\"|\");
				}
			}
			printf(\"\\n\");
		}
	}
}

//判断是否赢
char IsWin(char chess[Row][Col], int x, int y, int row, int col)
{
	//赢
	//行相同
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//if (chess[i][0] == chess[i][1] == chess[i][2] == \'*\')//写法不对!!

		if((chess[i][0]==chess[i][1])&&(chess[i][1]==chess[i][2])&&(chess[i][0]==\'*\'))
		{
			return \'*\';
		}
		else if ((chess[i][0] == chess[i][1]) && (chess[i][1] == chess[i][2]) && (chess[i][0] == \'#\'))
		{
			return \'#\';
		}
	}
	//列相同
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if ((chess[0][j] == chess[1][j]) && (chess[1][j] == chess[2][j]) && (chess[0][j] == \'*\'))
		{
			return \'*\';
		}
		else if ((chess[0][j] == chess[1][j]) && (chess[1][j] == chess[2][j]) && (chess[0][j] == \'#\'))
		{
			return \'#\';
		}
	}
	//对角线相同
	if ((chess[0][0] == chess[1][1])&&(chess[1][1] == chess[2][2])&&(chess[0][0] == \'*\'))
	{
		return \'*\';
	}
	else if ((chess[0][0] == chess[1][1]) && (chess[1][1] == chess[2][2]) && (chess[0][0] == \'#\'))
	{
		return \'#\';
	}
	if ((chess[0][2] == chess[1][1]) && (chess[1][1] == chess[2][0]) && (chess[0][2] == \'*\'))
	{
		return \'*\';
	}
	else if((chess[0][2] == chess[1][1]) && (chess[1][1] == chess[2][0]) && (chess[0][2] == \'#\'))
	{
		return \'#\';
	}
	//游戏继续
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (chess[i][j] == \' \')
			{
				return \'C\';
			}
		}
	}
}

//玩家动
char PlayerMove(char chess[Row][Col], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf(\"玩家动(请输入坐标):\\n\");
		scanf(\"%d %d\", &x, &y);
		if (chess[x-1][y-1] == \' \')
		{
			chess[x-1][y-1] = \'*\';//玩家下棋子*
		}
		else if ((x > row) || (y > col))
		{
			printf(\"该处已超出范围,请重新输入!\\n\");
			continue;
		}
		else
		{
			printf(\"该处已被占用,请重新输入!\\n\");
			continue;
		}

		//打印棋盘
		DisplayBoard(chess, Row, Col);

		//判断输赢
		char iw = IsWin(chess, x, y, row, col);
		return iw;
	}
}

电脑动
char ComputerMove(char chess[Row][Col], int row, int col)
{
	printf(\"电脑下棋:\\n\");
	while (1)
	{
		//生成随机数
		int x = rand() % row;
		int y = rand() % col;
		if (chess[x][y] == \' \')
		{
			chess[x][y] = \'#\';//电脑下棋\'#\'
		}
		else
		{
			continue;
		}
		//打印棋盘
		DisplayBoard(chess, Row, Col);

		//判断输赢
		char iw = IsWin(chess, x, y, row, col);
		return iw;
	}
	
	
}

//游戏
void game()
{
	//创建数组
	char chess[Row][Col] = { 0 };

	//初始化棋盘:数据全为0
	InitBoard(chess, Row, Col);

	//打印棋盘
	DisplayBoard(chess, Row, Col);

	while (1)
	{
		//玩家动
		char iw1 = PlayerMove(chess, Row, Col);
		打印棋盘
		//DisplayBoard(chess, Row, Col);

		if (iw1 == \'*\')
		{
			printf(\"玩家赢\\n\");
			Sleep(1000);
			printf(\"\\n是否想再来一局?\\n\");
			break;
		}
		else if (iw1 == \'#\')
		{
			printf(\"电脑赢\\n\");
			Sleep(1000);
			printf(\"\\n是否想再来一局?\\n\");
			break;
		}
		else if (iw1 == \'C\')
		{
			;//游戏继续
		}
		else
		{
			printf(\"平局\\n\");
			Sleep(1000);
			printf(\"\\n是否想再来一局?\\n\");
			break;
		}

		//电脑动
		char iw2 = ComputerMove(chess, Row, Col);
		打印棋盘
		//DisplayBoard(chess, Row, Col);

		if (iw2 == \'*\')
		{
			printf(\"玩家赢\\n\");
			Sleep(1000);
			printf(\"\\n是否想再来一局?\\n\");
			break;
		}
		else if (iw2 == \'#\')
		{
			printf(\"电脑赢\\n\");
			Sleep(1000);
			printf(\"\\n是否想再来一局?\\n\");
			break;
		}
		else if (iw2 == \'C\')
		{
			;//游戏继续
		}
		else
		{
			printf(\"平局\\n\");
			Sleep(1000);
			printf(\"\\n是否想再来一局?\\n\");
			break;
		}
	}
}

3、game.h 文件

#pragma once

#include
#include
#include
#include

#define Row 3
#define Col 3

//int row = 3;
//int col = 3;

//游戏
void game();

//初始化棋盘:数据全为0
void InitBoard(char chess[Row][Col], int row, int col);

//打印棋盘
void DisplayBoard(char chess[Row][Col], int row, int col);

//玩家动
char PlayerMove(char chess[Row][Col], int row, int col);

//判断是否赢
char IsWin(char chess[Row][Col], int x, int y, int row, int col);

//电脑动
char ComputerMove(char chess[Row][Col], int row, int col);

******************************************************************************

二、扫雷

一)分析与准备

 1、

test.c  //测试三子棋游戏逻辑

game.c   //游戏的实现

game.h   //函数的声明(需要 分号;) 以及符号的定义

(因为 #include 在三个文件中均使用,所以直接包含在头文件中引用头文件即可)

 2、游戏part

菜单   判断(循环)游戏

游戏的实现:

布置雷:二维数组

布置雷的信息:另外一个新的数组mine(多行和列:1表示雷  0表示无雷)

排查出雷的信息的数组show(同样多行多列   *表示未排查  数字是周围含有多少雷地数目)

//定义行列

//定义数组

//初始化两个数组:多设置一个初始化内容的参数set

//打印棋盘show_board( );

//布置雷:set_mine( );

雷的个数定义在头文件中,然后将其赋值给count;坐标取随机值,并且循环雷,直到count==0

//打印show棋盘(保持神秘性)

//排查雷:find_mine( );

扫雷:

输入坐标:判断是否合法(循环)

 是雷,炸死,游戏结束,打印mine;  不是雷,告知其周围八个坐标上有多少个雷get_mine( ) 函数:数字字符 - 数字0字符 == 对应数字, 打印show

直到把所有雷的位置找到,则游戏结束,扫雷成功;

排雷数 == 方格数 - 雷数EASY_COUNT

 3、扩展功能

1)标记:标记雷

2)消失一片:递归实现:选中的不是雷且周围没有雷,该坐标没有被排查过,则继续递归,直到出现周围有雷则进行雷个数的标记

注意:递归不能出现死递归,即:不能递归已经出现过的,对已经出现过的进行标记

二)代码实现

 1、test.c文件

//简单扫雷 9行9列
//10个雷

#include\"game.h\"

//菜单
void menu()
{
	printf(\"*******************************************************\\n\");
	printf(\"*************     Welcome To My Game!     *************\\n\");
	printf(\"*************           1.Play            *************\\n\");
	printf(\"*************           0.Exit            *************\\n\");
	printf(\"*******************************************************\\n\");
}

void game()
{
	//设置数组
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	初始化数组
	//init_mine(mine, ROWS, COLS);
	//init_show(show, ROW, COL);

	//初始化数组 优化
	Init(mine, ROWS, COLS, \'0\');
	Init(show, ROWS, COLS, \'*\');

	//打印show
	Print(show, ROW, COL);

	//布置雷
	set_mine(mine, ROW, COL);

	检查设置雷
	//Print(mine, ROWS, COLS);


	int sum = ROW * COL;

	//循环
	while (sum > EASY_COUNT)
	{

		//扫雷
		int num = find_mine(mine, show, ROW, COL);

		//判断是否为雷
		if (9 == num)
		{
			//此处应该打印雷的布局:以show数组进行打印
			Print(show, ROW, COL);
			printf(\"很抱歉 您被炸死了!\\n\");
			break;
		}
		else
		{
			//非雷
			sum--;

			//此处应该打印雷的布局:以show数组进行打印
			Print(show, ROW, COL);
		}
	}
	if (sum == EASY_COUNT)
	{
		printf(\"恭喜你 游戏胜利!\\n\");
	}
}

int main()
{

	//
	int row = 9;
	int col = 9;
	int rows = 11;
	int cols = 11;

	do
	{
		//随机数准备
		srand((unsigned int)time(NULL));

		//菜单
		menu();

		//选择
		int choi = 0;
		printf(\"请输入您的选择:\\n\");
		scanf(\"%d\", &choi);
		switch (choi)
		{
		case 1:
			printf(\"Game Start!\\n\");
			game();
			Sleep(1000);
			printf(\"是否想再来一局?\\n\");
			printf(\"\\n\");
			break;
		case 0:
			printf(\"Game Over!\\n\");
			break;
		default:
			printf(\"非法输入 请重新输入!\\n\");
			printf(\"\\n\");
			break;

		}

	}while(1);

	return 0;
}

 2、game.c文件

#include\"game.h\"
//
初始化两数组
//void init_mine(char mine[ROWS][COLS],int rows,int cols)
//{
//	int i = 0;
//	for (i = 0; i < rows; i++)
//	{
//		int j = 0;
//		for (j = 0; j < cols; j++)
//		{
//			mine[i][j] = \'0\';//初始化无雷0
//		}
//	}
//}
//
//void init_show(char show[ROW][ COL], int row, int col)
//{
//	//保持神秘感*
//	int i = 0;
//	for (i = 0; i < row; i++)
//	{
//		int j = 0;
//		for (j = 0; j < col; j++)
//		{
//			show[i][j] = \'*\';//初始化*
//		}
//	}
//}

//初始化两数组  优化
void Init(char arr[ROWS][COLS],int rows,int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;//初始化无雷0
		}
	}
}

打印函数
//void Print(char arr[ROW][COL], int x, int y)
//{
//	int i = 0;
//	int j = 0;
//
//	//
//	for (i = 0; i <= x; i++)
//	{
//		for (j = 0; j <= y; j++)
//		{
//			if (0 == i)
//			{
//				printf(\"%d \", j);
//			}
//			else
//			{
//				if (j < y)
//				{
//					printf(\"%c \", arr[i - 1][j]);
//				}
//			}
//		}
//		printf(\"\\n\");
//		if (i < x)
//		{
//			printf(\"%d \", i + 1);
//		}
//	}
//}

//打印函数 更新
void Print(char arr[ROWS][COLS], int x, int y)
{
	int i = 0;
	for (i = 0; i <= y ; i++)
	{
		printf(\"%d \", i);
	}
	printf(\"\\n\");

	//注意 1 1 是 mine 的起始0位置
	for (i = 1; i <= x; i++)  //注意是 1-x
	{
		printf(\"%d \", i );
		int j = 0;
		for (j = 1; j <= y; j++)  //注意是1-y
		{
			printf(\"%c \", arr[i][j]);  
			//打印的是9*9数组:1-9才是实际要打印的(其实就是1-row 1-col)
		}
		printf(\"\\n\");
	}
}

//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		//生成随机数
		//int x = rand() % 9 + 1;//1-9下标
		//int y = rand() % 9 + 1;

		//优化随机数:要在1-row 1-col内布置雷
		int x = rand() % row + 1;  //注意下标:1-row
		int y = rand() % col + 1;

		if (mine[x+1][y+1] == \'0\')//注意下标要加1  画图可以看
		{
			mine[x+1][y+1] = \'1\';
			//EASY_COUNT--; //左值为变量
			count--;
		}
	}
}


//扫雷
int find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	printf(\"请输入你想看的位置:\\n\");
	scanf(\"%d %d\", &x, &y);

	//判断mine的雷数目
	if ((x >= 1) && (x <= row) && (y >= 1) && (y <= col))
	{
		if (\'1\' == mine[x][y])
		{
			show[x][y] = \'1\';
			return 9;//因为周围雷的数目不可能出现9
		}
		else
		{

			//找周围雷的个数
			char num = \'0\';
			int i = 0;
			for (i = (x - 1); i <= (x + 1); i++)
			{
				int j = 0;
				for (j = (y - 1); j <= (y + 1); j++)
				{
					num += mine[i][j];
				}
			}
			//此处应该
			show[x][y] = num - 9 * \'0\';
			return (num - 10 * \'0\');

			更新:另一种
			//char num = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
			//	mine[x][y - 1] + mine[x][y + 1] +
			//	mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1];
			//show[x][y] = num- 7 * \'0\'; //注意:此处要减去(相加个数-1)*‘0’  因为重复加了‘0’
			//return (num - \'0\' * 8);
			
		}
	}
	else
	{
		printf(\"非法输入 请重新输入\\n\");
	}
}

 3、game.h文件

#pragma once


#include
#include
#include
#include

#define EASY_COUNT 10
#define ROW 9
#define COL 9
//#define ROWS 11
//#define COLS 11

//优化
#define ROWS (ROW +2)
#define COLS (COL +2)


//初始化两数组  优化
void Init(char arr[ROWS][COLS], int rows, int cols, char set);

//打印函数
void Print(char arr[ROW][COL], int x, int y);


//布置雷
//void set_mine(char mine[ROWS][COLS], int rows, int cols);
void set_mine(char mine[ROWS][COLS], int row, int col);   //修改

//扫雷
int find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

*******************************注:该为一个简单代码 无扩展内容

—————————一个人所有的愤怒都来自于对自己无能的痛苦。———————————

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号