package com.itheima_02;
import java.util.Random;
import java.util.Scanner;
public class RunBoom {
public static void main(String[] args) {
Random r = new Random();
int[][] map = new int[12][18]; //二维随机数数组,提供随机的数字分布
int[][] gameMap = new int[10][16]; //根据map生成扫雷的主要游戏数组
Boom[][] show = new Boom[12][18];//真正的用于修改的游戏地图
//初始化随机地图,二维数组边界为全部是系统初始化的0 ,便于判断扫雷地图的边界雷区
//主要是为了防止检测的时候数组越界
//从[1][1]到[max-1][max-1]
for (int i = 1; i < map.length-1; i++) {
for (int j = 1; j < map.length-1; j++) {
map[j] = r.nextInt(5) + 1; //随机范围 1-5
}
}
//printSoSo(map);这个是测试用的,打印查看随机数数组的生成情况
//获取gameMap 去掉map的边框并且检测每个位置的周边含有数字5的情况(就是含有雷的数目)
for (int i = 1; i < map.length-1; i++) {
for (int j = 1; j < map.length-1; j++) {
Boom b = new Boom();//每次都需要一个新的对象,用于存入Boom[][]中
//计数器,存储每个坐标周围的的雷的个数
int count = 0;
//已map[j]为中心进行边缘一圈检测
if (map[i - 1][j - 1] == 5) {
count++;
}
if (map[i - 1][j] == 5) {
count++;
}
if (map[i - 1][j + 1] == 5) {
count++;
}
if (map[j - 1] == 5) {
count++;
}
if (map[j + 1] == 5) {
count++;
}
if (map[i + 1][j - 1] == 5) {
count++;
}
if (map[i + 1][j + 1] == 5) {
count++;
}
if (map[i + 1][j] == 5) {
count++;
}
//这里gameMap是比map 两边都少1
gameMap[i-1][j-1] = count;
//此处设置 地图随机点 为5 的 时候 为雷
if (map[j]==5) {
b.setBang(true);//改变Boom对象的bang属性
}
/*其实gameMap应该是不必要的,可以直接存入Boom的对象中,主要是一开始自己写的
Boom类没那么多属性,后来写的过程中,慢慢调试加入的.后来写完了,感觉太痛苦,就不改了……
*/
b.setId(gameMap[i-1][j-1]);
show[j]=b;
//将Boom对象放入Boom的二维数组,注意,此处的数组中有一圈是null的,
//后面会进行数组修复,为了使检测到这些位置的时候自动停止,防止数组越界
}
}
//printSoSo(show); 这是测试用,看看地图生成的情况,下一行一样。
//printSoSo(gameMap);
//根据Id属性,对Boom的二维数组进行对应的ico的修改
//"#"代表雷," "代表周围一圈无雷,数字代表周围雷的数目,都以字符串的形式存入ico属性
change(show);
//对Boom数组的边界进行修复
repair(show);
//printIco(show);
while (true) {
Scanner sc = new Scanner(System.in);
//print(show);
int wide;//横坐标
int deep;//纵坐标
System.out.println("欢迎来到渣渣的扫雷,请输入横纵坐标(1-10)(1-16)");
while (true) {
System.out.println("请输入横坐标");
wide = sc.nextInt();
if (wide <= 10 && wide >= 1) {
//wide -= 1;
break;
} else {
System.out.println("请输入正确的横坐标");
}
}
while (true) {
System.out.println("请输入纵坐标");
deep = sc.nextInt();
if (deep <= 16 && deep >= 1) {
//deep -= 1;
break;
} else {
System.out.println("请输入正确的纵坐标");
}
}
//改变地图,判断结果
changeMap(show, wide, deep);
}
}
//游戏开始时函数.功能:改变显示,判断 gameover 与 win
public static void changeMap(Boom[][] show, int wide, int deep) {
if (show[wide][deep].isBang() == true) {
System.out.println("你摸到雷了哦,gameover");
//判断是雷,游戏结束,修改所有对象的显示属性, war 3 "i see dead people".
for (int i = 1; i < show.length-1; i++) {
for (int j = 1; j < show.length-1; j++) {
show[j].setFlag(true);
}
}
printIco(show);//打印全图
System.exit(0);//关机
} else {
//判断不为雷,则修改显示标记
show[wide][deep].setFlag(true);
//检测该坐标周围是否无雷,无雷显示
check(show,wide,deep);
//改变地图后,统计当前Boom[][]中是否还存在非雷的未显示的对象
int count = 0;
for (int i = 1; i < show.length-1; i++) {
for (int j = 1; j < show.length-1; j++) {
if (show[j].isFlag()==false&&show[j].isBang()==false) {
count++;
}
}
}
//如果所有的非雷对象都被显示,则游戏结束
if (count==0) {
System.out.println("you win");
System.exit(0);//关闭虚拟机
}
printIco(show);//打印刷新后的 扫雷地图
}
}
//修复函数,把周围边界的值设定好
public static void repair(Boom[][] show){
for (int i = 0; i < show.length; i++) {
for (int j = 0; j < show.length; j++) {
//二维数组中无对象,则写入
if (show[j]==null) {
Boom empty = new Boom();
empty.setId(9); //原本想留着有用,终究没用上
empty.setIco(" ");
empty.setBang(false);
empty.setFlag(true);
show[j] = empty;
}
}
}
}
//刚开始想递归检测,栈内存溢出,后来放弃了,...技术太差,装不来
/*
检测函数,功能是检测输入点的一周是否无雷,无雷则全部显示;
写完后就没修改了,比较复杂,后来写注释的时候,感觉不用这么麻烦;
点周围一圈无雷的话直接判断输入点坐标对象的Id是否为-4或者其ico是否equals(" ")就可以了;
*/
public static void check(Boom[][] show,int wide,int deep) {
//if(show[wide][deep].getId()!=9){
//判断条件很恶心......
if (show[wide-1][deep].isBang()==false&&show[wide-1][deep-1].isBang()==false&&show[wide-1][deep+1].isBang()==false&&show[wide][deep-1].isBang()==false&&show[wide][deep+1].isBang()==false&&show[wide+1][deep-1].isBang()==false&&show[wide+1][deep].isBang()==false&&show[wide+1][deep+1].isBang()==false) {
show[wide-1][deep].setFlag(true);
show[wide-1][deep-1].setFlag(true);
show[wide-1][deep+1].setFlag(true);
show[wide][deep+1].setFlag(true);
show[wide][deep-1].setFlag(true);
show[wide+1][deep].setFlag(true);
show[wide+1][deep-1].setFlag(true);
show[wide+1][deep+1].setFlag(true);
}
}
//测试用的数组内容显示函数
public static void testPrintIco(Boom[][] show){
for (int i = 1; i < show.length-1; i++) {
for (int j = 1; j < show.length-1; j++) {
System.out.print(show[j].getIco()+"|");
}
System.out.println();
System.out.println("————————————————————————————————");
}
}
//游戏中打印函数,根据flag 决定是否显示当前位置,顺便画了个简易的框图.
public static void printIco(Boom[][] show){
for (int i = 1; i < show.length-1; i++) {
System.out.println(" ————————————————————————————————");
System.out.print("|");
for (int j = 1; j < show.length-1; j++) {
if (show[j].isFlag()) {
System.out.print(show[j].getIco()+"|");
}else{
System.out.print("*|");
}
}
System.out.println();
}
System.out.println(" ————————————————————————————————");
}
public static void change(Boom[][] show){
//遍历检测 雷和无雷的位置,并且修改相应对象的Id
for (int i = 1; i < show.length-1; i++) {
for (int j = 1; j < show.length-1; j++) {
if (show[j].isBang()==true) {
show[j].setId(-1);
}else{
if (show[j].getId()==0) {
show[j].setId(-4);
}
}
}
}
//再次遍历,根据相应对象的Id值,对其ico进行不同的修改
for (int i = 1; i < show.length-1; i++) {
for (int j = 1; j < show.length-1; j++) {
if (show[j].getId()==-4) {
show[j].setIco(" ");
}else if (show[j].getId()==-1) {
show[j].setIco("#");
}else {
show[j].setIco(""+show[j].getId());
}
}
}
}
public static void printSoSo(int[][] a){ //打印int 数组
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
System.out.print(a[j]+" ");
}
System.out.println();
}
System.out.println("------------------------------------------------");
}
public static void printSoSo(Boom[][] a){ //打印 boom数组
for (int i = 1; i < a.length-1; i++) {
for (int j = 1; j < a.length-1; j++) {
System.out.print(a[j].getId()+" ");
}
System.out.println();
}
System.out.println("------------------------------------------------");
}
}
......真的被自己恶心到了...写的格式有点乱....以后要注意...不过能成功运行,还是挺开心的
扫雷.zip
(9.45 KB, 下载次数: 23)