首页 > 解决方案 > 扫雷瓷砖价值问题

问题描述

我目前正在编写扫雷游戏,以了解有关在我的代码中使用对象的更多信息。我生成板的方式是:

我的问题:

棋盘生成成功后,偶尔会出现值不正确的牌,一般比应有的值少 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;
    }
}

标签: java

解决方案


你的逻辑在这里搞砸了:

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

您正在使用yfor 行,但 test y != randColx和的类似问题x != randRow


推荐阅读