我正在创建一个带有人工智能的棋盘游戏,而我正试图让人工智能选择将他的游戏部件放入闪存中一两秒,然后再进行所选择的移动。我的尝试如下:
Thread.sleep代码
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的线程而不是公共布尔调用(),它是public void run())
public class ButtonFlashThread implements Callable<Boolean> {
private int sleepTime = 800;
private JButton button;
public ButtonFlashThread(JButton b) {
button = b;
}
public Boolean call() {
for (int i = 0; i < 3; i++) {
button.setBackground(Color.pink);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
button.setBackground((new JButton()).getBackground());
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
的invokeLater
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();
Thread.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; }
}
}
答案 0 :(得分:3)
你在想这个。只需创建一个单一的Swing Timer ,就是它,然后给它一个状态 - 即,给它的ActionListener字段改变,一个是一个布尔值,表示何时闪烁,你转为true和false,另一个,一个计算闪烁次数的int,在达到一定数量后关闭Timer,然后移动。
像
这样简单20:1E:50:3F:8A:3E
20:1E:50:3F:8A:3F
20:1E:50:3F:8A:40
20:1E:50:3F:8A:41
20:1E:50:3F:8A:42
20:1E:50:3F:8A:43
这个的总运行时间是MAX_COUNT *计时器的延迟。
例如,
function generate($prefix, $start, $end){
$start = str_split($start);
$end = str_split($end);
$start_first = $start[0];
$start_second = $start[1];
$end_first = $end[0];
$end_second = $end[1];
if(is_numeric($start_second)){
$start_second_numeric = true;
}
else{
$start_second_numeric = false;
}
if(is_numeric($end_second)){
$end_second_numeric = true;
}
else{
$end_second_numeric = false;
}
$mac_array = array();
$range_first = range($start_first, $end_first);
foreach($range_first as $first_character){
if($start_second_numeric && $end_second_numeric || !$start_second_numeric && !$end_second_numeric){
$range_second = range($start_second, $end_second);
}
elseif(!$start_second_numeric && $end_second_numeric){
$range_second = range($start_second, "F");
$range_third = range("0", $end_second);
}
elseif($start_second_numeric && !$end_second_numeric){
$range_second = range($start_second, "9");
$range_third = range("A", $end_second);
}
foreach($range_second as $second_character){
$string = $prefix . ":" . $first_character . $second_character;
array_push($mac_array, $string);
}
if(is_array($range_third)){
foreach($range_third as $second_character){
$string = $prefix . ":" . $first_character . $second_character;
array_push($mac_array, $string);
}
}
}
return $mac_array;
}