我需要帮助,因为我是 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/