编程学习记录——第8课【数组与设计五子棋,扫雷游戏】

编程学习记录——第8课【数组与设计五子棋,扫雷游戏】,第1张

编程学习记录——第8课【数组与设计五子棋,扫雷游戏】 数组是指一组具有相同类型的元素的集合。 一维数组

一维数组的创建及初始化 例int arr[]={1,2,3,4},表示创建了一个大小为4的数组,数组内为四个整型元素1,2,3,4。char arr[]="abcd",表示创建了一个大小为5的数组,数组的元素为'a','b','c','d','',。其中为字符串的结束标志。

int arr1 [ 10 ] = { 1 , 2 , 3 };表示创建了一个大小为10的整型数组,第一,二,三个元素分别为'1';'2','3'.其余元素初始化为0。 1. 数组是使用下标来访问的,下标是从 0 开始。 2. 数组的大小可以通过计算得到。
int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);

一维数组在内存中是连续储存的,随着数组下标的增加,在内存中的地址也增加。

冒泡排序
void maopao(int arr[], int sz)
{
	int flag = 0;
	for (int i = 0;i < sz - 1;i++)
	{
		for (int j = 0;j < sz -1- i;j++)
		{
			if (arr[j] > arr[j + 1]) { flag = 1; int m = arr[j];arr[j] = arr[j + 1];arr[j + 1] = m; }
			
		}
		if (flag == 0) break;
	}
}

数组的长度需要外部传参获得,因为数组传递给函数的是首元素的地址,无法在函数内部求得真正的数组长度。

通常情况下,数组名代表的是数组首元素的地址,有两个外

sizeof内部单独放一个数组名,数组名表示整个数组。用&数组名取地址时,取出的是整个数组的地址。 二维数组

二维数组的创建与初始化

例:

int arr[3][4] = {1,2,3,4};//三行四列,后俩行初始化为0 int arr[3][4] = {{1,2},{4,5}};一个括号表示一行内的元素,其余初始化为0 int arr[][4] = {{2,3},{4,5}};两行四列,其余初始化为0. 二维数组如果有初始化,行可以省略,列不能省略 二维数组在内存中也是连续储存的,arr[0]->arr[1]->arr[2]...... 数组越界

数组下标的使用应在0-n-1之间,下标不在此范围内 *** 作数组,则称为数组越界。

五子棋游戏

思路:通创建二维数组,简历棋盘的横轴与纵轴,下棋的实质是向二维数组对应的元素存放数据。

初始化:在下棋之前,应把数组元素初始化为空格。

打印棋盘:打印完每个元素后打印一个|作为分隔,每行最后的元素不打印,每打印完一行,,打印一行符号作为分隔,最后一行不打印,通过写循环实现即可。

真人下棋:下棋时需要输入坐标,每下一次棋,就往数组对应坐标的元素中存入数据,下棋的过程应写成循环,写下棋函数时,应判断输入的坐标的元素上是否已被下,或者坐标范围是否符合,否则,应重新进入下棋循环,重新输入。

判断输赢:分横向/纵向/左上斜/左下斜。当连续的上述情况的循环里出现的都是‘*’,则人赢,若出现的都是'#',则电脑赢。

电脑下棋:通过对上述判断条件的稍微修改,若还差一步,真人方就要赢的时候,在差的那个空位填入‘#’,阻止其赢,若四种情况都不满足,则采用生成横纵坐标随机数,找到空位,写入。

下棋过程写入循环,当一方赢后,才跳出循环,再判断哪一方赢。

#include
#include
#define row 5
#define col 5
int judge(char arr[row][col], int x, int y)//判断输赢
{
	//横向
	for (int i = 0;i < x;i++)
	{
		int count1 = 0;int count2 = 0;
		for (int j = 0;j < y;j++)
		{
			if (arr[i][j] != '*') count1++;
			if (arr[i][j] != '#') count2++;
		}
		if (count1 == 0) return 0;//人赢
		else if (count2 == 0) return 1;//电脑赢
	}
	//纵向
	for (int i = 0;i < y;i++)
	{
		int count1 = 0;int count2 = 0;
		for (int j = 0;j < x;j++)
		{
			if (arr[j][i] != '*') count1++;
			if (arr[j][i] != '#') count2++;
		}
		if (count1 == 0) return 0;
		else if (count2 == 0) return 1;
	}
	//左上起始斜
	if (x > y) x = y;
	int count1 = 0;int count2 = 0;
	for (int i = 0;i < x;i++)
	{
		if (arr[i][i] != '*') count1++;
		if (arr[i][i] != '#') count2++;
	}
	if (count1 == 0) return 0;
	else if (count2 == 0) return 1;
	//左下起斜
	count1 = 0;count2 = 0;
	for (int i = 0;i < x;i++)
	{
		if (arr[x - 1 - i][0 + i] != '*') count1++;
		if (arr[x - 1 - i][0 + i] != '#') count2++;
	}
	if (count1 == 0) return 0;
	else if (count2 == 0) return 1;
	return 2;
}
int  computerplay(char arr[row][col], int x, int y)
{
	int n = x;
	//电脑随机下
	printf("电脑下棋n");
	//横向
	for (int i = 0;i < x;i++)
	{
		int count1 = 0;
		for (int j = 0;j < y;j++)
		{
			if (arr[i][j] == '*') count1++;
		}
		if (count1 == n - 1)
		{
			for (int j = 0;j < y;j++)
			{
				if (arr[i][j] == ' ') { arr[i][j] = '#';return 0; }
			}
		}
	}
	//纵向
	for (int i = 0;i < y;i++)
	{
		int count1 = 0;
		for (int j = 0;j < x;j++)
		{
			if (arr[j][i] == '*') count1++;

		}
		if (count1 == n - 1)
		{
			for (int j = 0;j < x;j++)
			{
				if (arr[j][i] == ' ') { arr[j][i] = '#';return 1; }

			}
		}
	}
	//左上起始斜
	int count1 = 0;
	for (int i = 0;i < n;i++)
	{
		if (arr[i][i] == '*') count1++;

	}
	if (count1 == n - 1)
	{
		for (int i = 0;i < n;i++)
		{
			if (arr[i][i] == ' ') { arr[i][i] = '#';return 1; }

		}
	}
	//左下起斜
	count1 = 0;
	for (int i = 0;i < n;i++)
	{
		if (arr[x - 1 - i][0 + i] == '*') count1++;
	}
	if (count1 == n - 1)
	{
		for (int i = 0;i < n;i++)
		{
			if (arr[x - 1 - i][0 + i] == ' ') { arr[x - 1 - i][0 + i] = '#';return 1; }
		}
	}
	int count = 0;
	while (1)
	{
		count++;
		int i = rand() % (x - 1);
		int j = rand() % (y - 1);
		if (arr[i][j] == ' ')
		{
			arr[i][j] = '#';
			break;
		}
		if (count > 1000) break;
	}
	//电脑不完全随机下;
	
}
int humanplay(char arr[row][col], int m, int n)
{
	int x = 0;int y = 0;
	printf("请输入坐标->:");
	scanf("%d %d", &x, &y);
	while (1)
	{
		if (x >= 1 && x <= m && y >= 1 && y <= m)
		{
			if (arr[x - 1][y - 1] != ' ') { printf("该坐标已被下,请重新输入n"); return 0; }
			else { arr[x - 1][y - 1] = '*'; return 1; }
		}
		else printf("坐标范围有误n"); return 0;

	}
}
void printqipan(char arr[row][col], int x, int y)
{
	for (int i = 0;i < x;i++)
	{
		for (int j = 0;j < x;j++)
		{
			printf(" %c ", arr[i][j]);
			if (j < x - 1) printf("|");
		}
		printf("n");
		for (int j = 0;j < x;j++)
		{
			printf("---");
			if (j < x - 1) printf("|");
		}
		printf("n");
	}
}
void setqipan(char arr[row][col], int x, int y)
{
	for (int i = 0;i < x;i++)
	{
		for (int j = 0;j < y;j++)
		{
			arr[i][j] = ' ';
		}
	}
}
void game()
{
	char arr[row][col] = { 0 };
	setqipan(arr, row, col);//初始化棋盘
	printqipan(arr, row, col);//打印棋盘;
	while (judge(arr, row, col) != 0 && judge(arr, row, col) != 1)
	{
		;//真人下棋

		if (humanplay(arr, row, col) == 1)
		{
			printqipan(arr, row, col);//打印棋盘;
			computerplay(arr, row, col);//电脑下棋;
			printqipan(arr, row, col);//打印棋盘;
		}
	}
	if (judge(arr, row, col) == 0) printf("恭喜您,赢了。n");
	else if (judge(arr, row, col) == 1) printf("很遗憾,输了。n");
}
void menu()
{
	printf("*************************n");
	printf("*********开始-输入‘1’***n");
	printf("*********退出-输入‘0‘***n");
	printf("*************************n");

}
void test()
{
	int input = 0;
	do {
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:game();break;
		case 0:printf("已退出");break;
		default:printf("无效命令");continue;
		}
	} while (input);
}
int main()
{
	srand((unsigned int)time(NULL));
	test();
	return 0;
}
扫雷游戏的实现

分为几个模块

初始化棋盘,打印棋盘,埋雷,用户输入判断,输入后打印,判断是否排雷完成。以及展开。

我们需要创建两个二维数组,一个数组用来存放雷的位置,另一个数组专门用来用户输入后计算存入周围雷的数值并打印。这样两个数组互不干扰。

初始化数组时,为了防止数组的越界的问题,如果我们本意是设置9X9的棋盘,那我们应该创建两个行列都是11的数组,只有这样在计算对应坐标周围八个位置的雷数时才不会造成数组越界,我们只需要用到这倆个数组的第二行至第十行。第二列至第十列。

打印棋盘:遍历数组即可

埋雷:通过时间戳设置随机函数起始值,通过随机函数生成坐标埋雷。

用户输入判断:判断坐标是否合理,判断是否是雷。

由于每次输入后都会打印数组,打印时会遍历数组,所以在打印遍历数组时计算数组中未排查出的坐标数量,当未排查出的坐标数量等于雷的个数时,排雷完成。

展开:就是说当输入的坐标周围八个不是雷时,从周围八个坐标开始,依次排查,符合坐标周围八个不是雷时让其显示出来,也就是一个递归,从而实现展开。

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#define ROW 9
#define COL 9
#define SUM 4
#define ROWS ROW+2
#define COLS COL+2
int judge(char arr[ROWS][COLS], int x, int y)
{
	int sum = 0;
	for (int i = -1;i <= 1;i++)
	{
		for (int j = -1;j <= 1;j++)
		{
			sum += arr[x + i][y + j] - '0';
		}
	}
	return sum;
}
void spread(char ous[ROWS][COLS], char ins[ROWS][COLS], int x, int y)
{
	if (x < 1 || y < 1) return 0;
	if (judge(ins, x, y) == 0)
	{
		for (int i = -1;i <= 1;i++)
		{
			for (int j = -1;j <= 1;j++)
			{
				if (ous[x + i][y + j] == '#') { ous[x + i][y + j] = judge(ins, x + i, y + j) + '0';spread(ous, ins, x + i, y + j); }
			}
		}
	}
	if (judge(ins, x, y) != 0) { ous[x][y] = judge(ins, x, y) + '0';return 0; }
}
int printqipan(char arr[ROWS][COLS], int row, int col)
{
	int countwin = 0;
	for (int i = 0;i <= row;i++)
	{
		printf(" %d |", i);
	}
	printf("n");
	printf("n");
	for (int i = 1;i <= row;i++)
	{
		printf(" %d |", i);
		for (int j = 1;j <= col;j++)
		{
			if (arr[i][j] == '0') arr[i][j] = ' ';
			printf(" %c ", arr[i][j]);
			printf("|");
			if (arr[i][j] == '#' || arr[i][j] == '$') countwin++;
		}
		printf("n");
		printf("n");
	}
	printf("n");
	return countwin;
}
void play(char ous[ROWS][COLS], char ins[ROWS][COLS], int row, int col, int sum)
{
	int x = 0;int y = 0;int choice = 0;
	while (1)
	{
		printf("1.排查地雷 2.标记地雷 3.取消标记n");
		scanf("%d", &choice);
		if (choice > 3) continue;
		printf("请输入坐标n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (choice == 1)
			{
				if (ins[x][y] == '1') { printf("很遗憾,你被炸死了n"); printqipan(ins, ROW, COL);break; }
				else
				{
					ous[x][y] = judge(ins, x, y) + '0';
					if (judge(ins, x, y) == 0) spread(ous, ins, x, y);
					if (printqipan(ous, ROW, COL) == sum) { printf("排雷完成n"); break; }
				}
			}
			if (choice == 2)
			{
				if (ous[x][y] == '#') { ous[x][y] = '$';printqipan(ous, ROW, COL); }
				else { printf("非法标记,重新输入n"); }
			}
			if (choice == 3)
			{
				if (ous[x][y] == '$') { ous[x][y] = '#';printqipan(ous, ROW, COL); }
				if (ous[x][y] != '$') { printf("未被标记,重新输入n"); continue; }
			}
		}
		else
		{
			printf("坐标输入有误,请重新输入n");
			continue;
		}
	}
}
void setlei(char arr[ROWS][COLS], int row, int col, int sum)
{
	int count = sum;int i = 0;int j = 0;
	while (count)
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (arr[i][j] == '0') { arr[i][j] = '1'; count = count - 1; }
	}
}

void setqipan(char arr[ROWS][COLS], int rows, int cols, char set)
{
	for (int i = 0;i < rows;i++)
	{
		for (int j = 0;j < cols;j++)
		{
			arr[i][j] = set;
		}
	}
}
void game()
{
	char ins[ROWS][COLS] = { 0 };
	char ous[ROWS][COLS] = { 0 };
	setqipan(ins, ROWS, COLS, '0');
	setqipan(ous, ROWS, COLS, '#');
	setlei(ins, ROW, COL, SUM);
	
	printqipan(ous, ROW, COL);
	play(ous, ins, ROW, COL, SUM);
}
void menu()
{
	printf("*******************n");
	printf("***开始-输入'1'***n");
	printf("***退出-输入'0'***n");
	printf("*******************n");
}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1: game();break;
		case 0:printf("退出成功n");break;
		default:printf("无效命令n");
		}
	} while (input);
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5711867.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存