扫雷瓷砖价值问题

时间:2018-06-05 22:06:30

标签: java

我目前正在编写一个扫雷游戏,以便在我的代码中学习更多关于使用对象的知识。我生成董事会的方式是:

  • 创建指定行数和列数的“Tile”对象的二维数组
  • 平铺对象存储一个值(相邻炸弹的数量,如果是炸弹则为9),一个布尔值来表示是否已单击该平铺(如果单击一个平铺,则对于清除多个平铺的行为很重要不与任何炸弹相邻),以及用于图块的图形表示的按钮
  • 首先,通过将所有Tile值设置为0来设置电路板。
  • 然后,在一个while循环中,炸弹随机分布到电路板上。
  • 成功放置炸弹后,所有相邻的非炸弹Tile值都会增加1.使用行+列坐标确定板上是否存在该区域的方法可以避免绑定错误。
  • 重复此过程,直至放置所有炸弹。

我的问题:

在成功生成电路板后,偶尔会出现一些值不正确的磁贴,通常比它们应该少1。通常是“1”或“2”瓦片应该是“2”或“3”瓦片。我无法辨别出这种模式,这让人感到非常沮丧。我确信我可以用不同的方式构造我的代码,比如在每个炸弹放置后迭代板并添加数值,但这不是我想要的方式。我觉得这种方式比较凉爽。

我删除了图形内容,因为这个问题没有必要,我认为这已经是一个很长的代码,可以在这里发布一个问题了。您应该能够将其粘贴到IDE中并使其运行正常,游戏板将输出到您的控制台。

我的电路板设置为5x5,有5个炸弹,虽然这个问题在所有电路板尺寸和炸弹密度上都存在。这个问题并不常见,并且不会出现在每一块板上。我通常会在这样大小的板上运行2-3次后看到它,所以要做好准备。

这是一个示例图片,适用于任何不想打开IDE的人。如你所见,“1”牌与2枚炸弹相邻:

Minesweeper Error

但不用多说,这是我的代码。谢谢!

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;
    }
}

1 个答案:

答案 0 :(得分:1)

你的逻辑搞砸了:

           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行,但请测试y != randCol。与xx != randRow类似的问题。