我正在编写一个井字游戏,该游戏在玩家(用户点击按钮)和计算机玩家之间轮流。
我有一个调用的方法playersTurn()
,它需要等到JButton
在方法结束之前单击 a 并且计算机播放器轮到它。我已阅读有关使用线程和wait - notify
方法的信息,但我是 Java 新手,不知道如何实现这一点。
我想知道是否有更简单的方法来克服这个问题,或者这是唯一的方法,如果是这样,有人可以指导我找到一个好的教程吗?
谢谢
正如@HFOE 所说(对他+1),您不想将Thread
s 与notify一起使用并等待,这确实使事情变得过于复杂您的游戏逻辑在 IMO 上是有偏差的。
在开始游戏之前先制定一些框架:
JButton
秒(阵列将按住按钮)JPanel
用 aGridLayout(3,3)
创建井字游戏网格现在是重要的部分:
考虑到上述内容,请参阅我的示例,我所做的基础是在播放器离开后(单击按钮并设置播放ActionListener
器符号)后用于每个按钮的内部,我们调用cpu播放的方法:
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
public class Test {
//declare variables for player and cpu symbol
private String playerSymbol = "X";
private String cpuSymbol = "O";
//used for cpu to select random block
private Random r = new Random();
//create arraylist to hold buttons
ArrayList<JButton> blocks = new ArrayList<>();
//this is the action listner that will be added to each block and will allow player the first turn then cpu goes
private ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
//players turn
playerTurn(ae);
//check for win after player gone
checkForWin();
//cpu turn
cpuTurn();
//check for a win after cpu goes
checkForWin();
}
private void cpuTurn() {
System.out.println("CPU goes");
while (true) {
int blockNumber = r.nextInt(9);
System.out.println(blockNumber + "");
String tmp = blocks.get(blockNumber).getText();
if (tmp.equals("")) {
blocks.get(blockNumber).setText(cpuSymbol);
break;
}
}
}
private void checkForWin() {
System.out.println("Checking for a win...");
}
private void playerTurn(ActionEvent ae) {
System.out.println("Player goes");
JButton block = (JButton) ae.getSource();
block.setText(playerSymbol);
}
};
public Test() {
initComponents();
}
private void initComponents() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel board = new JPanel(new GridLayout(3, 3));//create gridlayput to hold buttons
//create blocks/Jbuttons to hold X and Y
createBlocks(blocks);
//add buttons/blocks to the board
fillBoard(blocks, board);
//add board to JFrame content pane
frame.add(board);
frame.pack();
frame.setVisible(true);
}
private void fillBoard(ArrayList<JButton> blocks, JPanel board) {
for (JButton block : blocks) {
board.add(block);
}
}
private void createBlocks(ArrayList<JButton> blocks) {
for (int i = 0; i < 9; i++) {
//create new button with a size of 50,50
JButton block = new JButton() {
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
};
block.addActionListener(al);//add the actionlistner to the button
blocks.add(block);
}
}
public static void main(String[] args) {
//set L&F and create UI on EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {//set L&F
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
//create UI
new Test();
}
});
}
}
你不应该等待并测试发生了什么,正确的方法是将监听器设置为按钮,例如在按钮单击后更改活动播放器。但是一切都取决于您的代码实施。