import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;
/**
* <P>这是扫雷游戏的主类,它没有GUI,只能在命令行下输入坐标来执行扫雷的动作。</P>
*
* @author Liupeng Chen
* @version 1.0.0
* @since MineSweeper
*/
public class MineSweeper {
public static final Scanner std_input=new Scanner(System.in);
private int row,col;
private double mine_density;
private Mine minefield[][];
private String mineState[][];
/**
* 构造扫雷游戏的主类,初始化扫雷游戏。默认是6行6列的雷区,布雷密度为0.20
*/
public MineSweeper() {
this.row=6; //雷区为6行
this.col=6; //雷区为6列
this.mine_density=0.20; //布雷密度为0.20
initMinefield(); //初始化雷区设置
}
/**
* 构造扫雷游戏的主类,初始化扫雷游戏。自定义雷区的大小和布雷密度
*
* @param row 雷区的行数
* @param col 雷区的列数
* @param mine_density 布雷密度是控制游戏难度的一个主要参数,一般在0.10~0.30之间为宜,
* 过高的布雷密度只会提升玩家的运气降低他的智商
*/
public MineSweeper(int row,int col,double mine_density) {
// TODO Auto-generated constructor stub
this.row=row; //设置雷区的行数
this.col=col; //设置雷区的列数
this.mine_density=mine_density; //设置布雷的密度
initMinefield(); //初始化雷区设置
}
/**
* 初始化雷区设置,雷区的设置包括雷区的大小(行和列的数目)、每个布雷点的信息
* (是否真的埋下地雷和埋在周围布雷点的地雷总数)以及雷区的初始显示状态
*/
private void initMinefield() {
minefield=new Mine[row+2][col+2]; //为了方便计算,在雷区的周围多加空白的两行两列
Random r=new Random(); //将用来随机布雷的Random实例
//初始化雷区周围的两行两列,它们都是不含有地雷的
for (int i=0; i<row+2; i++) {
minefield[i][0]=new Mine(i,0,false);
minefield[i][col+1]=new Mine(i,col+1,false);
}
for (int j=0; j<col+2; j++) {
minefield[0][j]=new Mine(0,j,false);
minefield[row+1][j]=new Mine(row+1,j,false);
}
//初始化雷区的实际区域,并由布雷密度决定对每个布雷点的随机布雷
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++) {
if (r.nextDouble()<mine_density) //这条语句决定了随机布雷
minefield[i][j]=new Mine(i, j, true);
else
minefield[i][j]=new Mine(i, j, false);
}
}
//设置埋在每个布雷点周围的地雷总数
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++) {
Mine m=minefield[i][j];
m.setAroundMineNum(calcAroundMineNum(m));
}
}
initMineState(); //初始化雷区的显示状态
}
/**
* 计算布雷点周围的地雷总数并返回其值
* @param m
* @return
*/
private int calcAroundMineNum(Mine m) {
int aroundMines=0;
int X=m.getPlaceX(),Y=m.getPlaceY();
for (int i=-1; i<=1; i++) {
for (int j=-1; j<=1; j++) {
if (minefield[X+i][Y+j].isMine())
aroundMines++;
}
}
return aroundMines-(m.isMine()?1:0);
}
private void initMineState() {
mineState=new String[row+2][col+2];
for (int i = 0; i < row+2; i++) {
for (int j = 0; j < col+2; j++)
mineState[i][j]="O";
}
}
private void updateMineState() {
int n;
Mine m;
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++) {
m=minefield[i][j];
if (m.isStepedOn()) {
if ((n=m.getAroundMineNum())==0)
mineState[i][j]=".";
else mineState[i][j]=String.valueOf(n);
}
}
}
}
private void sweeping(Mine m) {
if (m.isMine()) {
m.setStepedOn();
return;
}
int X,Y;
LinkedList<Mine> searchMines=new LinkedList<Mine>();
Mine curMine=m;
curMine.setStepedOn();
if (curMine.getAroundMineNum()==0) searchMines.add(curMine);
while (!searchMines.isEmpty()) {
curMine=searchMines.remove();
X=curMine.getPlaceX(); Y=curMine.getPlaceY();
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (!(1<=X&&X<=row&&1<=Y&&Y<=col)) continue;
curMine=minefield[X+i][Y+j];
if (!curMine.isStepedOn()) {
curMine.setStepedOn();
if (curMine.getAroundMineNum()==0) searchMines.add(curMine);
}
}
}
}
updateMineState();
}
private boolean isWin() {
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++)
if (!minefield[i][j].isStepedOn()&&!minefield[i][j].isMine())
return false;
}
return true;
}
private void play() {
int X=1,Y=1;
Scanner sc=std_input.useDelimiter("\\D+");
while (true) {
displayCurMineState();
while (true) {
System.out.print("请输入目标位置(X,Y):");
X=sc.nextInt();
Y=sc.nextInt();
sc.nextLine();
if (1<=X&&X<=row&&1<=Y&&Y<=col)
if (!minefield[X][Y].isStepedOn()) break;
else System.out.println("目标("+X+","+Y+")已被扫雷,请重新输入");
else System.out.println("目标("+X+","+Y+")不合法!请重新输入");
}
System.out.println("执行目标("+X+","+Y+")的扫雷工作...");
System.out.println();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (minefield[X][Y].isMine()) {
displayFinalMineState();
System.out.println("囧...你踩雷了 @_@ ");
break;
}
else sweeping(minefield[X][Y]);
if (isWin()) {
displayFinalMineState();
System.out.println("恭喜你获胜了!");
break;
}
}
}
private void displayCurMineState() {
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++)
System.out.print(mineState[i][j]+" ");
System.out.println();
}
}
private void displayFinalMineState() {
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++)
if (minefield[i][j].isMine())
System.out.print("* ");
else System.out.print(mineState[i][j]+" ");
System.out.println();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int level;
char yORn='n';
Scanner sc;
MineSweeper ms;
System.out.println("**********************************************");
System.out.println("**********************************************");
System.out.println("************ 扫雷游戏(By 陈鎏鹏) ***********");
System.out.println("**********************************************");
System.out.println("**********************************************");
while (true) {
sc=std_input.useDelimiter("\\D+");
while (true) {
System.out.print("请选择游戏难度(0.默认 1.初级 2.中级 3.高级):");
level=sc.nextInt();
sc.nextLine();
if (0<=level&&level<=3) break;
else System.out.println("难度级别不合法!请重新输入");
}
if (level==1) {
ms=new MineSweeper(5,5,0.15);
System.out.println("扫雷游戏开始,难度级别:初级");
}
else if (level==2) {
ms=new MineSweeper(8,8,0.20);
System.out.println("扫雷游戏开始,难度级别:中级");
}
else if (level==3) {
ms=new MineSweeper(9,9,0.25);
System.out.println("扫雷开始,难度级别:高级");
}
else {
ms=new MineSweeper();
System.out.println("扫雷开始,难度级别:默认");
}
System.out.println();
ms.play();
sc.reset();
System.out.print("游戏结束,是否重新开始(Yes or Not):");
yORn=sc.next().charAt(0);
sc.nextLine();
if (yORn=='y'||yORn=='Y') continue;
else break;
}
System.out.println("^_^ Bye Bye!");
sc.close();
}
}
用Java做的命令行下的扫雷程序。。。
需积分: 9 120 浏览量
2008-12-24
20:45:03
上传
评论
收藏 7KB RAR 举报
chinpom
- 粉丝: 2
- 资源: 1