我是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.
答案 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。