私はGUI TicTacToeゲームを何年も前に作りました。コードを600行から約150行に縮小することができました。Java TicTacToeプログラムは、勝ち組合以外の組み合わせで起動します
私は同じスキームを使用していましたが、私は自分で解決できないいくつかの問題に遭遇しましたので、私を助けてください。
プログラムは、2つのクラス、メインクラス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 で作られています。ボタンはというラベルで比較されたであるため、ゲームの開始時に一致するラベルを持たないように、ボタンは作成時に1から9のラベルが付いています。ここでは:あなたがbtnPlayButton
をクリックするたびに
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]);
}
、プログラムはactionPerformed
メソッドにジャンプします。 btnPlayButtons
にはActionCommand
がないため、メソッドのelseセクションにジャンプします。ここでは、int buttonCounter
は1だけ大きくなります.Wether buttonCounter
は偶数または奇数です。クリックされたbtnPlayButtonは、 "X"または "O"でラベル付けされます。 buttonCounter
はクリックごとに+1を取得するため、XとOは交互に表示されます。クリックしたボタンの
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()
で 、またはより正確に、btnPlayButtons[x]
、btnPlayButtons[y]
、btnPlayButtons[z]
のButtonsWithIdenticalLabels(x, y, z)
ラベルは、それらが同一である場合、それは真を返し、採取し、比較することができます。 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]
は、審美的には赤色に塗りつぶされます。
Restartボタンを使用すると、forループにジャンプして、btnPlayButtonを再度ラベル付けし、TTTFrameに実装されているActionListener
を追加します。 buttonCounter
も0にリセットされています。再ラベリングは、クラスの初めに1と同じです。
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行のOと時にはフィールドは次のようにありますが認識し得ている
に勝つ誰かがこのバグを修正する方法を知っているかのように私は本当に幸せになると思います。事前に
おかげで、
Fihdi
質問でこの多くのコードを使用すると、ここで助けを得ることはあまりありません。すでに自分でデバッグしようとしましたか?それはあなたがバグを見つけ、ここでより具体的な質問に戻ってくるのを助けるはずです。 –
ようこそスタックオーバーフロー! [ツアー](ツアー)を見て回り、[ヘルプセンター](/ help)、特に[どのように良い質問をしますか?](/ help/how-to-質問)と[ここではどのような話題について聞くことができますか?](/ help/on-topic) [Java命名規則](http://www.oracle.com/technetwork/java/codeconventions-135099.html) –
https://ericlippert.com/2014/03/05/howをお読みください-to-debug-small-programs/ – slim