【问题标题】:TicTacToe win conditions problems井字游戏获胜条件问题
【发布时间】:2013-07-12 08:42:41
【问题描述】:

这里是新程序员,在 Eclipse 上使用 Java 编写一个 Tictactoe 游戏。

我认为我的获胜条件有问题。它出现了错误: 线程“主”java.lang.NullPointerException 中的异常 在 Game.NoughtsCrosses.(NoughtsCrosses.java:106) 在 Game.Main.main(Main.java:5)

这是我的获胜条件。 imo制作得不好,但是我在编译时遇到了问题。谁能发现为什么?太棒了!!

我在 3x3 网格中设置了正方形,0 -> 8。每个按钮都有自己的文本,当每个玩家单击时,它们会设置为 X 或 O。

win条件代码:

if (square[0].getText().equals(square[1].getText()) && square[1].getText().equals(square[2].getText()) != square[0].getText().isEmpty()) {
    win = true;
}

Full Pastebin of code

再次感谢 :) 有任何问题,我可以详细说明 :D

【问题讨论】:

  • 1) 标题中无需添加主要标签。 2) 为了尽快获得更好的帮助,请发帖SSCCE
  • 仅供参考,这实际上是运行时错误而不是编译时错误
  • 只是想让你知道我在下面更新了我的答案。

标签: java nullpointerexception tic-tac-toe


【解决方案1】:

看起来其中一个方块文本为空。需要记住的重要一件事是空字符串与 null 不同。在 java 中,如果您没有专门为 String 分配值,那么它将为空。要解决此问题,您需要在设置游戏板时将每个方块文本显式设置为 ""(一个空字符串)。

【讨论】:

  • OP 说“每个按钮都有自己的文本,当每个玩家单击时,该文本设置为 X 或 O。”这可能意味着您是正确的,并且它是导致问题的未点击按钮之一。
  • @rossum 是的,加上 java.lang.NullPointerException 让我相当有信心这是问题所在
【解决方案2】:

好吧,我采用了您提供的代码,经过大量修改后,我能够制作出功能齐全的井字游戏。您所做的大部分工作都在正确的轨道上,您只需要首先从设计开始。

在我的 NoughtsCrosses 课程中,我有以下内容:

  • 类 Action 实现 ActionListener
    • 这有一个我通过构造函数传入的 JButton 属性
    • 在actionPerformed中
      • 设置文字
      • 禁用按钮
      • 增加计数器
      • 检查是否有人获胜
        • 如果有赢家或平局游戏结束,请设置“再玩一次?”文字
        • 否则调用 changeTurn 函数
  • 类Reset实现ActionListenter
    • 这有一个我通过构造函数传入的 JButton 属性
    • 在actionPerformed中
      • 我调用了 resetGame 函数
  • 功能变化转
  • 功能重置游戏
  • 函数 checkForWinners

作为提示,这是我对 Action 类的实现和我提到的构造函数的示例

class Action implements ActionListener{ 
 private JButton button;
 public Action(JButton button){ 
  this.button = button; 
 } 
 public void actionPerformed(ActionEvent e) { 
   button.setText(letter); 
   button.setEnabled(false); 
   counter++; 
   boolean gameOver = checkForWinners(); 
   if(!gameOver) 
    changeTurn(); 
   else{ 
    newgame.setText("Play again?"); 
    newgame.addActionListener(resetButton); 
   } 
 } 
}

new Action(square[i]) 这样的电话是您完成这项工作所需要的。 注意:resetButton 属于我上面提到的Reset 类,很像Action 类,它具有与我传递newgame 相同的构造。

【讨论】:

  • 这里是您想要的程序的基本设计。正如我所说,我有一个完整的工作版本,所以如果你对实现它有疑问,请询问我
  • 非常感谢,您是救生员 :D 您是否对 GUI 进行了很多更改,或者一切看起来都很好?您是将按钮保留在一维数组中还是将其更改为两个多维数组?
  • 我将它们保存在一个一维数组中。我在 GUI 上唯一更改的是添加缺少的 ActionListener 来重置游戏,其余的都很好!
  • 啊,好吧。至少我对 Swing 没问题:P 好的,我一直在搞砸,现在似乎可以工作了。原谅菜鸟问题,但我可以让游戏输入一个正方形,将其更改为 X,但它不会反击 ++(我认为,没有玩家更改)并且无法选择另一个按钮。我可以问一下你是如何处理你的函数 changeTurn 的吗?抱歉,我是新手:D
  • 没问题。在我的实现中,我增加了 Action 类中的计数器,然后我检查了获胜者或平局,然后调用了 changeTurn,其中包含您编写的代码:if (counter % 2 == 0){ player = 1; letter = "X"; } else{ player = 2; letter = "O"; } playergo.setText("It is Player " + player + "'s Turn");
【解决方案3】:

您的获胜条件检查似乎不在您的 actionPerformed 代码中,而是在类级别,因此它可能在窗口被您的按钮填充之前被调用。

尝试将支票放在actionPerformed 中,如下所示:http://pastebin.com/xRViSUzy

【讨论】:

    【解决方案4】:

    什么是范围(最简单地说,是哪个花括号)是里面有问题的行?

    根据您的缩进来判断有点棘手,但在我看来,您的“if”不在方法内(例如构造函数)。我猜想您打算在初始化正方形的构造函数主体中的行之后执行此行及其周围的行。相反,这些行是预先运行的,因此对“new”的调用还没有运行。

    我认为,如果您进行一些重组以将这些条件移动到您的构造函数中,或者移动到构造函数之后 调用的另一个方法中,那么事情看起来会好很多。

    希望对您有所帮助。

    【讨论】:

      【解决方案5】:

      如果您要实施此类解决方案,请自行简化工作。根据我在上面看到的微小的 sn-p 代码,看起来你真的让你必须做的工作过于复杂了。

      char cell0 = //get that char, be it X or O
      char cell1 = //
      ...
      char cell8 = //
      

      现在您可以逐个比较单元格以确定胜利。您的棋盘游戏设置如下:

      0 1 2
      3 4 5
      6 7 8
      

      所以你可以按顺序进行:

      Horizontal Solutions:
      (cell0 == cell1 && cell0 == cell2)
      (cell3 == cell4 && cell3 == cell5)
      (cell6 == cell7 && cell6 == cell8)
      
      Vertical Solutions
      (cell0 == cell3 && cell0 == cell6)
      //And so on
      
      Cross Solutions:
      (cell0 == cell4 && cell0 == cell8)
      (cell2 == cell4 && cell2 == cell6)
      

      这将检查你的胜利条件。

      【讨论】:

        【解决方案6】:

        问题是您的代码中有多余的大括号,因此问题中的语句实际上出现在 NoughtsCrosses 类的实例初始化程序块中,但没有一个 JButton 组件已被初始化为实例初始化器被调用 before 构造函数,这是 JButton 实例化存在的地方(但从未调用过)。当您尝试在数组square 的第一个元素上调用getText 时, NullPointerException 被抛出。

        修复删除前面ActionListener中包含的代码的附加大括号

        class Action implements ActionListener {
            public void actionPerformed(ActionEvent e) {
               // existing code here
        /// }    remove
        //}      remove
        // {     remove
        
            // win conditions. if true, set win==true; else set win
            // here is where the compilation error is, next line
            if (square[0].getText() == square[1].getText() ...) { 
              win = true;
            } //etc
        } <-- add this
        

        【讨论】:

        • 谢谢!刚刚摆脱了那些。现在它加载正常,又出现一两个错误,但至少我可以看到现在发生的事情并开始处理它。再次感谢你:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多