java - 使用 ImageIcons 在 Java 中编程 Tic Tac Toe - WinningCondition

标签 java eclipse imageicon

我需要帮助,因为我是 Java 编程的初学者。 我现在正在为大学编写 Tic Tac Toe 程序,但遇到了一些问题,因为我想使用一些笑脸而不是 X 和 O。但我不知道如何通过搜索获胜者来比较它们,所以我使用了字母。但你可以在 Playground 上看到这些字母和笑脸,我认为这不是最好的解决方案。也许你们中的一些人对我的程序有更好的建议和评论。我将图像 Devil.png 和 sun.png 复制到了 TicTacToe src 文件夹中。

    import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

public class Gui implements ActionListener {

    // Variables
    private static int[][] winCombos = new int[][] //Possible win combinations
            {
                {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, //horizontal wins
                {0, 3, 6}, {1, 4, 7}, {2, 5, 8}, //vertical wins
                {0, 4, 8}, {2, 4, 6}             //diagonal wins
            };

    static JButton btn[] = new JButton[9];
    private int count = 0;
    private int xscore = 0;
    private int oscore = 0;
    private String letter = "";
    private boolean win = false;
    private ImageIcon devil; // devil= spieler X
    private ImageIcon sun; // sun = spieler O

    public Gui() {

        // Create Window
        JFrame jf = new JFrame();

        jf.setSize(400, 400);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setLocationRelativeTo(null);
        jf.setResizable(false);
        jf.setTitle("Tic-Tac-Toe Playfield");
        jf.setLayout(new GridLayout(3, 3));
        devil = new ImageIcon(getClass().getResource("devil.png")); //X
        sun = new ImageIcon(getClass().getResource("sun.png")); //O

        // Add Buttons to the Window
        for (int i = 0; i < btn.length; i++) {
            btn[i] = new JButton();
            btn[i].setVisible(true);
            btn[i].setFocusPainted(false);
            btn[i].addActionListener(this);
            jf.add(btn[i]);
        }
        jf.setVisible(true);
    }

    public void actionPerformed(ActionEvent a) 
    {
            count++;

            //Who's turn is it 
            if(count % 2 == 0)
            {
                letter = "O";
                oscore++;
            }
            else
            {
                letter = "X";
                xscore++;
            }

            //Change button to letter
            if(letter == "X")
            {
                JButton pressedButton = (JButton)a.getSource();
                pressedButton.setIcon(devil);
                pressedButton.setEnabled(false);
            }
            else if(letter == "O")
            {
                JButton pressedButton = (JButton)a.getSource();
                pressedButton.setIcon(sun);
                pressedButton.setEnabled(false);
            }

            //Search for Winner
            for(int i=0; i<=7; i++)
            {
               if(btn[winCombos[i][0]].getIcon() !=null &&
                       btn[winCombos[i][0]].getIcon().equals(btn[winCombos[i][1]].getIcon()) && 
                       btn[winCombos[i][1]].getIcon() !=null && 
                               btn[winCombos[i][1]].getIcon().equals(btn[winCombos[i][2]].getIcon())

                       )

                {
                    win = true;
                }
            }


            //Dialog at the end of the game
            if(win)
            {
                JOptionPane.showMessageDialog(null, letter + " wins the game");
                System.exit(0);
            }
            else if(count == 9 && !win)
            {
                JOptionPane.showMessageDialog(null, "There is no winner.");
                System.exit(0);
            }               
    }}

最佳答案

这里有 MadProgrammers 的建议

Step back for a moment. You need to do is separate the logic from the presentation, this allows you to consistently model the logic and allow the presentation to present in whatever form it wants to. This is the basic functionality of the "model-view-controller" paradigm. With this, you model your data (the game and it's state) and then allow the view (the UI) to present it in what ever manager it wants to. This means the logic for determining when a player wins a game is determined by the model

绝对是正确的方法,也是您应该考虑设计 future 项目的方式。不过,我假设您可能尚未在类(class)中介绍 MVC 和其他设计模式。

您现在遇到的问题将是循环中的 NullPointerException ,因为第一次单击时,大多数按钮都不会分配图标,因此当您尝试调用 .equals( ) 在该空对象上发生异常。

因此,简单的修复方法是您需要先检查空图标,然后才能进行相等性检查。

编辑在调用 equals 之前!

if(btn[winCombinations[i][0]].getIcon() != null && 
   btn[winCombinations[i][0]].getIcon().equals(....

您还需要对 btn[winCombinations[i][1]].getIcon() 执行此操作

结束编辑

更简洁的方法可能是使用 Objects.equals()如果可以的话,方法

解释更多:当异常发生时,方法会中断 - 因此它发生在 for 循环中,因此下面的代码将不会被执行。尝试在循环下方添加以下内容:

System.out.println("Reached here!");

您会注意到,只有按下所有按钮后才会打印它。

为了帮助您更直观地检查,您可以在循环周围添加一个 try catch - 请注意,这不是理想的操作 - 但会帮助您更直观地诊断问题。

try
{
    // your win check loop
}
catch (Exception e)
{
    e.printStackTrace();
    JOptionPane.showMessageDialog(null, "Oh no!:\n" + e);
}

关于java - 使用 ImageIcons 在 Java 中编程 Tic Tac Toe - WinningCondition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44664041/

相关文章:

java - Mule Flow 中的选择

android - 在 Eclipse 中持久设置 Android 项目的默认名称

java - 为什么 ImageIcon 不起作用?

java - 为什么 setIcon 不在 JButton 上显示图像?

java - 在java中以编程方式删除图像文件后,ImageIcon显示路径中删除的文件

java - 如何将 ArrayList 拆分为多个列表?

java - 使用 Jsp 页面中的 IP 地址连接到 HP 扫描仪

java - 为什么增强的 for 循环不执行空值检查

java - 从 Eclipse 导出可运行的 JAR 时遇到问题

eclipse - 如何在 Eclipse 中选择引号内的文本?