Java swing睡眠命令
我正在用人工智能创建一个棋盘游戏,我试图让人工智能选择放置游戏块的方块闪烁一两秒钟,然后再进行所选的移动。我的尝试如下: 线程。睡眠Java swing睡眠命令,java,swing,Java,Swing,我正在用人工智能创建一个棋盘游戏,我试图让人工智能选择放置游戏块的方块闪烁一两秒钟,然后再进行所选的移动。我的尝试如下: 线程。睡眠 button.setBackground(Color.pink); Thread.sleep(800); button.setBackground((new JButton()).getBackground()); Thread.sleep(800); button.setBackground(Color.pink); Thread.sleep(800); but
button.setBackground(Color.pink);
Thread.sleep(800);
button.setBackground((new JButton()).getBackground());
Thread.sleep(800);
button.setBackground(Color.pink);
Thread.sleep(800);
button.setBackground((new JButton()).getBackground());
Thread.sleep(800);
线程
Thread flash = new Thread(new ButtonFlashThread(button));
flash.start();
可调用
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Boolean> task = es.submit(new ButtonFlashThread(button));
计时器
Runnable flashON = new Runnable() {
public void run() { button.setBackground(Color.pink); } };
Runnable flashOFF = new Runnable() {
public void run() { button.setBackground((new JButton()).getBackground()); } };
javax.swing.SwingUtilities.invokeLater(flashON);
javax.swing.SwingUtilities.invokeLater(flashOFF);
javax.swing.SwingUtilities.invokeLater(flashON);
javax.swing.SwingUtilities.invokeLater(flashOFF);
ActionListener flashON = new ActionListener(){
public void actionPerformed(ActionEvent arg0){ button.setBackground(Color.pink); } };
ActionListener flashOFF = new ActionListener(){
public void actionPerformed(ActionEvent arg0) { button.setBackground((new JButton()).getBackground()); } };
int sleep = 800;
Timer timer = new Timer(sleep, flashON); timer.setRepeats(false); timer.start();
timer = new Timer(sleep, flashOFF); timer.setRepeats(false); timer.start();
timer = new Timer(sleep, flashON); timer.setRepeats(false); timer.start();
timer = new Timer(sleep, flashOFF); timer.setRepeats(false); timer.start();
Sleep命令冻结GUI,当按钮闪烁时,所有其他尝试都会继续执行代码。不是我想要的那样。我希望按钮闪烁,代码暂停,直到按钮闪烁完毕,然后才恢复。基本上,我正在寻找一种方法来完成以下工作:
//Find desired move (done)
//Flash the JButton a few times to indicate selected move
//Do following move (done)
正是按照这个顺序
编辑1:
下面的实现
private void flashButton(JButton button) {
class MoveTimerListener implements ActionListener {
private boolean flashOn = false;
private int count;
private int MAX_COUNT = 5;
private JButton button;
public MoveTimerListener(JButton b) {
button = b;
}
public void actionPerformed(ActionEvent e) {
flashOn = !flashOn;
if (count >= MAX_COUNT) { // MAX_COUNT is an int constant
// reached max -- stop timer
((Timer) e.getSource()).stop();
flashOn = false;
aiMove();
updateGUI();
}
if (flashOn)
button.setBackground(Color.yellow);
else
button.setBackground((new JButton()).getBackground());
count++;
}
}
Timer t = new Timer(5000, new MoveTimerListener(button));
t.start();
updateGUI();
}
在代码完成很久之后,当按钮仍在后台闪烁时,不要暂停代码并让其继续
编辑2:
我实现了您的示例,如下所示:
private void flashButton() {
_moveTimer = new Timer(100, new MoveTimerListener());
_moveTimer.start();
updateGUI();
}
private class MoveTimerListener implements ActionListener {
private boolean flashOn = false;
private int count;
@Override
public void actionPerformed(ActionEvent e) {
flashOn = !flashOn;
if (count >= 20) {
((Timer) e.getSource()).stop();
flashOn = false;
_gm.makeMove(aiMove[0], aiMove[1]);
}
if (flashOn) {
_boardButtons[aiMove[0]][aiMove[1]].setBackground(Color.yellow);
} else {
_boardButtons[aiMove[0]][aiMove[1]].setBackground((new JButton()).getBackground());
}
count++;
}
}
然而,代码似乎总是跳过actionPerformed方法。我做错什么了吗
编辑3:不是很小,但可以运行的程序。有问题的代码在第95-140行
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GameGUI extends JFrame implements MouseListener {
private GameManager _gm;
private JLabel[] _scores;
private JLabel[] _players;
private JPanel _contentPane;
private JButton[] _toolbarButtons;
private JButton[][] _boardButtons;
private Timer _moveTimer;
private int[] aiMove;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GameManager gm = new GameManager();
//gm.addPlayer(new Player("player", 2, 0));
gm.addPlayer(new Player("random", 2, 1));
gm.addPlayer(new Player("max kills ai", 1, 2));
gm.initBoard(8, 8);
GameGUI frame = new GameGUI(gm);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GameGUI(GameManager gm) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
_contentPane = new JPanel();
_boardButtons = new JButton[gm.getBoardSize()[0]][gm.getBoardSize()[1]];
_gm = gm;
addWindowGUI(_contentPane);
setContentPane(_contentPane);
aiMove();
updateGUI();
}
private void addWindowGUI(JPanel cp) {
cp.setLayout(new BoxLayout(_contentPane, BoxLayout.PAGE_AXIS));
JPanel gameInfo = new JPanel();
gameInfo.setLayout(new FlowLayout());
//Game grid
JPanel gameGrid = new JPanel();
int buttonSize = 40;
gameGrid.setLayout(new GridLayout(_gm.getBoardSize()[0], _gm.getBoardSize()[1]));
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++) {
_boardButtons[i][j] = new JButton();
_boardButtons[i][j].setPreferredSize(new Dimension(buttonSize, buttonSize));
_boardButtons[i][j].addMouseListener(this);
gameGrid.add(_boardButtons[i][j]);
}
gameInfo.add(gameGrid);
cp.add(gameInfo);
}
public void mouseClicked(MouseEvent e) {
if (!_gm.getCurrentPlayer().isAI()) {
//Find desired move and conduct it
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++)
if (e.getSource().equals(_boardButtons[i][j]))
_gm.makeMove(i,j);
aiMove();
updateGUI();
}
}
public void aiMove() {
int winner = _gm.isGameOver();
while (winner == -1 && _gm.getCurrentPlayer().getAI() != 0) {
updateGUI();
aiMove = _gm.getNextAIMove();
flashButton();
winner = _gm.isGameOver();
}
if (winner != -1) {
// Winner
}
}
private void flashButton() {
_moveTimer = new Timer(100, new MoveTimerListener());
_moveTimer.start();
updateGUI();
}
private class MoveTimerListener implements ActionListener {
private boolean flashOn = false;
private int count;
@Override
public void actionPerformed(ActionEvent e) {
flashOn = !flashOn;
if (count >= 20) {
((Timer) e.getSource()).stop();
flashOn = false;
_gm.makeMove(aiMove[0], aiMove[1]);
}
if (flashOn) {
_boardButtons[aiMove[0]][aiMove[1]].setBackground(Color.yellow);
} else {
_boardButtons[aiMove[0]][aiMove[1]].setBackground((new JButton()).getBackground());
}
count++;
}
}
public void mouseEntered(MouseEvent e) {
if (!_gm.getCurrentPlayer().isAI()) {
LinkedList<int[]> l = new LinkedList<int[]>();
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++)
if (e.getSource().equals(_boardButtons[i][j]))
l = _gm.canPlace(i,j);
for (int i = 0; i < l.size(); i++) {
int[] temp = l.get(i);
_boardButtons[temp[0]][temp[1]].setBackground(Color.yellow);
}
}
}
private void updateGUI() {
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++)
if (_gm.getBoard().stoneAt(i, j) == 1)
_boardButtons[i][j].setBackground(Color.green);
else if (_gm.getBoard().stoneAt(i, j) == 2)
_boardButtons[i][j].setBackground(Color.red);
}
public void mouseExited(MouseEvent arg0) { updateGUI(); }
//Not relevant
public void mousePressed(MouseEvent arg0) { }
public void mouseReleased(MouseEvent arg0) { }
//Other classes
public static class GameManager {
private int _turn;
private Player[] _players;
private GameBoard _board;
private GameLog _log;
public int getTurn() { return _turn; }
public Player[] getPlayers() { return _players; }
public GameBoard getBoard() { return _board; }
public GameManager() {
_turn = 0;
_players = new Player[0];
}
public int[] getNextAIMove() {
AI ai = new AI();
return ai.play(_players[_turn].getAI(), _board, _players[_turn].getColour());
}
public void initBoard(int m, int n) {
int[] colours = new int[_players.length];
for (int i = 0; i < colours.length; i++)
colours[i] = _players[i].getColour();
_board = new GameBoard(m, n, colours);
updateScore();
}
public void addPlayer(Player p) {
Player[] temp = _players;
_players = new Player[temp.length + 1];
for (int i = 0; i < temp.length; i++)
_players[i] = temp[i];
_players[temp.length] = new Player(p);
Random rnd = new Random();
_turn = rnd.nextInt(_players.length);
}
private void advanceTurn() {
_turn++;
if(_turn == _players.length)
_turn = 0;
}
public void makeMove(int y, int x) {
if (_board.place(y, x, _players[_turn].getColour()) != 0) {
updateScore();
advanceTurn();
}
}
public LinkedList<int[]> canPlace(int y, int x) {
return _board.canPlace(y, x, _players[_turn].getColour());
}
public int[] getBoardSize() {
return _board.getSize();
}
private void updateScore() {
int[] scores = new int[_players.length];
for (int i = 0; i < _board.getSize()[0]; i++)
for (int j = 0; j < _board.getSize()[1]; j++)
for (int j2 = 0; j2 < _players.length; j2++)
if (_players[j2].getColour() == _board.stoneAt(i, j))
scores[j2]++;
for (int i = 0; i < _players.length; i++) {
_players[i].setScore(scores[i]);
}
}
public int isGameOver() {
int winner = 0;
for (int i = 0; i < _players.length; i++) {
for (int j = 0; j < _board.getSize()[0]; j++)
for (int j2 = 0; j2 < _board.getSize()[1]; j2++)
if (canPlace(j, j2).size() != 0)
return -1;
advanceTurn();
}
for (int i = 1; i < _players.length; i++)
if (_players[i].getPoints() > _players[winner].getPoints())
winner = i;
return winner;
}
public Player getCurrentPlayer() {
return _players[_turn];
}
}
public static class AI {
public int[] play(int diff, GameBoard board, int colour) {
//List all possible moves
int[] move = new int[2];
LinkedList<int[]> posibilities = new LinkedList<int[]>();
for (int i = 0; i < board.getSize()[0]; i++)
for (int j = 0; j < board.getSize()[1]; j++)
if (board.canPlace(i, j, colour).size() > 0) {
int[] temp = {i, j};
posibilities.add(temp);
}
//Choose a move according to AI difficulty
switch (diff) {
case 1: // Easy - random
Random r = new Random();
move = posibilities.get(r.nextInt(posibilities.size()));
break;
case 2: // Medium - max kills
int max = 0, kills = board.canPlace(posibilities.get(0)[0], posibilities.get(0)[1], colour).size();
for (int i = 1; i < posibilities.size(); i++) {
int[] temp = posibilities.get(i);
int tempkills = board.canPlace(temp[0], temp[1], colour).size();
if (kills < tempkills) {
kills = tempkills;
max = i;
}
}
move = posibilities.get(max);
break;
case 3: // Hard
break;
}
return move;
}
}
public static class GameBoard {
private int[][] _board;
private int _m;
private int _n;
public GameBoard(int m, int n, int[] colours) {
_m = m;
_n = n;
_board = new int[m][n];
for (int i = 0; i < _board.length; i++)
for (int j = 0; j < _board[i].length; j++)
_board[i][j] = 0;
if (_m % 2 == 0 && _n % 2 == 0) {
_board[m/2][n/2] = _board[m/2 - 1][n/2 - 1] = colours[0];
_board[m/2][n/2 - 1] = _board[m/2 - 1][n/2] = colours[1];
}
int[][] testBoard = {
{2, 2, 2, 2, 1, 1, 2, 2},
{2, 1, 2, 2, 1, 1, 1, 2},
{1, 1, 2, 2, 1, 2, 2, 1},
{2, 2, 2, 1, 2, 1, 1, 1},
{2, 2, 1, 2, 1, 1, 1, 2},
{1, 1, 1, 2, 2, 2, 2, 2},
{1, 1, 1, 2, 2, 2, 2, 2},
{1, 1, 1, 2, 1, 1, 1, 0}};
//_board = testBoard;
}
public int[] getSize() {
int[] size = {_m, _n};
return size;
}
public LinkedList<int[]> canPlace(int y, int x, int colour) {
LinkedList<int[]> eats = new LinkedList<int[]>();
if (_board[y][x] != 0) return eats;
int i;
if (existsAnotherIn("u", y, x, colour)) {
i = 1;
while (isInBounds(y + i, x) && _board[y + i][x] != colour && _board[y + i][x] != 0) {
int[] temp = {y + i, x};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("d", y, x, colour)) {
i = 1;
while (isInBounds(y - i, x) && _board[y - i][x] != colour && _board[y - i][x] != 0) {
int[] temp = {y - i, x};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("l", y, x, colour)) {
i = 1;
while (isInBounds(y, x - i) && _board[y][x - i] != colour && _board[y][x - i] != 0) {
int[] temp = {y, x - i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("r", y, x, colour)) {
i = 1;
while (isInBounds(y, x + i) && _board[y][x + i] != colour && _board[y][x + i] != 0) {
int[] temp = {y, x + i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("ul", y, x, colour)) {
i = 1;
while (isInBounds(y + i, x - i) && _board[y + i][x - i] != colour && _board[y + i][x - i] != 0) {
int[] temp = {y + i, x - i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("ur", y, x, colour)) {
i = 1;
while (isInBounds(y + i, x + i) && _board[y + i][x + i] != colour && _board[y + i][x + i] != 0) {
int[] temp = {y + i, x + i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("dl", y, x, colour)) {
i = 1;
while (isInBounds(y - i, x - i) && _board[y - i][x - i] != colour && _board[y - i][x - i] != 0) {
int[] temp = {y - i, x - i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("dr", y, x, colour)) {
i = 1;
while (isInBounds(y - i, x + i) && _board[y - i][x + i] != colour && _board[y - i][x + i] != 0) {
int[] temp = {y - i, x + i};
eats.add(temp);
i++;
}
}
return eats;
}
private boolean isInBounds(int i, int j) {
return i >= 0 && j >= 0 && i < _m && j < _n;
}
private boolean existsAnotherIn(String lane, int vo, int ho, int colour) {
int v = 0, h = 0;
do {
if ((v != 0 || h != 0) && _board[vo + v][ho + h] == colour) return true;
if (lane.contains("u")) v++;
else if (lane.contains("d")) v--;
if (lane.contains("r")) h++;
else if (lane.contains("l")) h--;
} while (isInBounds(vo + v, ho + h) && _board[vo + v][ho + h] != 0);
return false;
}
public int place(int y, int x, int colour) {
LinkedList<int[]> stonesToEat = canPlace(y, x, colour);
if (!stonesToEat.isEmpty()) {
_board[y][x] = colour;
for (int i = 0; i < stonesToEat.size(); i++) {
int[] place = stonesToEat.get(i);
_board[place[0]][place[1]] = colour;
}
}
return stonesToEat.size();
}
public String toString() {
String s = "";
for (int i = 0; i < _board.length; i++) {
for (int j = 0; j < _board[0].length; j++) {
s+=_board[i][j]+"\t";
}
s += "\n";
}
return s;
}
public int stoneAt(int i, int j) {
return _board[i][j];
}
}
public static class Player {
private String _name;
private int _points;
private int _colour;
private int _ai;
public Player(String name, int colour, int ai) {
_name = name;
_points = 0;
_colour = colour;
_ai = ai;
}
public void setScore(int s) {
_points = s;
}
public Player(Player p) {
_name = p._name;
_points = p._points;
_colour = p._colour;
_ai = p._ai;
}
public boolean isAI() {
return _ai != 0;
}
public void addPoints(int add) { _points += add; }
public int getColour() { return _colour; }
public String getName() { return _name; }
public int getPoints() { return _points; }
public int getAI() { return _ai; }
}
public class GameLog extends GameManager {
private int _startingPlayer;
private LinkedList<String> _moves;
public GameLog(int startPlayer) {
_startingPlayer = startPlayer;
_moves = new LinkedList<String>();
}
public void addMove(String m) {
_moves.add(m);
}
public int getStartingPlayer() { return _startingPlayer; }
public LinkedList<String> getMoves() { return _moves; }
}
import java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.util.LinkedList;
导入java.util.Random;
导入javax.swing.BoxLayout;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.Timer;
公共类GameGUI扩展JFrame实现MouseListener{
私人游戏经理(总经理);
私人JLabel[]_分数;
私人JLabel[]_玩家;
私有JPanel_内容窗格;
私有JButton[]\u工具栏按钮;
专用JButton[][]按钮;
私人定时器(moveTimer),;
私人国际[]爱慕;
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
GameManager gm=新GameManager();
//gm.addPlayer(新玩家(“玩家”,2,0));
gm.addPlayer(新玩家(“随机”,2,1));
gm.addPlayer(新玩家(“max杀死ai”,1,2));
董事会总经理(8,8);
GameGUI框架=新GameGUI(gm);
frame.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
/**
*创建框架。
*/
公共游戏GUI(游戏管理器总经理){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
立根(100100450300);
_contentPane=newjpanel();
_boardButtons=新的JButton[gm.getBoardSize()[0]][gm.getBoardSize()[1]];
_gm=gm;
addWindowGUI(_contentPane);
setContentPane(_contentPane);
aiMove();
updateGUI();
}
私有void addWindowGUI(JPanel cp){
cp.setLayout(新的BoxLayout(_contentPane,BoxLayout.PAGE_AXIS));
JPanel gameInfo=新的JPanel();
gameInfo.setLayout(新的FlowLayout());
//游戏网格
JPanel gameGrid=新的JPanel();
int按钮大小=40;
gameGrid.setLayout(新的GridLayout(_gm.getBoardSize()[0],_gm.getBoardSize()[1]);
对于(int i=0;i<\u boardButtons.length;i++)
对于(int j=0;j<_boardButtons[i]。长度;j++){
_boardButtons[i][j]=新的JButton();
_boardButtons[i][j].setPreferredSize(新尺寸(buttonSize,buttonSize));
_boardButtons[i][j].addMouseListener(本);
gameGrid.add(_boardButtons[i][j]);
}
gameInfo.add(gameGrid);
cp.add(gameInfo);
}
公共无效mouseClicked(MouseEvent e){
如果(!\u gm.getCurrentPlayer().isAI()){
//找到想要的动作并进行
对于(int i=0;i<\u boardButtons.length;i++)
对于(int j=0;j<_boardButtons[i]。长度;j++)
如果(e.getSource().equals(_[i][j]))
_总经理马克莫夫(i,j);
aiMove();
updateGUI();
}
}
公共无效aiMove(){
int winner=_gm.isGameOver();
while(winner==-1&&u gm.getCurrentPlayer().getAI()!=0){
updateGUI();
aiMove=_gm.getNextAIMove();
flashButton();
获胜者=_gm.isGameOver();
}
如果(获胜者!=-1){
//胜利者
}
}
私有void flashButton(){
_moveTimer=新计时器(100,新的MoveTimerListener());
_moveTimer.start();
updateGUI();
}
私有类MoveTimerListener实现ActionListener{
私有布尔flashOn=false;
私人整数计数;
@凌驾
已执行的公共无效操作(操作事件e){
闪光=!闪光;
如果(计数>=20){
((计时器)e.getSource()).stop();
闪光=假;
_gm.makeMove(aiMove[0],aiMove[1]);
}
如果(闪络){
_boardButtons[aiMove[0]][aiMove[1]].背景(颜色.黄色);
}否则{
_boardButtons[aiMove[0]][aiMove[1]].setBackground((新的JButton()).getBackground());
}
计数++;
}
}
公共无效鼠标事件(鼠标事件e){
如果(!\u gm.getCurrentPlayer().isAI()){
LinkedList l=新建LinkedList();
对于(int i=0;i<\u boardButtons.length;i++)
对于(int j=0;j<_boardButtons[i]。长度;j++)
如果(e.getSource().equals(_[i][j]))
l=_gm.canPlace(i,j);
对于(int i=0;iimport java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GameGUI extends JFrame implements MouseListener {
private GameManager _gm;
private JLabel[] _scores;
private JLabel[] _players;
private JPanel _contentPane;
private JButton[] _toolbarButtons;
private JButton[][] _boardButtons;
private Timer _moveTimer;
private int[] aiMove;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GameManager gm = new GameManager();
//gm.addPlayer(new Player("player", 2, 0));
gm.addPlayer(new Player("random", 2, 1));
gm.addPlayer(new Player("max kills ai", 1, 2));
gm.initBoard(8, 8);
GameGUI frame = new GameGUI(gm);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GameGUI(GameManager gm) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
_contentPane = new JPanel();
_boardButtons = new JButton[gm.getBoardSize()[0]][gm.getBoardSize()[1]];
_gm = gm;
addWindowGUI(_contentPane);
setContentPane(_contentPane);
aiMove();
updateGUI();
}
private void addWindowGUI(JPanel cp) {
cp.setLayout(new BoxLayout(_contentPane, BoxLayout.PAGE_AXIS));
JPanel gameInfo = new JPanel();
gameInfo.setLayout(new FlowLayout());
//Game grid
JPanel gameGrid = new JPanel();
int buttonSize = 40;
gameGrid.setLayout(new GridLayout(_gm.getBoardSize()[0], _gm.getBoardSize()[1]));
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++) {
_boardButtons[i][j] = new JButton();
_boardButtons[i][j].setPreferredSize(new Dimension(buttonSize, buttonSize));
_boardButtons[i][j].addMouseListener(this);
gameGrid.add(_boardButtons[i][j]);
}
gameInfo.add(gameGrid);
cp.add(gameInfo);
}
public void mouseClicked(MouseEvent e) {
if (!_gm.getCurrentPlayer().isAI()) {
//Find desired move and conduct it
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++)
if (e.getSource().equals(_boardButtons[i][j]))
_gm.makeMove(i,j);
aiMove();
updateGUI();
}
}
public void aiMove() {
int winner = _gm.isGameOver();
while (winner == -1 && _gm.getCurrentPlayer().getAI() != 0) {
updateGUI();
aiMove = _gm.getNextAIMove();
flashButton();
winner = _gm.isGameOver();
}
if (winner != -1) {
// Winner
}
}
private void flashButton() {
_moveTimer = new Timer(100, new MoveTimerListener());
_moveTimer.start();
updateGUI();
}
private class MoveTimerListener implements ActionListener {
private boolean flashOn = false;
private int count;
@Override
public void actionPerformed(ActionEvent e) {
flashOn = !flashOn;
if (count >= 20) {
((Timer) e.getSource()).stop();
flashOn = false;
_gm.makeMove(aiMove[0], aiMove[1]);
}
if (flashOn) {
_boardButtons[aiMove[0]][aiMove[1]].setBackground(Color.yellow);
} else {
_boardButtons[aiMove[0]][aiMove[1]].setBackground((new JButton()).getBackground());
}
count++;
}
}
public void mouseEntered(MouseEvent e) {
if (!_gm.getCurrentPlayer().isAI()) {
LinkedList<int[]> l = new LinkedList<int[]>();
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++)
if (e.getSource().equals(_boardButtons[i][j]))
l = _gm.canPlace(i,j);
for (int i = 0; i < l.size(); i++) {
int[] temp = l.get(i);
_boardButtons[temp[0]][temp[1]].setBackground(Color.yellow);
}
}
}
private void updateGUI() {
for (int i = 0; i < _boardButtons.length; i++)
for (int j = 0; j < _boardButtons[i].length; j++)
if (_gm.getBoard().stoneAt(i, j) == 1)
_boardButtons[i][j].setBackground(Color.green);
else if (_gm.getBoard().stoneAt(i, j) == 2)
_boardButtons[i][j].setBackground(Color.red);
}
public void mouseExited(MouseEvent arg0) { updateGUI(); }
//Not relevant
public void mousePressed(MouseEvent arg0) { }
public void mouseReleased(MouseEvent arg0) { }
//Other classes
public static class GameManager {
private int _turn;
private Player[] _players;
private GameBoard _board;
private GameLog _log;
public int getTurn() { return _turn; }
public Player[] getPlayers() { return _players; }
public GameBoard getBoard() { return _board; }
public GameManager() {
_turn = 0;
_players = new Player[0];
}
public int[] getNextAIMove() {
AI ai = new AI();
return ai.play(_players[_turn].getAI(), _board, _players[_turn].getColour());
}
public void initBoard(int m, int n) {
int[] colours = new int[_players.length];
for (int i = 0; i < colours.length; i++)
colours[i] = _players[i].getColour();
_board = new GameBoard(m, n, colours);
updateScore();
}
public void addPlayer(Player p) {
Player[] temp = _players;
_players = new Player[temp.length + 1];
for (int i = 0; i < temp.length; i++)
_players[i] = temp[i];
_players[temp.length] = new Player(p);
Random rnd = new Random();
_turn = rnd.nextInt(_players.length);
}
private void advanceTurn() {
_turn++;
if(_turn == _players.length)
_turn = 0;
}
public void makeMove(int y, int x) {
if (_board.place(y, x, _players[_turn].getColour()) != 0) {
updateScore();
advanceTurn();
}
}
public LinkedList<int[]> canPlace(int y, int x) {
return _board.canPlace(y, x, _players[_turn].getColour());
}
public int[] getBoardSize() {
return _board.getSize();
}
private void updateScore() {
int[] scores = new int[_players.length];
for (int i = 0; i < _board.getSize()[0]; i++)
for (int j = 0; j < _board.getSize()[1]; j++)
for (int j2 = 0; j2 < _players.length; j2++)
if (_players[j2].getColour() == _board.stoneAt(i, j))
scores[j2]++;
for (int i = 0; i < _players.length; i++) {
_players[i].setScore(scores[i]);
}
}
public int isGameOver() {
int winner = 0;
for (int i = 0; i < _players.length; i++) {
for (int j = 0; j < _board.getSize()[0]; j++)
for (int j2 = 0; j2 < _board.getSize()[1]; j2++)
if (canPlace(j, j2).size() != 0)
return -1;
advanceTurn();
}
for (int i = 1; i < _players.length; i++)
if (_players[i].getPoints() > _players[winner].getPoints())
winner = i;
return winner;
}
public Player getCurrentPlayer() {
return _players[_turn];
}
}
public static class AI {
public int[] play(int diff, GameBoard board, int colour) {
//List all possible moves
int[] move = new int[2];
LinkedList<int[]> posibilities = new LinkedList<int[]>();
for (int i = 0; i < board.getSize()[0]; i++)
for (int j = 0; j < board.getSize()[1]; j++)
if (board.canPlace(i, j, colour).size() > 0) {
int[] temp = {i, j};
posibilities.add(temp);
}
//Choose a move according to AI difficulty
switch (diff) {
case 1: // Easy - random
Random r = new Random();
move = posibilities.get(r.nextInt(posibilities.size()));
break;
case 2: // Medium - max kills
int max = 0, kills = board.canPlace(posibilities.get(0)[0], posibilities.get(0)[1], colour).size();
for (int i = 1; i < posibilities.size(); i++) {
int[] temp = posibilities.get(i);
int tempkills = board.canPlace(temp[0], temp[1], colour).size();
if (kills < tempkills) {
kills = tempkills;
max = i;
}
}
move = posibilities.get(max);
break;
case 3: // Hard
break;
}
return move;
}
}
public static class GameBoard {
private int[][] _board;
private int _m;
private int _n;
public GameBoard(int m, int n, int[] colours) {
_m = m;
_n = n;
_board = new int[m][n];
for (int i = 0; i < _board.length; i++)
for (int j = 0; j < _board[i].length; j++)
_board[i][j] = 0;
if (_m % 2 == 0 && _n % 2 == 0) {
_board[m/2][n/2] = _board[m/2 - 1][n/2 - 1] = colours[0];
_board[m/2][n/2 - 1] = _board[m/2 - 1][n/2] = colours[1];
}
int[][] testBoard = {
{2, 2, 2, 2, 1, 1, 2, 2},
{2, 1, 2, 2, 1, 1, 1, 2},
{1, 1, 2, 2, 1, 2, 2, 1},
{2, 2, 2, 1, 2, 1, 1, 1},
{2, 2, 1, 2, 1, 1, 1, 2},
{1, 1, 1, 2, 2, 2, 2, 2},
{1, 1, 1, 2, 2, 2, 2, 2},
{1, 1, 1, 2, 1, 1, 1, 0}};
//_board = testBoard;
}
public int[] getSize() {
int[] size = {_m, _n};
return size;
}
public LinkedList<int[]> canPlace(int y, int x, int colour) {
LinkedList<int[]> eats = new LinkedList<int[]>();
if (_board[y][x] != 0) return eats;
int i;
if (existsAnotherIn("u", y, x, colour)) {
i = 1;
while (isInBounds(y + i, x) && _board[y + i][x] != colour && _board[y + i][x] != 0) {
int[] temp = {y + i, x};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("d", y, x, colour)) {
i = 1;
while (isInBounds(y - i, x) && _board[y - i][x] != colour && _board[y - i][x] != 0) {
int[] temp = {y - i, x};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("l", y, x, colour)) {
i = 1;
while (isInBounds(y, x - i) && _board[y][x - i] != colour && _board[y][x - i] != 0) {
int[] temp = {y, x - i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("r", y, x, colour)) {
i = 1;
while (isInBounds(y, x + i) && _board[y][x + i] != colour && _board[y][x + i] != 0) {
int[] temp = {y, x + i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("ul", y, x, colour)) {
i = 1;
while (isInBounds(y + i, x - i) && _board[y + i][x - i] != colour && _board[y + i][x - i] != 0) {
int[] temp = {y + i, x - i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("ur", y, x, colour)) {
i = 1;
while (isInBounds(y + i, x + i) && _board[y + i][x + i] != colour && _board[y + i][x + i] != 0) {
int[] temp = {y + i, x + i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("dl", y, x, colour)) {
i = 1;
while (isInBounds(y - i, x - i) && _board[y - i][x - i] != colour && _board[y - i][x - i] != 0) {
int[] temp = {y - i, x - i};
eats.add(temp);
i++;
}
}
if (existsAnotherIn("dr", y, x, colour)) {
i = 1;
while (isInBounds(y - i, x + i) && _board[y - i][x + i] != colour && _board[y - i][x + i] != 0) {
int[] temp = {y - i, x + i};
eats.add(temp);
i++;
}
}
return eats;
}
private boolean isInBounds(int i, int j) {
return i >= 0 && j >= 0 && i < _m && j < _n;
}
private boolean existsAnotherIn(String lane, int vo, int ho, int colour) {
int v = 0, h = 0;
do {
if ((v != 0 || h != 0) && _board[vo + v][ho + h] == colour) return true;
if (lane.contains("u")) v++;
else if (lane.contains("d")) v--;
if (lane.contains("r")) h++;
else if (lane.contains("l")) h--;
} while (isInBounds(vo + v, ho + h) && _board[vo + v][ho + h] != 0);
return false;
}
public int place(int y, int x, int colour) {
LinkedList<int[]> stonesToEat = canPlace(y, x, colour);
if (!stonesToEat.isEmpty()) {
_board[y][x] = colour;
for (int i = 0; i < stonesToEat.size(); i++) {
int[] place = stonesToEat.get(i);
_board[place[0]][place[1]] = colour;
}
}
return stonesToEat.size();
}
public String toString() {
String s = "";
for (int i = 0; i < _board.length; i++) {
for (int j = 0; j < _board[0].length; j++) {
s+=_board[i][j]+"\t";
}
s += "\n";
}
return s;
}
public int stoneAt(int i, int j) {
return _board[i][j];
}
}
public static class Player {
private String _name;
private int _points;
private int _colour;
private int _ai;
public Player(String name, int colour, int ai) {
_name = name;
_points = 0;
_colour = colour;
_ai = ai;
}
public void setScore(int s) {
_points = s;
}
public Player(Player p) {
_name = p._name;
_points = p._points;
_colour = p._colour;
_ai = p._ai;
}
public boolean isAI() {
return _ai != 0;
}
public void addPoints(int add) { _points += add; }
public int getColour() { return _colour; }
public String getName() { return _name; }
public int getPoints() { return _points; }
public int getAI() { return _ai; }
}
public class GameLog extends GameManager {
private int _startingPlayer;
private LinkedList<String> _moves;
public GameLog(int startPlayer) {
_startingPlayer = startPlayer;
_moves = new LinkedList<String>();
}
public void addMove(String m) {
_moves.add(m);
}
public int getStartingPlayer() { return _startingPlayer; }
public LinkedList<String> getMoves() { return _moves; }
}
class MoveTimerListener implements ActionListener {
private boolean flashOn = false;
private int count;
@Override
public void actionPerformed(ActionEvent e) {
flashOn = !flashOn;
if (count >= MAX_COUNT) { // MAX_COUNT is an int constant
// reached max -- stop timer
((Timer) e.getSource()).stop();
flashOn = false;
// TODO: place code to make move here
}
if (flashOn) {
// TODO: place code to flash here
}
count++;
}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class FlashingTimerGui extends JPanel {
private static final int MAX_COUNT = 20;
private static final int IMG_WIDTH = 60;
private static final int SIDES = 3;
public static final int MOVE_TIMER_DELAY = 100;
private Icon blankIcon;
private Icon blackIcon;
private Icon redIcon;
private List<JLabel> labelList = new ArrayList<>();
private Timer moveTimer;
private int labelListIndex = 0;
public FlashingTimerGui() {
blankIcon = createIcon(new Color(0, 0, 0, 0));
blackIcon = createIcon(Color.black);
redIcon = createIcon(Color.red);
JPanel gridPanel = new JPanel(new GridLayout(SIDES, SIDES));
gridPanel.setBorder(BorderFactory.createLineBorder(Color.black));
for (int i = 0; i < SIDES * SIDES; i++) {
JLabel label = new JLabel(blankIcon);
label.setBorder(BorderFactory.createLineBorder(Color.black));
gridPanel.add(label);
labelList.add(label);
}
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new MoveAction("Move")));
setLayout(new BorderLayout());
add(gridPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
labelList.get(labelListIndex).setIcon(blackIcon);
}
private Icon createIcon(Color color) {
BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_WIDTH,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(color);
int x = 4;
int y = x;
int w = IMG_WIDTH - 2 * x;
int h = w;
g2.fillOval(x, y, w, h);
g2.dispose();
return new ImageIcon(img);
}
private class MoveTimerListener implements ActionListener {
private boolean flashOn = false;
private int count;
@Override
public void actionPerformed(ActionEvent e) {
flashOn = !flashOn;
if (count >= MAX_COUNT) { // MAX_COUNT is an int constant
// reached max -- stop timer
((Timer) e.getSource()).stop();
flashOn = false;
// code to make move here
labelList.get(labelListIndex).setIcon(blankIcon);
labelListIndex++;
labelListIndex %= labelList.size();
labelList.get(labelListIndex).setIcon(blackIcon);
}
if (flashOn) {
labelList.get(labelListIndex).setIcon(redIcon);
} else {
labelList.get(labelListIndex).setIcon(blackIcon);
}
count++;
}
}
private class MoveAction extends AbstractAction {
public MoveAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
if (moveTimer != null && moveTimer.isRunning()) {
// timer is running -- ignore request to re-run
return;
}
moveTimer = new Timer(MOVE_TIMER_DELAY, new MoveTimerListener());
moveTimer.start();
}
}
private static void createAndShowGui() {
FlashingTimerGui mainPanel = new FlashingTimerGui();
JFrame frame = new JFrame("Flashing Timer");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}