Java MineSweeper控制台递归错误

时间:2016-03-15 01:46:42

标签: java algorithm recursion helper minesweeper

我是Stack的新手。

我的扫雷程序基于文本的程序遇到了麻烦,我无法按照我想要的方式让我的递归工作。

有人可以通过我的递归来帮助我揭示所有空白的细胞并且是“点击”细胞的邻居吗?

我的代码存在的问题是,每当我在10×10板内显示一个点时,

例如:

当你输入r显示,并放入第3行和第3列

代码显示地图的所有位置,不包括地雷, 而不是仅显示附近的数字,而不是连接到其他“空白”位置。

现在已经过时了

输出应为:

 1|  .  .  .  .  .  .  .  .  .  . 
 2|  .  .  .  .  .  .  .  .  .  . 
 3|  .  .  3  .  .  .  .  .  .  . 
 4|  .  .  .  .  .  .  .  .  .  . 
 5|  .  .  .  .  .  .  .  .  .  . 
 6|  .  .  .  .  .  .  .  .  .  . 
 7|  .  .  .  .  .  .  .  .  .  . 
 8|  .  .  .  .  .  .  .  .  .  . 
 9|  .  .  .  .  .  .  .  .  .  . 
10|  .  .  .  .  .  .  .  .  .  . 
     1  2  3  4  5  6  7  8  9 10 

然而实际输出是:

 1|  1  1  1  1  1  1  0  0  0  0 
 2|  1  .  1  1  .  1  0  0  0  0 
 3|  2  3  3  2  2  2  1  0  0  0 
 4|  1  .  .  1  1  .  2  1  1  0 
 5|  1  3  3  2  2  2  3  .  2  1 
 6|  0  2  .  2  1  .  3  3  .  1 
 7|  0  2  .  2  1  1  2  .  2  1 
 8|  1  2  3  2  1  0  1  1  1  0 
 9|  2  .  4  .  1  1  1  2  1  1 
10|  2  .  .  2  1  1  .  2  .  1 
     1  2  3  4  5  6  7  8  9 10 

这些是我的递归指南:

扫雷的递归算法

当用户点击某个单元格时

如果细胞尚未显露,请将其揭示

如果细胞的真实性质是我的,游戏结束

否则,如果单元格的真实性质为空白,则递归显示      如果他们在界限范围内并且没有被揭露,则每个邻居都有8个。

此算法自然地揭示所有相邻的空单元格,并在到达边缘上的数字单元格时终止。

这是我的新代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class P4_Icel_Murad_MinesweeperConsole {
     char resp = ' ';
     int row =  0;
     int col = 0;
     final static int MINES = 5;
     public boolean won = false;
     public boolean fail = false;
    public static void main(String[] args) {

        P4_Icel_Murad_MinesweeperConsole hello = new P4_Icel_Murad_MinesweeperConsole(10, MINES);
        System.out.println();
        hello.revealBoard();
    }


        private static class Cell {

            final int FLAGGED = 1;
            final int QUESTION = 2;
            final int BLANK = 3;


            public boolean hidden = true;
            public final boolean mine;
            public int flagType;
            public int neighbors = 0;


            public Cell(boolean mine) {
                this.mine = mine;
            }
            public void setFlag(int myFlagType){
                if(myFlagType == 1){
                    this.flagType = myFlagType;
                }else if (myFlagType == 2) {
                    this.flagType = myFlagType;
                }else if (myFlagType == 3) {
                    hidden = true;
                    this.neighbors = myFlagType;
                }
            }
            public boolean getflagType(int i) {
                if(i == 1){
                    return true;
                }else
                return false;
            }
        }

        private final int size;
        private Cell[][] board;

        private void revealBoard(){
            for (int i = 0; i < board.length; i++) {
                for (int j = 0; j < board[0].length; j++) {
                    Cell f = board[i][j];
                    f.hidden = false;

                }
            }
            showBoard();
        }
        private void revealCell(int i, int j){          
                    Cell f = board[i][j];
                    f.hidden = false;
                    f.setFlag(0);

        }



        private P4_Icel_Murad_MinesweeperConsole(int size, int numberOfMines) {
            this.size = size;
            initBord(numberOfMines);
            showBoard();
            while(!won && !fail){
                questionAsk();
                showBoard();
            }
        }

        private void questionAsk(){
            Scanner s = new Scanner(System.in);
            System.out.println("Would you like to flag a cell or reveal a cell?");
            System.out.println("Enter 'f' or 'r': >");
            resp = s.next().charAt(0);
             System.out.println("Enter row: ");
             row = s.nextInt() - 1;
             System.out.println("Enter col: ");
             col = s.nextInt() - 1;
             if(row > size || col > size){
                 System.out.println("This row/col amount is too high.");
                 showBoard();
                 questionAsk();
             }
             userInput(row,col,true);
        }
        private void initBord(int numberOfMines) {
            List<Cell> mines = new ArrayList<Cell>();
            for (int i = 0; i < size * size; i++) {
                mines.add(new Cell(i < numberOfMines));
            }
            Collections.shuffle(mines);
            board = new Cell[size][size];
            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    board[i][j] = (i == 0 || j == 0 || i == size || j == size)
                            ? new Cell(false)
                            : mines.remove(0);
                }
            }
            calculateNeighbors();
        }
        // F>HIDDEN IS DONE ONLY FOR ONE POS, MUST FIX
        private void userInput(int row, int col, boolean revealMines){
            Cell f = board[row][col];
            if (resp == 'r') {
                if (f.mine && !revealMines) {
                    return;
                }
            if (f.hidden) { 
                revealCell(row,col);

                if(f.mine){
                    failed();   
                }else if (f.neighbors == 0){

                        if (isInBounds(row + 1,col)){
                            Cell neighbor = board[row + 1][col];
                            if (neighbor.hidden && neighbor.neighbors == 0) {
                                userInput(row + 1,col,false);
                            }else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row + 1,col);
                            }
                        }
                        if (isInBounds(row - 1,col)){
                            Cell neighbor = board[row - 1][col];
                            if (neighbor.hidden && neighbor.neighbors == 0) {
                                userInput(row - 1,col,false);
                            }else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row - 1,col);
                            }
                        }
                        if (isInBounds(row,col - 1)){
                            Cell neighbor = board[row][col - 1];
                            if (neighbor.hidden && neighbor.neighbors == 0) 
                            userInput(row,col - 1,false);
                            else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row,col-1);
                            }
                        }
                        if (isInBounds(row , col + 1)){
                            Cell neighbor = board[row][col + 1];
                            if (neighbor.hidden && neighbor.neighbors == 0) 
                            userInput(row,col + 1,false);   
                            else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row,col+1);
                            }
                        }
                        if (isInBounds(row - 1,col - 1)){
                            Cell neighbor = board[row - 1][col - 1];
                            if (neighbor.hidden && neighbor.neighbors == 0) 
                            userInput(row - 1,col - 1,false);
                            else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row -1 ,col - 1);
                            }
                        }
                        if (isInBounds(row + 1,col - 1)){
                            Cell neighbor = board[row + 1][col - 1];
                            if (neighbor.hidden && neighbor.neighbors == 0) 
                            userInput(row + 1,col - 1,false);
                            else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row + 1 ,col - 1);
                            }
                        }
                        if (isInBounds(row + 1,col + 1)){
                            Cell neighbor = board[row + 1][col + 1];
                            if (neighbor.hidden && neighbor.neighbors == 0) 
                            userInput(row + 1,col + 1,false);
                            else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row + 1 ,col + 1);
                            }
                        }
                        if (isInBounds(row - 1,col + 1) && f.hidden){
                            Cell neighbor = board[row - 1][col + 1];
                            if (neighbor.hidden && neighbor.neighbors == 0) 
                            userInput(row - 1,col + 1,false);   
                            else if (neighbor.hidden && !neighbor.mine){
                                revealCell(row - 1 ,col + 1);
                            }
                        }

                }

            }
            }
            if(resp == 'f'){
                if (f.hidden) {
                    f.setFlag(1);
                    revealCell(row,col);

                }else if(f.flagType == 1){
                    f.setFlag(2);
                }else if(f.flagType == 2){
                    f.setFlag(3);
                }else if(f.flagType == 3){
                    f.setFlag(1);
                }

            }
            for (int i = 0; i < board.length; i++) {
                for (int j = 0; j < board.length; j++) {
                if(f.getflagType(1) == f.mine)
                    won = true;
                }
            }



                }



        private boolean isInBounds(int row, int col){
            if((row < size && row >= 0) && (col < size && col >= 0)){
                return true;
            }
            return false;
        }



        private void failed(){
            System.out.println("You Lost! :(");
            fail = true;
        }


        private void calculateNeighbors() {
            int count = 0;
            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {            
                    for (int di = -1; di <= 1; di++) {
                        for (int dj = -1; dj <= 1; dj++) {
                            if(isInBounds(i + di,j + dj))
                                if (board[i + di][j + dj].mine) count++;  
                        }
                    }
                    board[i][j].neighbors = count;
                    count = 0;
                }
            }

        }

        private void showBoard() {
            for(int i = 0; i < size; i++) {
                System.out.printf("%2d| ",i + 1);
               for(int j = 0; j < size; j++) {
                   Cell f = board[i][j];
                   if(f.hidden || f.flagType == 3) {
                       System.out.printf("%3s",". ");
                   }  else if (f.mine) {
                       System.out.printf("%3s","* ");
                   } else if (f.flagType == 1){
                       System.out.printf("%3s","F ");
                   }else if (f.flagType == 2){
                       System.out.printf("%3s","? ");
                   }else{
                       calculateNeighbors();
                       System.out.printf("%3s", f.neighbors + " ");
                   }
               }          
               System.out.println();
            }
            System.out.print("    ");
            for(int i = 0; i < size; i++) {
                System.out.printf("%3s",i + 1 + " ");
            }
            System.out.println();
        }

    }





Thank you in advance.

1 个答案:

答案 0 :(得分:0)

您只需要将布尔值传递给userInput函数,指示是否显示地雷。如果使用实际用户输入调用该函数,则应该传递true,因为应该显示我的并且它应该是游戏结束。如果函数是递归调用的,则传递false,因为您只想递归显示空单元格。

像这样测试:

private void userInput(int row, int col, boolean revealMines){
    Cell f = board[row][col];
    if (resp == 'r') {

        // if this cell is a mine and we are not revealing mines, return:
        if (f.mine && !revealMines)
            return;

        if (f.hidden) {

questionAsk函数中这样调用:

 userInput(row,col,true);
递归调用时

和false。

相关问题