描述:首先选择难度,根据选择的难度生成地雷图,并在控制台输出游戏界面,其中‘~’表示灰色区域,‘*’表示地雷,‘_’表示空白区域,‘1~8’表示提示数字,之后根据提示输入进行游戏操作。
说明:控制台输入输出,根据输入的行、列情况进行显示,可标注地雷。若当前选中的为数字则显示数字,若为地雷则游戏结束,若为灰色区域则将灰色区域周围的8格全部显示,直至周围全为数字为止。当提示数字周围标注的地雷数与数字相等,再次输入提示数字的行列时,则会自动显示提示数字周围未选中的区域。当提示数字和灰色区域全部显示完后,则过关,并输出用时。
注:1、控制台输入只能输入数字,输入其他会报错,并且输入的数字若超出范围则会提示重新输入;2、灰色区域周围只能是数字,不可能有其他情况;3、地雷周围的8格内至少有一个数字,否则不合规则;4、第一步绝对不会踩中地雷。
源代码:
import java.util.Scanner; /** * 游戏操作 * * 与SaoLei相配,主函数中调用new SaoLei2(); * * -2-->灰色, -1-->地雷, 0-->空白, 1~8-->提示数字 * * @author lixiang * */ public class SaoLei2 { private int[][] game; private SaoLei sl; private Scanner sc; private int choose; // 游戏选择 private boolean start = true; // 第一步判断 private long startTime; // 开始时间 private long endTime; // 结束时间 private boolean pass = false; // 是否过关 private boolean jump = false; // 跳过输入 private boolean flag = false; // 结果不全面标志 // 8个方向 上、下、左、右、左上、左下、右上、右下 public static final int[][] move = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{1,-1},{-1,1},{1,1}}; public SaoLei2() { sc = new Scanner(System.in); // 初始化开始 start(); game = new int[sl.rows+1][sl.columns+1]; print(game); // 执行游戏 play(0,0,0); } // 递归显示灰色区域 private void dfs(int i, int j){ game[i][j] = -2; for (int k = 0; k < 8; k++) { if(dfs_range(i, j, move[k][0], move[k][1])){ if(sl.data[i+move[k][0]][j+move[k][1]]==-2 && game[i+move[k][0]][j+move[k][1]]==0){ game[i+move[k][0]][j+move[k][1]] = -2; dfs(i+move[k][0], j+move[k][1]); }else{ game[i+move[k][0]][j+move[k][1]] = sl.data[i+move[k][0]][j+move[k][1]]; } } } } // 根据方向判别是否越界 private boolean dfs_range(int i, int j, int dir_i, int dir_j){ if(i+dir_i>=1 && i+dir_i<=sl.rows && j+dir_j>=1 && j+dir_j<=sl.columns) return true; return false; } // 计算提示数字跟周围的地雷标记是否相等 public boolean numberEqualsMines(int i, int j){ int count = 0; for (int k = 0; k < 8; k++) { if(dfs_range(i, j, move[k][0], move[k][1])){ if(game[i+move[k][0]][j+move[k][1]]==-1) count++; } } return count==game[i][j] ? true : false; } // 执行 public void play(int i, int j, int m){ while(!judge()){ if(!jump){ System.out.print("输入行:"); i = flag(1,sl.rows); System.out.print("输入列:"); j = flag(1,sl.columns); if(game[i][j]<=0 && game[i][j]!=-2){ System.out.print("是/否地雷(-1/0):"); m = flag(-1,0); }else m = 0; } // 标注地雷 if(m==-1){ game[i][j]=m; print(game); continue; } // 当第一步踩中地雷,重新布置 if(start && m==0){ while(sl.data[i][j]==-1){ sl.run(); } start = false; // 开始计时 startTime = System.currentTimeMillis(); } if(game[i][j]==0 || game[i][j]==-1){ // 未知区域 if(sl.data[i][j]==-1){ // 地雷 print(sl.data); System.out.println("哈哈,踩到地雷了!"); break; }else if(sl.data[i][j]==-2){ // 空白 dfs(i,j); if(!jump) print(game); else break; }else{ // 提示数字 game[i][j] = sl.data[i][j]; if(!jump) print(game); else break; } }else if(game[i][j]>0){ // 点击数字提示 if(numberEqualsMines(i, j)){ for (int k = 0; k < 8; k++) { if(dfs_range(i, j, move[k][0], move[k][1]) && game[i+move[k][0]][j+move[k][1]]==0){ jump = true; play(i+move[k][0],j+move[k][1],0); jump = false; } } print(game); } } } endTime = System.currentTimeMillis(); // 通关 if(pass){ if(flag) print(game); System.out.println("恭喜你,过关!"); System.out.println("用时" + transMsToMin(endTime-startTime)); } } // 将_ms时间转换为_m_s形式 public String transMsToMin(long time){ String res = ""; int second = (int) (time/1000), minute = 0; while(second >= 60){ second -= 60; minute++; } res += (minute>0 ? minute+"分" : "") + second + "秒"; return res; } // 判断是否过关 public boolean judge(){ for (int i = 1; i < game.length; i++) { for (int j = 1; j < game[i].length; j++) { if(sl.data[i][j]==-1) continue; if(game[i][j]!=sl.data[i][j]) return false; } } pass = true; // 通关,将所有0变为-1 if(pass){ for (int i = 1; i < game.length; i++) { for (int j = 1; j < game[i].length; j++) { if(game[i][j]==0){ game[i][j] = -1; flag = true; } } } } return true; } // 计算当前地雷数 public int count(){ int num = 0; for (int i = 1; i < game.length; i++) { for (int j = 1; j < game[i].length; j++) { if(game[i][j] == -1) num++; } } return num; } // 打印界面 public void print(int arr[][]){ System.out.println(); System.out.println("\t地雷数:" + count() + "/" + sl.count); if(sl.columns>=10){ for (int i = 0; i < 2; i++) { for (int j = 0; j < arr[0].length; j++) { if(i==0){ if(j==0)System.out.print(" |"); else System.out.print(j/10+"|"); }else{ if(j==0)System.out.print(" |"); else System.out.print(j%10+"|"); } } System.out.println(); } }else{ for (int i = 0; i < arr[0].length; i++) { if(i==0)System.out.print(" "); else System.out.print(i+" "); } System.out.println(); } for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { if(i==0){ if(j==0)System.out.print(" "); else System.out.print("_"); System.out.print(" "); } else{ if(j==0){ System.out.print(i); if(i<10) System.out.print(" "); } else if(arr[i][j]==0) System.out.print("_"); else if(arr[i][j]==-1) System.out.print("*"); else if(arr[i][j]==-2) System.out.print("~"); else System.out.print(arr[i][j]); System.out.print("|"); } } System.out.println(); } } // 输入判断 private int flag(int low, int high){ int num; do{ num = sc.nextInt(); if(num<low || num>high)System.out.println("重新输入:"); else break; }while(true); return num; } // 游戏难度选择 public void start(){ System.out.println("请选择难度:"); System.out.println("1.初级"); System.out.println("2.中级"); System.out.println("3.高级"); System.out.println("4.自定义"); choose = flag(1, 4); // 根据难度创建地雷 switch (choose) { case 1: sl = new SaoLei(9, 9, 10); // 初级 break; case 2: sl = new SaoLei(16, 16, 40); // 中级 break; case 3: sl = new SaoLei(16, 30, 99); // 高级 break; case 4: int r,c,count,range; // 行、列、地雷数、地雷数范围 System.out.print("自定义行(最大24):"); r = flag(1,24); System.out.print("自定义列(最大30):"); c = flag(1,30); range = (int)(r*c*0.45); System.out.print("自定义地雷数(最大"+ range +"):"); count = flag(1,range); sl = new SaoLei(r, c, count); break; default: break; } } }运行结果: