打印扫雷的地图
思路
① 先确定地图的size,输入size
②(选择挑战的版本),确定雷的数量
③根据生成雷的坐标,更新周围一圈map的值(这里size+2的意义在于,更新值避免下标溢出)
④打印地图
代码实现
- 初始化地图
输入地图的边长size,构建地图(用二维数组来表示)
tips:地图有效范围为1~size,初始化地图中0~size+1是为了给地图加一圈边,方便后续程序中对于雷的处理
Scanner input = new Scanner(System.in);
System.out.print("请输入地图的边长(≥6):");
int size = input.nextInt();//地图的边长,默认地图为正方形,即size*size
char[][] map = new char[size+2][size+2];
//初始化地图
for (int i = 0; i < size+2; i++) {//地图周围再环绕一圈,方便一会对地图进行处理
for (int j = 0; j < size+2; j++) {
map[i][j] = '0';
}
}
- 选择版本,通过选择版本来确定雷的数量num
(如果不选择版本的可以直接跳过这一步,直接通过输入num的值也可以)
//选择版本,即生成地雷的数量
System.out.print("请选择您想挑战的版本(1.初级 2.中级 3.高级 4.自定义雷的数量):");
int level = input.nextInt();
int num = 0;//记录地雷的数量
switch (level) {
case 1:
num = size ;
System.out.println("请稍后,正在生成初级版地图...");
break;
case 2:
num = size * 2;
System.out.println("请稍后,正在生成中级版地图...");
break;
case 3:
num = size * size / 2;
System.out.println("请稍后,正在生成高级版地图...");
break;
case 4:
System.out.print("请输入雷的数量:");
num = input.nextInt();
System.out.println("请稍后,正在生成自定义地图...");
break;
}
- 新建一个数组来标记雷
char[][] bomb = new char[size+2][size+2] ;//地雷
- 通过循环产生num个雷
-
- 使用random随机产生雷所在位置(x,y)(即随机产生x,y)
tips:地图有效范围为1~size,初始化地图0~size+1是为了给地图加一圈边,方便后续程序中对于雷的处理,所以雷产生的位置应该是在地图的有效范围1~size,因此为r.nextInt(size)+1,
- 使用random随机产生雷所在位置(x,y)(即随机产生x,y)
//bomb的x,y下标
int x,y;
//随机生成下标,表示bomb,范围[1,6),即[0,5]
x = r.nextInt(size)+1;
y = r.nextInt(size)+1;
-
- 产生雷的位置标记*,通过循环来判断此位置是否已存在雷,如果存在则重新生成坐标,如果不存在则在该位置添加雷,即给数组赋值“*”
//如果随机生成的位置已经存在雷,则重新生成
while (map[x][y] == '*') {
x = r.nextInt(size)+1;
y = r.nextInt(size)+1;
}
map[x][y] = '*' ; //标记bomp
- 接下来对bomb周围一圈的地图上标记
这里体现了为什么一开始地图初始化中虽然有效范围为1~size,但是定义成了0~size+1,实际上是为了给地图加一圈边,假如雷的位置在地图边缘,如果还是按照以其为中心对周围一圈的八个位置(即数组)进行操作,会出现数组下标越界的情况【比如雷的位置在map[1][1],处于地图的一角,如果没有加边处理,则地它周围一圈的八个位置只有3个是在地图的有效范围内,对另外位置进行处理时会出现下标越界的情况,为了避免这一情况对地图进行扩大一圈处理】,方便后续程序中对于雷的处理
具体思路:对雷的周围一圈八个位置进行判断,如果该位置不是雷,该位置对应的雷的数量就+1(即map[][]++)【一开始地图初始化的时候每个位置初始值都是0,表示周围没有雷,通过这一步的处理来进行修改】
if(map[x - 1][y - 1] != '*') {
map[x - 1][y - 1] ++;
}
if(map[x - 1][y] != '*'){
map[x - 1][y] ++;
}
if(map[x - 1][y + 1] != '*'){
map[x - 1][y + 1] ++;
}
if(map[x][y - 1] != '*'){
map[x][y - 1] ++;
}
if(map[x][y + 1] != '*'){
map[x][y + 1] ++;
}
if(map[x + 1][y - 1] != '*'){
map[x + 1][y - 1] ++;
}
if(map[x + 1][y] != '*'){
map[x + 1][y] ++;
}
if(map[x + 1][y + 1] != '*'){
map[x + 1][y + 1] ++;
}
- 最后打印地图,即遍历标记地图的二维数组
只需要打印地图的有效范围1~size,另外用于辅助数据操作的边不属于地图的有效范围,不需要打印
for (int i = 1; i < size + 1; i++) {
for (int j = 1; j < size + 1; j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();//每打印一行就换行
}
完整代码
import java.util.Random;
import java.util.Scanner;
/*
打印扫雷的地图
思路:
先确定地图的size,输入size
(选择挑战的版本),确定雷的数量
根据生成雷的坐标,更新周围一圈map的值(这里size+2的意义在于,更新值避免下标溢出)
打印地图
*/
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Random r = new Random();
System.out.print("请输入地图的边长(≥6):");
int size = input.nextInt();//地图的边长,默认地图为正方形,即size*size
char[][] map = new char[size+2][size+2];
//初始化地图
for (int i = 0; i < size+2; i++) {//地图周围再环绕一圈,方便一会对地图进行处理
for (int j = 0; j < size+2; j++) {
map[i][j] = '0';
}
}
//选择版本,即生成地雷的数量
System.out.print("请选择您想挑战的版本(1.初级 2.中级 3.高级 4.自定义雷的数量):");
int level = input.nextInt();
int num = 0;//记录地雷的数量
switch (level) {
case 1:
num = size ;
System.out.println("请稍后,正在生成初级版地图...");
break;
case 2:
num = size * 2;
System.out.println("请稍后,正在生成中级版地图...");
break;
case 3:
num = size * size / 2;
System.out.println("请稍后,正在生成高级版地图...");
break;
case 4:
System.out.print("请输入雷的数量:");
num = input.nextInt();
System.out.println("请稍后,正在生成自定义地图...");
break;
}
//随机产生地雷
for (int i = 0; i < num; i++) {
//bomb的x,y下标
int x,y;
//随机生成下标,表示bomb,范围[1,6),即[0,5]
x = r.nextInt(size)+1;
y = r.nextInt(size)+1;
while (map[x][y] == '*') {
x = r.nextInt(size)+1;
y = r.nextInt(size)+1;
}
map[x][y] = '*' ; //标记bomp
//接下来对bomb周围一圈的地图上标记,周围加一圈的好处在于防止溢出
//方法有点傻,但是暂时还想不到其它的方法
if(map[x - 1][y - 1] != '*') {
map[x - 1][y - 1] ++;
}
if(map[x - 1][y] != '*'){
map[x - 1][y] ++;
}
if(map[x - 1][y + 1] != '*'){
map[x - 1][y + 1] ++;
}
if(map[x][y - 1] != '*'){
map[x][y - 1] ++;
}
if(map[x][y + 1] != '*'){
map[x][y + 1] ++;
}
if(map[x + 1][y - 1] != '*'){
map[x + 1][y - 1] ++;
}
if(map[x + 1][y] != '*'){
map[x + 1][y] ++;
}
if(map[x + 1][y + 1] != '*'){
map[x + 1][y + 1] ++;
}
}
//打印地图
for (int i = 1; i < size + 1; i++) {
for (int j = 1; j < size + 1; j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
}