import java.util.*;
public class Game {
private static int[][] originalMap;//原始地图,记录地雷坐标
private static int[][] scanMap;//扫描地图,扫描用于记录格子对应的周围地雷数量
private static int height = 10;//地图高度
private static int width = 10;//地图宽度
private static int mine = 10;//地雷数量
private final static String myFormat = "%3s";
public static void main(String[] args) throws Exception {
Scanner scanner = null;
System.out.println("请输入地图的宽度和高度和地雷数量,示例: 10,10,7");
try {
scanner = new Scanner(System.in);
String inputString = scanner.nextLine();
String[] split = inputString.split(",");
try {
width = Integer.parseInt(split[0]);
height = Integer.parseInt(split[1]);
mine = Integer.parseInt(split[2]);
} catch (Exception e) {
System.out.println("地图输入异常,使用默认格式 15,15,45");
width = 15;
height = 15;
mine = 45;
}
init();//初始化地图大小并且埋入地雷
while (true) {
System.out.println("请输入当前排查地雷坐标 x,y 示例: 2,2");
AbstractMap.SimpleEntry<Integer, Integer> coordinate = inputCoordinate(scanner);
exec(coordinate);//排雷
System.out.println("当前地图: ");
show();
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (scanner != null)
scanner.close();
}
}
private static AbstractMap.SimpleEntry<Integer, Integer> inputCoordinate(Scanner scanner) {
String inputString = scanner.nextLine();
String[] split = inputString.split(",");
if (split.length != 2) {
System.out.println("输入坐标格式错误,请重新输入 示例: 3,5");
return inputCoordinate(scanner);
}
AbstractMap.SimpleEntry<Integer, Integer> coordinate = new HashMap.SimpleEntry<>(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
if (!isSurpass(coordinate)) {
System.out.println("输入的坐标操过界限,请重新输入");
return inputCoordinate(scanner);
} else {
return coordinate;
}
}
private static void show() {
//显示探索地图
for (int i = height - 1; i >= 0; i--) {
System.out.printf(myFormat, i);
System.out.printf(myFormat, "|");
for (int j = 0; j < width; j++) {
String tmp;
if (scanMap[j][i] == -1) {
tmp = "?";
} else if (scanMap[j][i] == 0) {
tmp = "0";
} else {
tmp = String.valueOf(scanMap[j][i]);
}
System.out.printf(myFormat, tmp);
}
System.out.println();
}
System.out.printf(myFormat, "y");
System.out.printf(myFormat, "/");
for (int j = 0; j < width; j++) {
System.out.printf(myFormat, "-");
}
System.out.println();
System.out.printf(myFormat, " ");
System.out.printf(myFormat, "x");
for (int j = 0; j < width; j++) {
System.out.printf(myFormat, j);
}
System.out.println();
}
/**
* 初始化地图大小并且埋入地雷
*
* @throws Exception 地雷过多
*/
private static void init() throws Exception {
if (mine > (height * width * 0.4)) {
throw new Exception("地雷数量太多,当前地图太拥挤,请增加地图大小或者降低地图中的地雷数量");
}
originalMap = new int[width][height];//初始化地图大小
scanMap = new int[width][height];
//初始化地图与扫描图
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
originalMap[i][j] = 0;//初始化地图的一个点 记录当前格子是否有地雷
scanMap[i][j] = -1;//初始化扫描图的一个点 数字表示周围一圈的地雷数量,-1表示当前格子没有探索过
}
}
for (int i = 0; i < mine; i++) {//放地雷到地图中
setMine();//放地雷
}
}
/**
* 往地图中随机埋入单个地雷
* 如果埋入地雷的位置已经有地雷了 重新找位置埋入地雷
*/
private static void setMine() {
//随机得到埋雷的坐标
double heightRandom = Math.random();//获取0~1之间的小数
double widthRandom = Math.random();//获取0~1之间的小数
long heightRound = Math.round((height - 1) * heightRandom);
long widthRound = Math.round((width - 1) * widthRandom);
int heightRoundInt = (int) heightRound;//横坐标
int widthRoundInt = (int) widthRound;//纵坐标
if (originalMap[heightRoundInt][widthRoundInt] == 0) {//找地方埋雷
//如果没有地雷,直接埋入
originalMap[heightRoundInt][widthRoundInt] = 1;
} else {
//如果有地雷,重新再埋入一次
setMine();//当前位置已经有地雷,重新找地方埋雷
}
}
private static void exec(AbstractMap.SimpleEntry<Integer, Integer> coordinate) throws Exception {
if (scanMap[coordinate.getKey()][coordinate.getValue()] != -1) {//只能探索未探索的格子
return;
}
if (originalMap[coordinate.getKey()][coordinate.getValue()] == 1) {
throw new Exception("踩到地雷");
} else {//当前格子没有地雷,自动向四周探索一圈
//获取周围一圈未被探索的坐标,并且在地图中的坐标
List<AbstractMap.SimpleEntry<Integer, Integer>> coordinateArray = getCoordinateArray(coordinate);//
//判断雷数量
int aroundMineSum = 0;//周围雷数量
for (AbstractMap.SimpleEntry<Integer, Integer> tuple2 : coordinateArray) {
if (originalMap[tuple2.getKey()][tuple2.getValue()] == 1) aroundMineSum++;
}
//记录当前探索的格子标记地雷数量
scanMap[coordinate.getKey()][coordinate.getValue()] = aroundMineSum;
if (aroundMineSum != 0) return; //如果周围有雷跳过 否则扩大一圈
for (AbstractMap.SimpleEntry<Integer, Integer> tuple2 : coordinateArray) {
exec(tuple2);
}
}
}
/**
* 当前坐标是否在越内
*
* @param coordinate 当前坐标点
* @return 是否越界
*/
public static boolean isSurpass(AbstractMap.SimpleEntry<Integer, Integer> coordinate) {
return coordinate.getKey() >= 0 && coordinate.getKey() < width && coordinate.getValue() >= 0 && coordinate.getValue() < height;
}
/**
* 当前坐标是否未探索
*
* @param coordinate 当前坐标点
* @return 是否探索
*/
public static boolean isExplore(AbstractMap.SimpleEntry<Integer, Integer> coordinate) {
return scanMap[coordinate.getKey()][coordinate.getValue()] == -1;
}
private static List<AbstractMap.SimpleEntry<Integer, Integer>> getCoordinateArray(AbstractMap.SimpleEntry<Integer, Integer> coordinate) {
int x = coordinate.getKey();
int y = coordinate.getValue();
//获取周围一圈的坐标
AbstractMap.SimpleEntry<Integer, Integer> LeftUpper = new HashMap.SimpleEntry<>(coordinate.getKey() - 1, coordinate.getValue() + 1);
AbstractMap.SimpleEntry<Integer, Integer> inUpper = new HashMap.SimpleEntry<>(coordinate.getKey(), coordinate.getValue() + 1);
AbstractMap.SimpleEntry<Integer, Integer> rightUpper = new HashMap.SimpleEntry<>(coordinate.getKey() + 1, coordinate.getValue() + 1);
AbstractMap.SimpleEntry<Integer, Integer> LeftIn = new HashMap.SimpleEntry<>(coordinate.getKey() - 1, coordinate.getValue());
AbstractMap.SimpleEntry<Integer, Integer> rightIn = new HashMap.SimpleEntry<>(coordinate.getKey() + 1, coordinate.getValue());
AbstractMap.SimpleEntry<Integer, Integer> LeftLower = new HashMap.SimpleEntry<>(coordinate.getKey() - 1, coordinate.getValue() - 1);
AbstractMap.SimpleEntry<Integer, Integer> inLower = new HashMap.SimpleEntry<>(coordinate.getKey(), coordinate.getValue() - 1);
AbstractMap.SimpleEntry<Integer, Integer> rightLower = new HashMap.SimpleEntry<>(coordinate.getKey() + 1, coordinate.getValue() - 1);
List<AbstractMap.SimpleEntry<Integer, Integer>> coordinateArray = new ArrayList<>();
if (isSurpass(LeftUpper) && isExplore(LeftUpper)) {
coordinateArray.add(LeftUpper);
}
if (isSurpass(inUpper) && isExplore(inUpper)) {
coordinateArray.add(inUpper);
}
if (isSurpass(rightUpper) && isExplore(rightUpper)) {
coordinateArray.add(rightUpper);
}
if (isSurpass(LeftIn) && isExplore(LeftIn)) {
coordinateArray.add(LeftIn);
}
if (isSurpass(rightIn) && isExplore(rightIn)) {
coordinateArray.add(rightIn);
}
if (isSurpass(LeftLower) && isExplore(LeftLower)) {
coordinateArray.add(LeftLower);
}
if (isSurpass(inLower) && isExplore(inLower)) {
coordinateArray.add(inLower);
}
if (isSurpass(rightLower) && isExplore(rightLower)) {
coordinateArray.add(rightLower);
}
return coordinateArray;
}
}
扫雷 java版本
最新推荐文章于 2025-08-05 17:34:52 发布