java - 扫雷瓷砖价值问题
问题描述
我目前正在编写扫雷游戏,以了解有关在我的代码中使用对象的更多信息。我生成板的方式是:
- 创建具有指定行数和列数的“平铺”对象的二维数组
- Tile 对象存储一个值(相邻炸弹的数量,如果是炸弹,则为 9),一个布尔值,表示是否已单击该图块(如果单击不相邻的图块,这对于一次清除多个图块的行为很重要到任何炸弹),以及用于图块图形表示的按钮
- 首先,通过将所有 Tile 值设置为 0 来设置板。
- 然后,在一个while循环中,炸弹随机分布在棋盘上。
- 成功放置炸弹后,所有相邻的非炸弹 Tile 值都增加 1。通过采用行 + 列坐标确定该区域是否存在于板上的方法来避免绑定错误。
- 重复此过程,直到放置所有炸弹。
我的问题:
棋盘生成成功后,偶尔会出现值不正确的牌,一般比应有的值少 1。通常是“1”或“2”图块,应该是“2”或“3”图块。我无法辨别出任何模式,这使得它相当令人沮丧。我确信我可以以不同的方式构建我的代码,例如在放置每个炸弹后遍历板并添加数值,但这并不是我真正想要的方式。我觉得这种方式比较酷。
我已经删除了图形的东西,因为它不是这个问题所必需的,我认为这已经是一个很长的代码,可以在这里发布一个问题。您应该能够将其粘贴到您的 IDE 中并使其正常运行,并且游戏板将输出到您的控制台。
我将板设置为 5x5,带有 5 个炸弹,尽管这个问题在所有板尺寸和炸弹密度中都存在。这个问题不是很频繁,也不会出现在每个板上。我通常会在这种大小的板上运行 2-3 次程序后看到它,所以要为此做好准备。
这是一个示例图像,适用于不希望打开 IDE 的任何人。如您所见,“1”块与 2 个炸弹相邻:
但事不宜迟,这是我的代码。谢谢!
import java.util.concurrent.ThreadLocalRandom;
public class Main {
public static void main(String[] args) {
Board board = new Board(5, 5, 5);
board.setupBoard();
board.printBoard();
}
}
class Board {
/*
* height: the height of the game board (in Tiles)
* width: the width of the game board (in Tiles)
* bombs: the total number of bombs to be spawned
* tiles: 2d array of Tile objects, which store
* important game information
*/
private int rows, cols, bombs;
private Tile[][] tiles;
/*
* Constructor - assigns values to height, width and bombs
*/
Board(int rows, int cols, int bombs) {
this.rows = rows;
this.cols = cols;
this.bombs = bombs;
tiles = new Tile[rows][cols];
}
Tile[][] getTiles() {
return tiles;
}
/*
* Iterates tiles adjacent to bomb tile if:
* - Tile is not a bomb
* - Tile exists
*/
private void bombIterate(int y, int x) {
if(x >= 0 && y >= 0 && x < cols && y < rows && tiles[y][x].getValue() != 9) {
tiles[y][x].setValue(tiles[y][x].getValue() + 1);
}
}
/*
* Determines if a tile exists or not to easier avoid bound errors
*/
boolean validClick(int y, int x) {
if(x >= 0 && y >= 0 && x < cols && y < rows && tiles[y][x].getValue() != 9
&& !tiles[y][x].isClicked()) {
return true;
}
return false;
}
/*
* Sets up all bombs and tile values
*/
void setupBoard() {
/*
* Initializes the game board with 0's
*/
for(int y = 0; y < rows; y++) {
for(int x = 0; x < cols; x++) {
tiles[y][x] = new Tile(0);
}
}
/*
* Randomly distributes bombs to the game board
*/
int randRow; int randCol;
while(bombs > 0) {
randRow = ThreadLocalRandom.current().nextInt(0, rows);
randCol = ThreadLocalRandom.current().nextInt(0, cols);
if(tiles[randRow][randCol].getValue() != 9) {
tiles[randRow][randCol].setValue(9);
/*
* Iterate tile values around placed bomb
*/
for(int y = randRow - 1; y < randRow + 2; y++) {
for(int x = randCol - 1; x < randCol + 2; x++) {
if(y != randCol || x != randRow) {
bombIterate(y, x);
}
}
}
bombs--;
}
}
}
/*
* Prints the game board (to console)
*/
void printBoard() {
for(int y = 0; y < rows; y++) {
System.out.println();
for(int x = 0; x < cols; x++) {
System.out.print(tiles[y][x].getValue() + " ");
}
}
}
}
class Tile {
/*
* value = the numerical value of the tile
* 9 = bomb, 0-8 = number of adjacent bombs
*
* clicked = boolean - represents if the tile has
* been interacted with yet
*
* button = the GUI button that is linked to
* the tile
*/
private int value;
private boolean clicked;
Tile(int value) {
this.value = value;
this.clicked = false;
}
/*
* Sets a tile's "clicked" value to true/false
*/
void setClicked(boolean clicked) {
this.clicked = clicked;
}
/*
* Returns if the tile has been clicked or not
*/
boolean isClicked() {
return clicked;
}
/*
* Returns the tile's value
*/
public int getValue() {
return value;
}
/*
* Used to set the tile's value to a new integer
*/
void setValue(int value) {
this.value = value;
}
}
解决方案
你的逻辑在这里搞砸了:
for(int y = randRow - 1; y < randRow + 2; y++) {
for(int x = randCol - 1; x < randCol + 2; x++) {
if(y != randCol || x != randRow) {
bombIterate(y, x);
}
}
}
您正在使用y
for 行,但 test y != randCol
。x
和的类似问题x != randRow
。
推荐阅读
- typescript - 在方法中推断正确的字符串文字
- javascript - selenium (python) click() 方法不使用脚本但使用命令行
- alexa - Alexa NLP 有多强大?
- firebase - 如何在 Cloud Firestore 上的文档数组中添加值?
- python - 我应该将所有自定义异常包含在一个文件中吗?
- javascript - 如何在脚本中定义函数?
- react-native - v2 Navigation.showModal 创建新组件实例但实际上并未导航到它
- terminal - Git bash:找不到whereis命令
- video - 是否可以在相同大小(就数据而言)块上分割视频?
- dart - 如何在颤动中创建可滚动的日期选择器?