幾年前,我做了一個GUI TicTacToe遊戲,想重做它,因爲我現在有更多的編程技巧。我能夠將代碼從600行縮減到大約150行。Java TicTacToe程序觸發非贏組合
雖然我使用了相同的方案,但遇到了一些我無法解決的問題,請幫助我。
該計劃包括兩個類,主類TTTMain
的:
public class TTTMain {
public static void main(String[] args) {
TTTFrame tttf = new TTTFrame(0,0);
/*Tic Tac Toe Field:
* 0 1 2
* 3 4 5
* 6 7 8
*/
}}
而且TTTFrame
:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TTTFrame extends JFrame implements ActionListener {
private Button[] btnPlayButton;
private Button btnRestart;
private int buttonCounter;
private int xScore;
private int oScore;
private Label Olabel, Xlabel;
TTTFrame(int xScore, int oScore) {
this.xScore = xScore;
this.oScore = oScore;
btnPlayButton = new Button[9];
for (int i = 0; i < 9; i++) {
btnPlayButton[i] = new Button("" + i);
btnPlayButton[i].setBackground(Color.white);
btnPlayButton[i].setForeground(Color.white);
btnPlayButton[i].addActionListener(this);
this.add(btnPlayButton[i]);
}
Xlabel = new Label("X: " + this.xScore);
Xlabel.setFont(new Font("Arial", Font.BOLD, 24));
Xlabel.setForeground(Color.white);
Xlabel.setBackground(Color.black);
this.add(Xlabel);
btnRestart = new Button("Restart");
btnRestart.setActionCommand("Restart");
btnRestart.setFont(new Font("Arial", Font.PLAIN, 18));
btnRestart.addActionListener(this);
this.add(btnRestart);
Olabel = new Label("O: " + this.oScore);
Olabel.setFont(new Font("Arial", Font.BOLD, 24));
Olabel.setForeground(Color.white);
Olabel.setBackground(Color.black);
this.add(Olabel);
this.setLayout(new GridLayout(4, 3));
this.pack();
this.setResizable(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Tic Tac Toe");
this.setSize(300, 400);
this.getContentPane().setBackground(Color.black);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Restart")) {
System.out.println("Restarted");
for (int i = 0; i < 9; i++) {
btnPlayButton[i].setLabel("" + i);
btnPlayButton[i].setForeground(Color.white);
btnPlayButton[i].setBackground(Color.white);
btnPlayButton[i].addActionListener(this);
this.buttonCounter = 0;
}
} else {
((Button) e.getSource()).setFont(new Font("Arial", Font.BOLD, 48));
((Button) e.getSource()).setForeground(Color.black);
System.out.println(buttonCounter);
if (buttonCounter % 2 == 0) {
((Button) e.getSource()).setLabel("X");
((Button) e.getSource()).removeActionListener(this);
} else {
((Button) e.getSource()).setLabel("O");
((Button) e.getSource()).removeActionListener(this);
}
buttonCounter++;
CheckField();
}
}
private void CheckField() {
if (ButtonsWithIdenticalLabels(0, 1, 2)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(3, 4, 5)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(6, 7, 8)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(0, 3, 6)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(1, 4, 7)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(2, 5, 8)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(0, 4, 8)) {
Deactivatebuttons();
}
if (ButtonsWithIdenticalLabels(2, 4, 6)) {
Deactivatebuttons();
}
}
private boolean ButtonsWithIdenticalLabels(int i, int j, int k) {
if (btnPlayButton[i].getLabel() == btnPlayButton[j].getLabel()
&& btnPlayButton[j].getLabel() == btnPlayButton[k].getLabel()) {
btnPlayButton[i].setBackground(Color.red);
btnPlayButton[j].setBackground(Color.red);
btnPlayButton[k].setBackground(Color.red);
if (btnPlayButton[i].getLabel().equals("X")) {
xScore++;
Xlabel.setText("X: " + xScore);
} else {
oScore++;
Olabel.setText("O: " + oScore);
}
return true;
} else {
return false;
}
}
private void Deactivatebuttons() {
for (int i = 0; i < 9; i++) {
btnPlayButton[i].removeActionListener(this);
}
}
}
現在讓我解釋的程序是如何工作的。 3x3運動場由ButtonArray btnPlayButton
組成。這些按鈕是,它們的標籤相比較,因此在遊戲開始時沒有匹配的標籤,創建時按鈕從1到9正確標記。在這裏:
for (int i = 0; i < 9; i++) {
btnPlayButton[i] = new Button("" + i); // Right here
btnPlayButton[i].setBackground(Color.white);
btnPlayButton[i].setForeground(Color.white);
btnPlayButton[i].addActionListener(this);
this.add(btnPlayButton[i]);
}
每當你點擊一個btnPlayButton
,程序跳轉到actionPerformed
方法。由於btnPlayButtons
沒有ActionCommand
,因此它跳轉到方法的else部分。在這裏,int buttonCounter
得到大於1. Wether buttonCounter
是偶數或奇數,被點擊的btnPlayButton被重新標記爲「X」或「O」。由於buttonCounter
每次點擊都獲得+1,所以X和Os是交替的。
據說這裏部分:
else {
((Button) e.getSource()).setFont(new Font("Arial", Font.BOLD, 48));
((Button) e.getSource()).setForeground(Color.black);
System.out.println(buttonCounter);
if (buttonCounter % 2 == 0) {
((Button) e.getSource()).setLabel("X");
((Button) e.getSource()).removeActionListener(this);
} else {
((Button) e.getSource()).setLabel("O");
((Button) e.getSource()).removeActionListener(this);
}
buttonCounter++;
CheckField();
}
的將點擊的按鈕ActionListener
被刪除,以防止作弊。每按下一次按鈕,比賽場地都會被檢查獲勝組合。這發生在CheckField()
。
在CheckField()
,或者更準確地說,ButtonsWithIdenticalLabels(x, y, z)
的的btnPlayButtons[x]
,btnPlayButtons[y]
,btnPlayButtons[z]
採取比較,如果相同則返回true標籤。
由於btnPlayButton排序是這樣的:
0 1 2
3 4 5
6 7 8
獲勝組合是:012,345,678,036,147,258,045和246
如此,例如,當btnPlayButton[0]
,btnPlayButton[1]
和btnPlayButton[2]
都具有相同的標籤。 ButtonsWithIdenticalLabels
是真的,程序跳轉到Deactivatebuttons()
所有btnPlayButton
都被禁用,意味着獲勝的組合被發現,遊戲結束。如果btnPlayButton[1]
的標籤是「X」,那麼int xScore
將被添加1。另外btnPlayButton[0]
,btnPlayButton[1]
和btnPlayButton[2]
被塗成紅色以增加美感。
使用重新啓動按鈕,您跳入一個for循環,該循環再次重新標記btnPlayButton並將它們添加到實現到TTTFrame中的ActionListener
。 buttonCounter
也重置爲0。該重新貼標籤是一樣的一個在類的開頭:
if (e.getActionCommand().equals("Restart")) {
System.out.println("Restarted");
for (int i = 0; i < 9; i++) {
btnPlayButton[i].setLabel("" + i);
btnPlayButton[i].setForeground(Color.white);
btnPlayButton[i].setBackground(Color.white);
btnPlayButton[i].addActionListener(this);
this.buttonCounter = 0;
}
現在的問題是,我是,那幾個重新啓動後,X和O的標籤不交了。有時也有3個OS在一排,有時甚至字段這樣越來越公認的奪冠
如果有人知道如何解決這個錯誤,我會很高興。
由於提前,
Fihdi
有了這個問題的代碼很多,你不太可能在這裏得到幫助。你是否試圖自己調試它?這應該可以幫助您找到錯誤,並在此處回答更具體的問題。 –
歡迎來到Stack Overflow! 請參考[遊覽](/遊覽),環顧四周,閱讀[幫助中心](/幫助),特別是[如何提出一個好問題?](/ help/how-to-問)和[我可以在這裏問什麼問題?](/幫助/話題)。請閱讀(並遵循) [Java命名約定](http://www.oracle.com/technetwork/java/codeconventions-135099.html) –
https://ericlippert.com/2014/03/05/how -to-debug-small-programs/ – slim