Я написал программу Reversi, которая делает графический интерфейс, заполненный 2d массивом кнопок.Есть несколько методов, в том числе validMoves (), который делает правильные ходы setEnabled (true);и показывает красную точку, чтобы пользователь знал, какие кнопки активны.он также переворачивает правильные плитки, когда вы выбираете, какую плитку вы хотите переместить.Проблема, с которой я сталкиваюсь, заключается в том, что графический интерфейс не ждет, когда игрок сделает ход.я написал ai, который в основном совпадает с игроком, который находит действительные ходы, находит, какой из них перевернет большинство плиток, и вернет его в формате "x * y", который мой метод затем подставит в x и y и сделаетдвигаться и перевернуть плитки.я попробовал thread.sleep () и wait () и некоторое время (! hasMoved) и кучу других вещей, с которыми он просто не хочет сотрудничать.с wait () я сталкиваюсь с бесконечным циклом bc, графический интерфейс есть, но в нем ничего нет.однако, когда я комментирую ожидание, оно показывается точно так, как должно.
package reversi;
/*
* bugs need to make it check the edges too // it goes out of bounds
* refresh scores doesnt work
*
* add clear all readys after someone does a move
*/
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JApplet;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Timer;
/**
* @author 13ponchera
* the board for reversi that will play the game
*/
public class ReversiBoard extends JApplet
{
private int score1;
private int score2;
private int turn;
private Icon p1 = new ImageIcon("images/p1.png");
private Icon p2 = new ImageIcon("images/p2.png");
private Icon bGround = new ImageIcon("images/bGround.png");
private Icon ready = new ImageIcon("images/ready.png");
// will help the action listener determin which players turn it is
private int x; // the number of buttons
private JButton[][] buttons;
private JPanel settingPanel =
new JPanel();
private JButton newGame =
new JButton("New Game?");
private JLabel score1A;
private JLabel score2A;
private JPanel gameBoard =
new JPanel();
private AI ai = new AI(bGround,p1,p2);
private boolean hasMoved;
private Timer t;
/**
* Initialization method that
* will be called after the applet is loaded
* into the browser.
* sets up everything
*/
public void init()
{
score1 = 0;
score2 = 0;
// sets the viewer to say the score
score1A = new JLabel("Player: " + score1);
score2A = new JLabel("Computer:" + score2);
//adds components to the setting panel
settingPanel.add(newGame);
newGame.addActionListener(new NewGameListener());
settingPanel.add(score1A);//initialized at 0
settingPanel.add(score2A);
//creates a game board of any size as long as it is an even number
String a = JOptionPane.showInputDialog
(null, "please enter an even integer for x");
x = Integer.parseInt(a) + 2;
if ((x % 2 == 0) && (x > 4))
{
gameBoard = new JPanel(new GridLayout(x, x, 4, 4));
buttons = new JButton[x][x];
}// add 2 to x then set the edges to a new picture
else
{
//asks for a new number untill number is even
while ((x % 2 != 0) && (x < 4))
{
String responce = JOptionPane.showInputDialog
(null, "Must be an even "
+ "number rows and collums \n\tplease enter x");
x = Integer.parseInt(responce) + 2;
}
gameBoard = new JPanel(new GridLayout(x, x, 4, 4));
buttons = new JButton[x][x];
}
//creates the buttons for each slot and puts them into a 2d array
for (int c = 0; c < x; c++)
{
for (int d = 0; d < x; d++)
{
buttons[c][d] = new JButton();
buttons[c][d].setIcon(bGround);
// adds the background default pict
buttons[c][d].addActionListener
(new ButtonListener(buttons[c][d],c,d));
// adds a generic button listener
buttons[c][d].setEnabled(false);
// the buttons are non clickable except for the valid moves
gameBoard.add(buttons[c][d]);
buttons[c][d].setIcon(bGround);
buttons[c][d].setDisabledIcon(bGround);
// adds the buttons to the jpanel
}
}
//makes the edges a different color
// adds the jpanel with all of the buttons into the content pane
buttons[x/2][x/2]
.setIcon(p1);
buttons[x/2][x/2]
.setDisabledIcon(p1);
buttons[(x/2) - 1][(x/2) - 1]
.setIcon(p1);
buttons[(x/2) - 1][(x/2) - 1]
.setDisabledIcon(p1);
refreshTable();
// makes the middle upper left and lower right white pieces
buttons[(x/2) - 1][(x/2)]
.setIcon(p2);
buttons[x/2][(x/2) - 1]
.setIcon(p2);
buttons[(x/2) - 1][(x/2)]
.setDisabledIcon(p2);
buttons[x/2][(x/2) - 1]
.setDisabledIcon(p2);
refreshTable();
// makes the midle upper right and lower left black pieces
getContentPane()
.add(gameBoard, BorderLayout.CENTER);
getContentPane();//burp the applet
// after two days of hitting my head on the keyboard
getContentPane()
.add(settingPanel, BorderLayout.SOUTH);
//adds the setting panel (new game button
//and scores to the content pane)
refreshTable();
t = new Timer();
hasMoved = false;
validMoves();
refreshTable();
synchronized(t)
{
while(!hasMoved)
{
try
{
t.wait(50);
}
catch (InterruptedException ex)
{
Logger.getLogger(ReversiBoard.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}
refreshTable();
aiTurn();
// make the edges a different picture
}
/**
* refreshes the table so that pictures will appear
*/
public void refreshTable()
{
for (int a = 0; a < x; a++)
{
for (int b = 0; b < x; b++)
{
buttons[a][b].repaint();
}
}
setScores();
score1A.setText
("Player: " + score1);
score2A.setText
("Computer: " + score2);
gameBoard.repaint();
settingPanel.repaint();
}
/**
* finds all the valid moves and sets the
* buttons enabled and gives them an identifiable picture
*/
public void validMoves()
{
int c = 0;
int d = 0;
// temperary values so search can go on uninterupted
for(int a = 1; a < x - 1; a++)
{
for(int b = 1; b < x - 1; b++)
{
//looks at every tile
if (buttons[a][b].getIcon() ==bGround)
{
//if it is a background child look to
//see if there is an enemy peace adjacent
if (buttons[a + 1][b].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = a + 1;
while ((buttons[c][b].getIcon() == p2)
&& (c < x)
&& (c > 0))
{
if (buttons[c + 1][b].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
//JOptionPane.showMessageDialog(null,"");
}
c++;
}
}
//see if there is an enemy peace adjacent
if (buttons[a - 1][b].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = a - 1;
while ((buttons[c][b].getIcon() == p2)
&& (c < x)
&& (c > 0))
{
if (buttons[c - 1][b].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
//JOptionPane.showMessageDialog(null,"");
}
c--;
}
}
if (buttons[a][b + 1].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = b + 1;
while ((buttons[a][c].getIcon() == p2)
&& (c < x)
&& (c > 0))
{
if (buttons[a][c + 1].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
//JOptionPane.showMessageDialog(null,"");
}
c++;
}
}
if (buttons[a][b - 1].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = b - 1;
while ((buttons[a][c].getIcon() == p2)
&& (c < x)
&& (c > 0))
{
if (buttons[a][c - 1].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
//JOptionPane.showMessageDialog(null,"");
}
c--;
}
}
//starts checking diagonals
if (buttons[a + 1][b + 1].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = a + 1;
d = b + 1;
while ((buttons[c][d].getIcon() == p2)
&& (c < x)
&& (c > 0)
&& (d < x)
&& (d > 0))
{
if (buttons[c + 1][d + 1].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
// JOptionPane.showMessageDialog(null,"");
}
c++;
d++;
}
}
if (buttons[a - 1][b - 1].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = a - 1;
d = b - 1;
while ((buttons[c][d].getIcon() == p2)
&& (c < x)
&& (c > 0)
&& (d < x)
&& (d > 0))
{
if (buttons[c - 1][d -1].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
//JOptionPane.showMessageDialog(null,"");
}
c--;
d--;
}
}
if (buttons[a - 1][b + 1].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = a - 1;
d = b + 1;
while ((buttons[c][d].getIcon() == p2)
&& (c < x)
&& (c > 0)
&& (d < x)
&& (d > 0))
{
if (buttons[c - 1][d + 1].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
// JOptionPane.showMessageDialog(null,"");
}
c--;
d++;
}
}
if (buttons[a + 1][b - 1].getIcon() == p2)
{
// keeps checking that direction
//until it runs to the end of the
//board or hits an ally
// c is the cordinates of where it finds
c = a + 1;
d = b - 1;
while ((buttons[c][d].getIcon() == p2)
&& (c < x)
&& (c > 0)
&& (d < x)
&& (d > 0))
{
if (buttons[c + 1][d - 1].getIcon() == p1)
{
buttons[a][b].setEnabled(true);
buttons[a][b]
.setIcon(ready);
// JOptionPane.showMessageDialog(null,"");
}
c++;
d--;
}
}
}
}
}
refreshTable();
/*try
{
Thread.sleep(50); // 30 seconds NA
}
catch (InterruptedException ex)
{
Logger.getLogger(ReversiBoard.class.getName())
.log(Level.SEVERE, null, ex);
}*/
}
/**
* calculates the scores of each player
*/
/**
*
* @return boolean if game is over
*/
public boolean winner()
{
refreshTable();
if (!anyMove(1) && !anyMove(0))
return true;
//joptionpan the winner (if score1 > score 2).... and vv
return false;
}
/**
* @param player 1 for player 1 for computer
* @return boolean if there is a move
*/
public void clearReady()
{
for (int a = 0; a < x; a++)
{
for (int b = 0; b < x; b++)
{
if (buttons[a][b].getIcon() == ready)
{
buttons[a][b].setIcon(bGround);
buttons[a][b].setEnabled(false);
buttons[a][b].setDisabledIcon(bGround);
}
}
}
}
private void makeMove(String move)
{
int temp = 0;
char[] f = move.toCharArray();
for(int i = 0; i < f.length; i++)
{
if (f[i] == ('*'))
temp = i;
}
int x = Integer.parseInt(move.substring(0,temp));
int y = Integer.parseInt(move.substring(temp + 1));
buttons[x][y].setIcon(p2);
buttons[x][y].setEnabled(false);
buttons[x][y].setDisabledIcon(p2);
flip(1,x,y);
}
private void aiTurn()
{
String move = ai.makeMove(buttons);
// string move is a string with cordinates seperated by a *
makeMove(move);
turn++;
}
class ButtonListener implements ActionListener
{
private JButton a;
private int x;
private int y;
private ButtonListener(JButton jButton, int c, int d)
{
a = jButton;
x = c;
y = d;
}
public void actionPerformed(ActionEvent e)
{
//must differentiate between p1 and p2
switch (turn % 2)
{
case 0:
a.setIcon(p1);
a.setEnabled(false);
a.setDisabledIcon(p1);
flip(0,x,y);
turn++;
clearReady();
hasMoved = true;
/*synchronized(t)
{
t.notifyAll();
}*/
refreshTable();
break;
case 1:
a.setIcon(p2);
a.setEnabled(false);
a.setDisabledIcon(p2);
flip(1,x,y);
turn++;
clearReady();
hasMoved = true;
/*synchronized(t)
{
t.notifyAll();
}*/
refreshTable();
break;
}
}
}
}