浏览 3135 次
锁定老帖子 主题:趣味编程:命令行版的扫雷游戏
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-06
最后修改:2009-01-29
package fun.mine; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.List; import java.util.Random; public class FunMine { int row,column; //行数、列数 int mineNum; //布雷数 int marked; //已标记雷数 Cell[][] cells; //表示雷区的数组 /** * 布雷 */ public void fill(int row,int column,int num){ this.row=row; this.column=column; this.mineNum=num; this.marked=0; cells=new Cell[row][column]; for(int i=0;i<row;i++){ for(int j=0;j<column;j++){ cells[i][j]=new Cell(); cells[i][j].rowIndex=i; cells[i][j].colIndex=j; } } int nm=mineNum; Random rand=new Random(System.currentTimeMillis()); while(nm>0){ int r=rand.nextInt(row); int c=rand.nextInt(column); if (cells[r][c].mine==Cell.MINE_EMPTY){ cells[r][c].mine=Cell.MINE_HAS; nm--; } } settingNumber(); } /** * 填数 */ private void settingNumber(){ for(int r=0;r<row;r++) for(int c=0;c<column;c++){ if (cells[r][c].mine==Cell.MINE_EMPTY){ List<Cell> adj=getAdjacentCells(cells[r][c], new CellFilter(){ public boolean filter(Cell cell){ return cell.mine==Cell.MINE_HAS; } }); cells[r][c].mine=adj.size(); } } } /** * 取相邻单元格 * @param cell * @param filter 一个实现了CellFilter接口的实例,用于过滤单元格 * @return */ private List<Cell> getAdjacentCells(Cell cell,CellFilter filter){ List<Cell> rs=new java.util.ArrayList<Cell>(); for(int roff=-1;roff<2;roff++) for(int coff=-1;coff<2;coff++){ int cr=cell.rowIndex+roff; int cc=cell.colIndex+coff; if (cr>=0 && cr<row && cc >= 0 && cc < column ){ if (cr==cell.rowIndex && cc==cell.colIndex) continue; if (filter.filter(cells[cr][cc])) rs.add(cells[cr][cc]); } } return rs; } /** * 标记/取消标记 * @param r * @param c * @param mark */ public void mark(int r,int c,int mark){ if (mark!=Cell.CELL_MARK && mark!=Cell.CELL_UNMARK) return; cells[r][c].mark=mark; if (mark==Cell.CELL_MARK) { marked++; }else{ marked--; } } /** * 打开指定的单元格 * 如果是空白,则打开其周围的单元格; * 如果是雷,则 game over. * 如果是数字,则只是置成打开的状态,不做进一步处理。 * * @param cell */ public int open(Cell cell){ cell.status=Cell.STATUS_OPENED; if (cell.mine==Cell.MINE_HAS) return -1; if (cell.mine==Cell.MINE_EMPTY){ List<Cell> adj=getAdjacentCells(cell, new CellFilter(){ public boolean filter(Cell cell){ return cell.status==Cell.STATUS_CLOSED; } }); for(Cell a:adj) open(a); } return 0; } /** * 打开指定的单元格 * 如果是空白,则打开其周围的单元格; * 如果是雷,则 game over. * 如果是数字,则只是置成打开的状态,不做进一步处理。 * * @param r * @param c */ public int open(int r,int c){ return open(cells[r][c]); } /** * 单元格描述类 * 表示有雷或无雷、打开或关闭、标记或未标记。 */ public static class Cell { public static int MINE_HAS=-1; public static int MINE_EMPTY=0; public static int CELL_UNMARK=0; public static int CELL_MARK=1; public static int STATUS_CLOSED=0; public static int STATUS_OPENED=1; public Cell(){ mark=CELL_UNMARK; mine=MINE_EMPTY; status=STATUS_CLOSED; } int rowIndex; int colIndex; int mark; int mine; int status; } public static interface CellFilter{ public boolean filter(Cell cell); } /** * 打印雷区实际情况 */ protected void debug(){ System.out.println("Debug: "); for(int r=0;r<row;r++){ for(int c=0;c<column;c++){ System.out.print(String.format("%1$8s", cells[r][c].mine)); } System.out.println(); } } /** * 打印游戏状态 */ protected void print(){ System.out.println("Status:"); for(int r=0;r<row;r++){ for(int c=0;c<column;c++){ if (cells[r][c].status==Cell.STATUS_OPENED){ System.out.print(String.format("%1$8s", cells[r][c].mine)); }else if (cells[r][c].mark==Cell.CELL_MARK){ System.out.print(String.format("%1$8s", "P")); }else{ System.out.print(String.format("%1$8s", "I")); } } System.out.println(); } System.out.println(String.format("总雷数:%1$d 已标记:%2$d ",mineNum,marked)); } public static void main(String[] args){ FunMine cm=new FunMine(); cm.fill(8,8,15); System.out.println("准备好了吗?开始扫雷吧。"); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String line; try{ while((line=br.readLine())!=null){ try{ if ("exit".equals(line)){ break; } String[] argv=line.split("\\s"); if ("open".equals(argv[0])){ int r=Integer.parseInt(argv[1]); int c=Integer.parseInt(argv[2]); cm.open(r, c); }else if ("mark".equals(argv[0])){ int r=Integer.parseInt(argv[1]); int c=Integer.parseInt(argv[2]); cm.mark(r, c, Cell.CELL_MARK); }else if ("umark".equals(argv[0])){ int r=Integer.parseInt(argv[1]); int c=Integer.parseInt(argv[2]); cm.mark(r, c, Cell.CELL_UNMARK); }else if ("debug".equals(argv[0])){ cm.debug(); }else if ("print".equals(argv[0])){ cm.print(); }else if ("fill".equals(argv[0])){ int r=Integer.parseInt(argv[1]); int c=Integer.parseInt(argv[2]); int n=Integer.parseInt(argv[3]); cm.fill(r,c,n); }else if ("help".equals(argv[0])){ showUseage(); }else{ throw new Exception("input error."); } }catch(Exception ex){ System.out.println("input error."); } } }catch(Exception ex){ ex.printStackTrace(); } } public static void showUseage(){ System.out.println("exit Quit this program."); System.out.println("fill r c num Fill mines."); System.out.println("mark r c Mark a unit as mine."); System.out.println("umark r c Cancel a marking of the unit."); System.out.println("open r c open the unit, be careful."); System.out.println("print Print game status."); System.out.println("debug Print all mines of the game, for debug."); System.out.println("help Show this help screen."); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-01-06
好玩
|
|
返回顶楼 | |
发表时间:2009-01-06
不行,有创意,在 mark 后直接 print 一下,多数人都要看的
|
|
返回顶楼 | |
发表时间:2009-01-07
有创意,这个要比谁敲键盘快了
|
|
返回顶楼 | |