我尝试为练习做一个扫雷,但我得到的错误是我不明白为什么

时间:2015-11-30 23:25:41

标签: java

import java.util.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

public class StartGame
{  
   private JFrame frame;
   private JPanel panel;
   private JButton[][] button = new JButton[9][9];
   private int[][] status = new int[9][9];

   public StartGame()
   {
      frame = new JFrame();
      frame.setTitle("MineSweeper");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(500, 500);

      panel = new JPanel();
      panel.setLayout(new GridLayout(9, 9));
      for (int i = 0; i < button.length; i++)
      {
         for (int j = 0; j < button.length; j++)
         {
            button[i][j] = new JButton("");
            panel.add(button[i][j]);
            status[i][j] = 0;
            button[i][j].addActionListener(new ButtonListener());
         }
      }

      setMine();

      frame.add(panel);
      frame.setVisible(true);

   }

   public void setMine()
   {
      Random randomNumber = new Random();
      for (int i = 0; i < 10; i++)
      {
         int x = randomNumber.nextInt(9);
         int y = randomNumber.nextInt(9);
         if (status[x][y] != 1)
         {
            status[x][y] = 1;
         }
         else 
         {
            i--;
         }
      }
   }

   public class ButtonListener implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         for (int x = 0; x < button.length; x++)
         {
            for (int y = 0; y < button.length; y++)
            {
               if (e.getSource() == button[x][y])
               {
                  if (status[x][y] == 0)
                  {
                     ButtonChange(x, y);
                  }
                  else 
                  {
                     JOptionPane.showMessageDialog(null ,"YOU LOSS");
                  }
               }
            }
         }
      }    
   }

   public void ButtonChange(int x, int y)
   {
      if (x >= 0 && y >= 0 && x < button.length && y < button.length)
      {
         int num = 0;
         if (status[x][y] == 0)
         {
            num += CheckMine(x-1, y-1);
            num += CheckMine(x, y-1);
            num += CheckMine(x+1, y-1);
            num += CheckMine(x-1, y);
            num += CheckMine(x+1, y);
            num += CheckMine(x-1, y+1);
            num += CheckMine(x, y+1);
            num += CheckMine(x+1, y+1);
         }

         if (num == 0)
         {
            button[x][y].setEnabled(false);
            ButtonChange(x, y-1);
            ButtonChange(x, y+1); 
            ButtonChange(x-1, y);
            ButtonChange(x+1, y);
         }
         else 
         {
            button[x][y].setEnabled(false);
            button[x][y].setText(Integer.toString(num));
         }
      }
   }

   public int CheckMine(int x, int y)
   {  
      int num = 0;
      if (x >= 0 && y >= 0 && x < button.length && y < button.length)
      {
         if (status[x][y] == 1)
         {
            num = 1;
         }
      }
      return num;
   }
}

这是我的代码,我还没有完成,因为我还没有制定检查获胜的方法。 主程序在另一个类。 我收到了一个错误:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError 
at javax.swing.JComponent.disable(JComponent.java:3638) 
at java.awt.Component.enable(Component.java:1517) 
at java.awt.Component.setEnabled(Component.java:1480) 
at javax.swing.JComponent.setEnabled(JComponent.java:2680) 
at    javax.swing.AbstractButton.setEnabled(AbstractButton.java:2091) 
at StartGame.ButtonChange(StartGame.java:104)
at StartGame.ButtonChange(StartGame.java:103)

当我尝试点击某个按钮时。 我不明白为什么,因为我检查它似乎是正确的。 它在ButtonChange函数中没有用于上下按钮更改但不是左右按钮。我只是不知道我的计划中发生了什么......

2 个答案:

答案 0 :(得分:1)

问题是你有一个按钮矩阵,你试图setEnabled(false)整个矩阵......你必须setEnable每个按钮显式...

<罢工>

尝试禁用两个for循环,如

for(int i = 0; i<9; i++){
  for(int j = 0 ; j<9; j++){
    button[i][j].setEnabled(false);
  }
}

<击>

修改

这不是问题......这个问题是因为你使用了递归性而导致的...... ButtonChange方法本身被称为太深了......让我们说是第一个调用的参数是(2,2)......该方法将自己调用(2,1)然后调用(2,0),然后调用(2,-1)然后调用(2,3)并启动再次使用(2,2)然后(2,1)......这样就会出现stackOverFlow错误

如果你放了一个System.out.println(&#34; X =&#34; + x +&#34;和Y =&#34; + y);在方法的第一行,再试一次,你会看到问题......

更新:

问题出在你的方法ButtonChange(int x,int y)中,因为你在那里用递归方法调用带有创建无限调用的参数的方法......让我给你看一个例子,以便让我理解

递归的一个例子是斐波纳契系列......我可以创建下一个代码来找出某个系列的值:

 public int fibonacci(int value){
     if(value == 1 || value == 2){
         return 1;
     }else{
         return fibonacci(value-1)+fibonacci(value-2);
     }
 }

如果我想知道值为4的系列值:

fibonacci(4)=3

但请检查下一个代码:

public int fibonacci(int value){
    if(value == 1 || value == 2 || value > 8){
        return 1;
    }else{
        return fibonacci(value-1)+fibonacci(value+1);
    }
}

检查方法我用#34; value-1&#34;递归调用方法。和&#34;值+ 1&#34;

现在,如果我想知道值为4的系列值:

f(4)=Error

在这一点上,如果你仔细观察我们有f(3)= f(2)+ f(4)和f(5)= f(4) + f(6)如果你还记得 f(4)是函数的初始值,那么这意味着现在原始函数出现在迭代中。这不仅使得在每次调用方法时递归都更大,而且迭代永远不会结束......所以最终会生成java.lang.StackOverFlow错误

当你在函数内部执行时,你在函数ButtonChange中有类似的行为

ButtonChange(x,y-1);
ButtonChange(x,y + 1);
ButtonChange(x-1,y);
ButtonChange(x + 1,y);

答案 1 :(得分:0)

似乎你在递归时无限期地左右跳跃。添加有关单元状态(已发现/未发现)的信息就足够了:

private Boolean[][] checked = new Boolean[9][9];

或使用按钮状态。然后修改主要条件:

if (x >= 0 && y >= 0 && x < button.length && y < button.length && !checked[x][y])

if (x >= 0 && y >= 0 && x < button.length && y < button.length && !button[x][y].isEnabled())

然后它应该工作。