扫雷(极简基础版)

game.h 

#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define row 9
#define line 9
#define rows row+2
#define lines line+2
void initbroad(char arr[lines][rows], int a, int b, char sign);
void printbroad(char arr[lines][rows]);
void set(char arr[lines][rows]);
int found(char arr[lines][rows], int a, int b);
void win(char mine[lines][rows], char show[lines][rows]);

game.c  

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "game.h"
#include <time.h>
#include <stdlib.h>
int wins = line * row - 10;
void initbroad(char arr[lines][rows],int a,int b,char sign)
{
	for (int i = 0;i < a;i++)
	{
		for (int j = 0; j < b; j++)
		{
			arr[i][j] = sign;
		}
	}
}
void printbroad(char arr[lines][rows])
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= line; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= row; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}
void set(char arr[lines][rows])
{
	srand((unsigned int)time(NULL));
	int count = 10;
	while(count)
	{
		int a = rand() % 9 + 1;
		int b = rand() % 9 + 1;
		if (arr[a][b] != '1')
		{
			arr[a][b] = '1';
			count--;
		}
	}
}
int found(char arr[lines][rows], int a, int b)
{
	return (arr[a + 1][b] + arr[a + 1][b + 1] + arr[a + 1][b - 1] + arr[a][b + 1] + arr[a][b - 1] + arr[a - 1][b] + arr[a - 1][b + 1] + arr[a - 1][b - 1] - 8 * '0');
}

void clear(char mine[lines][rows],char show[lines][rows],int a,int b)
{
	for (int i = 0; i <= 1; i++)
	{
		for (int j = 0; j <= 1; j++)
		{
			if ((a + i) <= 9 && (a + i) >= 1 && (b + j) <= 9 && (b + j) >= 1&&(show[a + i][b + j] == '*'))
			{
				if (mine[a + i][b + j] == '0')
				{
					int vc = found(mine, a+i, b + j);
					show[a+i][b + j] = vc + '0';
					wins--;
				}
			}
			if ((a + i) <= 9 && (a + i) >= 1 && (b - j) <= 9 && (b - j) >= 1 && (show[a + i][b - j] == '*'))
			{
				if (mine[a + i][b - j] == '0')
				{
					int vc = found(mine, a+i, b - j);
					show[a+i][b - j] = vc + '0';
					wins--;
				}
			}
		}
	}
	for (int i = 0; i <= 1; i++)
	{
		for (int j = 0; j <= 1; j++)
		{
			if ((a - i) <= 9 && (a - i) >= 1 && (b + j) <= 9 && (b + j) >= 1 && (show[a - i][b + j] == '*'))
			{
				if (mine[a - i][b + j] == '0')
				{
					int vc = found(mine, a, b + j);
					show[a-i][b + j] = vc + '0';
					wins--;
				}
			}
			if ((a - i) <= 9 && (a - i) >= 1 && (b - j) <= 9 && (b - j) >= 1 && (show[a - i][b - j] == '*'))
			{
				if (mine[a - i][b - j] == '0')
				{
					int vc = found(mine, a-i, b - j);
					show[a-i][b - j] = vc + '0';
					wins--;
				}
			}
		}
	}
}

void win(char mine[lines][rows], char show[lines][rows])
{

	while (wins >= 0)
	{
		if (wins == 0)
		{
			printf("WIN\n");
			break;
		}
		printbroad(show);
		printf("选择纵坐标及横坐标:\n");
		int a, b;
		scanf("%d%d", &a, &b);
		if (a >= 1 && a <= 9 && b >= 1 && b <= 9&&(show[a][b]=='*'))
		{
			if (mine[a][b] == '0')
			{
				int vc = found(mine, a, b);
				show[a][b] = vc + '0';
				wins--;
				clear(mine,show,a,b);
			}
			else
			{
				printf("踩雷了\n");
				printbroad(mine);
				break;
			}
		}
		else
		{
			printf("输入错误,重试\n");
		}
	}
}

 main.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include "game.h"
void menu()
{
	printf("************************************************\n");
	printf("******************** 1.play ********************\n");
	printf("******************** 0.exit ********************\n");
	printf("************************************************\n");
}
char show[lines][rows];
char mine[lines][rows];
void game()
{

	initbroad(show, lines, rows, '*');
	initbroad(mine, lines, rows, '0');
	set(mine);
	win(mine, show);
}
int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("********************开始游戏********************\n");
			game();
			break;
		case 0:
			printf("已退出\n");
		default:
			printf("输入错误,请重试\n");
		}
	} while (input);
	return 0;
}

        本扫雷游戏非常简陋,代码量在200行左右。

        在这个程序中,我们需要实现的功能有菜单、初始化棋盘、显示棋盘、放置地雷、输入坐标后判断是否为雷、显示周围雷数、判断胜利条件。

        由于以上功能需多次使用,防止代码堆积过多不易查看,将其放于头文件中保存。

 1、菜单的建立:

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

2、创立棋盘:

char show[lines][rows];
char mine[lines][rows];

        我们需要两块棋盘,一块用于记录雷的位置,一块用于展示给玩家看。

        该棋盘大小为9x9;但由于我们需要为展示的棋盘标序号,且判断周围雷数时不能超越数组范围,所以需要设定棋盘大小为11x11。

        为方便管理,我们可将其用define定义于game.h中,并在game.c中引用即可。

#define row 9
#define line 9
#define rows row+2
#define lines line+2

3、初始化棋盘:

void initbroad(char arr[lines][rows],int a,int b,char sign)
{
	for (int i = 0;i < a;i++)
	{
		for (int j = 0; j < b; j++)
		{
			arr[i][j] = sign;
		}
	}
}

        遍历整个二维数组,赋予选定的字符,如show给予*,而mine给予‘0’。

4、打印棋盘及横纵坐标:

void printbroad(char arr[lines][rows])
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= line; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= row; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}
initbroad(show,lines,rows,'*');
printbroad(show);

结果如下:

5、 放置地雷:

        为防止地雷不随机,使用rand函数(stdlib.h),并使用srand((unsigned int)time(NULL))来根据时间设定种子(time.h)。

void set(char arr[lines][rows])
{
	srand((unsigned int)time(NULL));
	int count = 10;
	while(count)
	{
		int a = rand() % 9 + 1;//使a在1~9之间
		int b = rand() % 9 + 1;
		if (arr[a][b] != '1')//判断该位置是否为雷
		{
			arr[a][b] = '1';
			count--;//每放一个雷count减1,只会放置十个雷
		}
	}
}

6、选择坐标并判断是否胜利:

        首先设定胜利目标,即找出所有的非雷坐标,即9x9-10个;设其为wins。

int wins = line * row - 10;
void win(char mine[lines][rows], char show[lines][rows])
{

	while (wins >= 0)
	{
		if (wins == 0)//wins=0时代表剩余非雷坐标数为0
		{
			printf("WIN\n");
			break;
		}
		printbroad(show);
		printf("选择纵坐标及横坐标:\n");
		int a, b;
		scanf("%d%d", &a, &b);
		if (a >= 1 && a <= 9 && b >= 1 && b <= 9&&(show[a][b]=='*'))//使(a,b)在棋盘内
		{
			if (mine[a][b] == '0')//判断是否为雷
			{
				int vc = found(mine, a, b);//判断周围雷数,函数定义在下面
				show[a][b] = vc + '0';//使show对应位置为周围雷数
				wins--;
				clear(mine,show,a,b);
			}
			else
			{
				printf("踩雷了\n");
				printbroad(mine);
				break;
			}
		}
		else
		{
			printf("输入错误,重试\n");
		}
	}
}

7、判断周围雷数:

int found(char arr[lines][rows], int a, int b)
{
	return (arr[a + 1][b] + arr[a + 1][b + 1] + arr[a + 1][b - 1] + arr[a][b + 1] + arr[a][b - 1] + arr[a - 1][b] + arr[a - 1][b + 1] + arr[a - 1][b - 1] - 8 * '0');
}

8、如果排查位置不为雷且周围没有雷,可以展开一片:

        机理与上方几条一致

void clear(char mine[lines][rows],char show[lines][rows],int a,int b)
{
	for (int i = 0; i <= 1; i++)
	{
		for (int j = 0; j <= 1; j++)
		{
			if ((a + i) <= 9 && (a + i) >= 1 && (b + j) <= 9 && (b + j) >= 1&&(show[a + i][b + j] == '*'))
			{
				if (mine[a + i][b + j] == '0')
				{
					int vc = found(mine, a+i, b + j);
					show[a+i][b + j] = vc + '0';
					wins--;
				}
			}
			if ((a + i) <= 9 && (a + i) >= 1 && (b - j) <= 9 && (b - j) >= 1 && (show[a + i][b - j] == '*'))
			{
				if (mine[a + i][b - j] == '0')
				{
					int vc = found(mine, a+i, b - j);
					show[a+i][b - j] = vc + '0';
					wins--;
				}
			}
		}
	}
	for (int i = 0; i <= 1; i++)
	{
		for (int j = 0; j <= 1; j++)
		{
			if ((a - i) <= 9 && (a - i) >= 1 && (b + j) <= 9 && (b + j) >= 1 && (show[a - i][b + j] == '*'))
			{
				if (mine[a - i][b + j] == '0')
				{
					int vc = found(mine, a, b + j);
					show[a-i][b + j] = vc + '0';
					wins--;
				}
			}
			if ((a - i) <= 9 && (a - i) >= 1 && (b - j) <= 9 && (b - j) >= 1 && (show[a - i][b - j] == '*'))
			{
				if (mine[a - i][b - j] == '0')
				{
					int vc = found(mine, a-i, b - j);
					show[a-i][b - j] = vc + '0';
					wins--;
				}
			}
		}
	}
}

        最后将这几个功能结合便可得到扫雷代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值