打印扫雷的地图(Java)

打印扫雷的地图

思路

① 先确定地图的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
			//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();
		}
	}
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Selcouther

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值