Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为扫雷游戏创建随机地雷 JButton[][]按钮=新JButton[20][20]; 公共空矿(){ ArrayList x=新的ArrayList(); ArrayList y=新的ArrayList(); 对于(int a=0;a_Java_Minesweeper - Fatal编程技术网

Java 为扫雷游戏创建随机地雷 JButton[][]按钮=新JButton[20][20]; 公共空矿(){ ArrayList x=新的ArrayList(); ArrayList y=新的ArrayList(); 对于(int a=0;a

Java 为扫雷游戏创建随机地雷 JButton[][]按钮=新JButton[20][20]; 公共空矿(){ ArrayList x=新的ArrayList(); ArrayList y=新的ArrayList(); 对于(int a=0;a,java,minesweeper,Java,Minesweeper,这里: JButton[][] buttons = new JButton[20][20]; public void mines(){ ArrayList<Integer> x = new ArrayList<>(); ArrayList<Integer> y = new ArrayList<>(); for(int a=0;a<20;a++){ x.add(a); y.add(a);

这里:

 JButton[][] buttons = new JButton[20][20];
public void mines(){
    ArrayList<Integer> x = new ArrayList<>();
    ArrayList<Integer> y = new ArrayList<>();
    for(int a=0;a<20;a++){
        x.add(a);
        y.add(a);
    }
    for(int i=0;i<30;i++){
    int random_x = x.get(new Random().nextInt(x.size()));
    int random_y = y.get(new Random().nextInt(y.size()));
    x.remove(random_x);
    y.remove(random_y);
    buttons[random_x][random_y].setText("X");
    }  
}
for(int i=0;i<30;i++){
int random_x=x.get(new random().nextInt(x.size());
int random_y=y.get(new random().nextInt(y.size());
x、 移除(随机_x);
y、 移除(随机);
....
将生成一个IndexOutOfBoundsException


您的列表有20个元素,您正在从中删除30倍的元素…

您的随机坐标可能大于您的网格大小。如果x的大小为20,并且您的随机x也是20,则您将有一个
索引自动边界异常

将其更改为:

for (int i = 0; i < 30; i++) {
    int random_x = x.get(new Random().nextInt(x.size()));
    int random_y = y.get(new Random().nextInt(y.size()));
    x.remove(random_x);
    y.remove(random_y);
....
x.remove(Integer.valueOf(random_x));
如果大小为20,则会得到一个介于0和19之间的随机数

此外,由于列表的类型为
Integer
,因此
x.remove(random_x)
调用将其解释为列表中的索引,而不是对象本身

要解决此问题,请在调用
remove()
时使用
整数,而不是
int
。例如:

int random_x = x.get(new Random().nextInt(x.size() - 1));
int random_y = y.get(new Random().nextInt(y.size() - 1));

编辑: 要进一步改进/修复随机生成器,请将其更改为:

for (int i = 0; i < 30; i++) {
    int random_x = x.get(new Random().nextInt(x.size()));
    int random_y = y.get(new Random().nextInt(y.size()));
    x.remove(random_x);
    y.remove(random_y);
....
x.remove(Integer.valueOf(random_x));

使用以下代码段进行测试时:

int random_x = x.get(new Random().nextInt(x.size() == 1 ? 1 : x.size() - 1));
Test t=新测试();
t、 地雷();
对于(int i=0;i<20;i++)
{
对于(int j=0;j<20;j++)
{
如果(“X”.equals(t.buttons[i][j].getText()){
系统输出println(“x:+i+”,y:+j);
}
}
}
给出输出: x:0,y:18 x:1,y:5 x:2,y:1 x:3,y:3 x:4,y:9 x:5,y:15 x:6,y:14 x:7,y:10 x:8,y:8 x:9,y:11 x:10,y:16 x:11,y:17 x:12,y:0 x:13,y:7 x:14,y:4 x:15,y:12 x:16,y:2 x:17,y:6 x:18,y:13 x:19,y:19

试试这个方法:

Test t = new Test();
t.mines();

for (int i = 0; i < 20; i++)
{
    for (int j = 0; j < 20; j++)
    {
        if ("X".equals(t.buttons[i][j].getText())) {
            System.out.println("x:" + i + ", y:" + j);
        }
    }
}
publicstaticvoidmines(JButton[]]按钮)
{
Random rand=新的Random();
int地雷计数=0;
同时(地雷数<30)
{
int randomInteger=(int)(rand.nextDouble()*buttons.length);
int randomInteger2=(int)(rand.nextDouble()*按钮[0]。长度);
if(按钮[randomInteger][randomInteger2].getText().equals(“X”))
继续;
其他的
{
按钮[randomInteger][randomInteger2].setText(“X”);
地雷计数++;
}
}
}
.nextDouble()
方法返回一个小于1.0的双精度值。但我们需要一个介于0和19之间的随机整数(即
按钮.length
-1)

所以我们将这个随机的双精度值乘以按钮列表的大小,即20,然后将它转换为int,这样我们可以得到0到19之间的值

按钮之间的区别。长度
按钮[0]。长度
是,第一个按钮可以得到第一个维度的长度(如您所知,这是一个二维数组)第二个给出了第二维度的长度,所以你可以动态地得到这个数字,然后与随机数相乘,以避免
ArrayIndexOutOfBounds
异常

您可以将此方法用于任何大小的二维按钮数组,它都可以工作。但是警告,如果您使用的数组中的按钮少于30个,则循环将永远继续,因为您无法获得30个地雷:)


改进此方法的一种方法是参数化mineCount,因此您可以更改此方法,如
publicstaticvoidmines(JButton[][]按钮,int-mineCount)
这样您就可以在方法调用时设置地雷计数。

您选择了一个不寻常的模型来保存地雷位置的信息。虽然您可能会通过一些明智的调试来解决眼前的问题,但我预计这将给您带来进一步的问题

我建议将您的模式更改为更直接的模式,例如:

public static void mines(JButton[][] buttons)
{
    Random rand = new Random();
    int mineCount = 0;
    while (mineCount < 30)
    {
        int randomInteger = (int) (rand.nextDouble() * buttons.length);
        int randomInteger2 = (int) (rand.nextDouble() * buttons[0].length);
        if (buttons[randomInteger][randomInteger2].getText().equals("X"))
            continue;
        else
        {
            buttons[randomInteger][randomInteger2].setText("X");
            mineCount++;
        }
    }

}
类单元{
私有最终JButton按钮=新JButton();
私有布尔值mine=false;
私有布尔隐藏=真;
公共单元格(){
按钮。setText(“”);
}
公共空间{
断言隐藏;
我的=正确;
}
公共布尔hasMine(){
回采;
}
公开披露{
隐藏=错误;
button.setText(我的?“X”:“—”;
}
公共布尔值isHidden(){
返回隐藏;
}
}
类字段{
公共静态最终整数大小=20;
专用最终单元格[][]单元格=新单元格[大小][大小];
公共字段(int minesToAdd){
对于(int x=0;x0){
单元格=单元格[random.nextInt(大小)][random.nextInt(大小)];
如果(!cell.hasMine()){
cell.setMine();
Minestoad——;
}
}
}
公共JPanel getButtonPanel(){
....
}
}
我相信这会让你的意图更加清晰。这其中有一些问题,例如模型和表示之间的紧密联系(JButton),但这完全可以通过各种设计模式解决。

你可以尝试以下方法:

class Cell {
    private final JButton button = new JButton();
    private boolean mine = false;
    private boolean hidden = true;

    public Cell() {
        button.setText(" ");
    }

    public void setMine() {
        assert hidden;
        mine = true;
    }

    public boolean hasMine() {
        return mine;
    }

    public void reveal() {
        hidden = false;
        button.setText(mine ? "X" : "-");
    }

    public boolean isHidden() {
        return hidden;
    }
}

class Field {
    public static final int SIZE = 20;

    private final Cell[][] cells = new Cell[SIZE][SIZE];

    public Field(int minesToAdd) {
        for (int x = 0; x < SIZE; ++) {
            for (int y = 0; y < SIZE; y++) {
                cells[x][y] = new Cell();
            }
        }
        Random random = new Random();
        while (minesToAdd > 0) {
            Cell cell = cells[random.nextInt(SIZE)][random.nextInt(SIZE)];
            if (!cell.hasMine()) {
                cell.setMine();
                minesToAdd--;
            }
        }
    }

    public JPanel getButtonPanel() {
        ....
    }
}

这不是NPE吗?除非
按钮中的值在某个地方初始化。你为什么要分别处理x和y?你肯定想删除30个随机对,而不是30个随机x坐标和30个随机y坐标。它们是在某个地方初始化的,如果我将它们分开,我更容易理解。这是问题吗?h如果我知道,你没有告诉我们你可能遇到了什么问题,也没有显示足够的代码。最好告诉我们并显示所有错误、异常、错误行为,然后发布完整的。为什么?在控制台中,它没有说任何关于IndexOutofBoundsException的内容嗯…可能是因为我需要30个地雷…但是在x和y我只有20个整数,每次需要一个,它就消除了它。所以在某个时候arraylist将为空?我确实更新了代码2次。是吗