198 lines
4.7 KiB
Java
198 lines
4.7 KiB
Java
package model;
|
|
|
|
import model.Board.TileColor;
|
|
import model.comPlayer.HumanPlayer;
|
|
import model.comPlayer.Player;
|
|
import model.playerModel.PlayerModel;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
import view.BoardPanel;
|
|
import view.HighScoreDialog;
|
|
import view.MainFrame;
|
|
import view.ScorePanel;
|
|
|
|
public class Referee implements Runnable {
|
|
public static final String COM_TURN = "Waiting for the computer's move.";
|
|
public static final String GAME_OVER = "Game over!";
|
|
public static final Logger LOGGER = Logger.getLogger(Referee.class
|
|
.getName());
|
|
|
|
public static final String PLAYER_TURN = "Waiting for the player's move.";
|
|
|
|
private Board board;
|
|
private BoardPanel boardPanel;
|
|
private final Player computerPlayer;
|
|
|
|
private final HumanPlayer humanPlayer = new HumanPlayer();
|
|
private final MainFrame mf;
|
|
private PlayerModel playerModel = null;
|
|
|
|
public Referee(MainFrame mnFrm, String player, Player computerPlayer) {
|
|
if (PlayerModel.exists(player)) {
|
|
PlayerModel.getPlayerPath(player);
|
|
playerModel = PlayerModel.load(PlayerModel.getPlayerPath(player));
|
|
}
|
|
|
|
if (getPlayerModel() == null) {
|
|
playerModel = new PlayerModel(player);
|
|
}
|
|
|
|
mf = mnFrm;
|
|
this.computerPlayer = computerPlayer;
|
|
initGame();
|
|
}
|
|
|
|
public boolean[] getBoardState() {
|
|
boolean[] boardState = new boolean[getPlayerModel().getNumInputNodes()];
|
|
|
|
int i = 0;
|
|
for (int r = 0; r < Board.NUM_ROWS; r++) {
|
|
for (int c = 0; c < Board.NUM_COLS; c++) {
|
|
boardState[i] = (board.getTile(r, c) == TileColor.BLUE);
|
|
boardState[i + 1] = (board.getTile(r, c) == TileColor.GREEN);
|
|
boardState[i + 2] = (board.getTile(r, c) == TileColor.RED);
|
|
boardState[i + 3] = (board.getTile(r, c) == TileColor.YELLOW);
|
|
|
|
i += 4;
|
|
}
|
|
}
|
|
|
|
return boardState;
|
|
}
|
|
|
|
public Player getComputerPlayer() {
|
|
return computerPlayer;
|
|
}
|
|
|
|
public HumanPlayer getHumanPlayer() {
|
|
return humanPlayer;
|
|
}
|
|
|
|
public String getMessage() {
|
|
if (isOver()) {
|
|
return GAME_OVER;
|
|
} else if (board.isPlayerTurn()) {
|
|
return PLAYER_TURN;
|
|
} else {
|
|
return COM_TURN;
|
|
}
|
|
}
|
|
|
|
public int getPlayerScore() {
|
|
return board.getTurn();
|
|
}
|
|
|
|
public TileColor getTile(int r, int c) {
|
|
return board.getTile(r, c);
|
|
}
|
|
|
|
public boolean isOver() {
|
|
return board.isTerminalState();
|
|
}
|
|
|
|
public void playToken(Move move) {
|
|
board.playTile(move.getCell(), move.getColor());
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
while (true) {
|
|
initGame();
|
|
mf.updateBoard();
|
|
play();
|
|
getPlayerModel().logGame(getPlayerScore());
|
|
|
|
if (!getPlayerModel().save()) {
|
|
System.err.println("Saving PlayerModel failed.");
|
|
}
|
|
|
|
new HighScoreDialog(mf, getPlayerModel());
|
|
}
|
|
}
|
|
|
|
public void setBoardPanel(BoardPanel boardPanel) {
|
|
this.boardPanel = boardPanel;
|
|
}
|
|
|
|
private boolean[] getMoveArray(Move mv) {
|
|
boolean[] move = new boolean[getPlayerModel().getNumOutputNodes()];
|
|
|
|
move[0] = (mv.getColor() == TileColor.BLUE);
|
|
move[1] = (mv.getColor() == TileColor.GREEN);
|
|
move[2] = (mv.getColor() == TileColor.RED);
|
|
move[3] = (mv.getColor() == TileColor.YELLOW);
|
|
|
|
int tile = 0;
|
|
for (int r = 0; r < Board.NUM_ROWS; r++) {
|
|
for (int c = 0; c < Board.NUM_COLS; c++) {
|
|
move[tile] = (mv.getCell().r == r && mv.getCell().c == c);
|
|
}
|
|
}
|
|
|
|
return move;
|
|
}
|
|
|
|
private PlayerModel getPlayerModel() {
|
|
return playerModel;
|
|
}
|
|
|
|
private ScorePanel getScorePanel() {
|
|
return mf.getScorePanel();
|
|
}
|
|
|
|
private void initGame() {
|
|
board = new Board();
|
|
}
|
|
|
|
private void play() {
|
|
int plies = 0;
|
|
while (!isOver()) {
|
|
getScorePanel().updateScore(getPlayerScore());
|
|
if (board.isPlayerTurn()) {
|
|
boolean wasInterrupted = false;
|
|
while (!humanPlayer.isReady()) {
|
|
try {
|
|
Thread.sleep(250L);
|
|
} catch (InterruptedException ie) {
|
|
wasInterrupted = true;
|
|
}
|
|
}
|
|
if (wasInterrupted) {
|
|
System.out
|
|
.println("Interrupted while waiting for human to move!");
|
|
} else {
|
|
Move mv = humanPlayer.getMove(board);
|
|
if (board.getTile(mv.getCell().r, mv.getCell().c) == TileColor.NONE) {
|
|
playToken(humanPlayer.getMove(board));
|
|
|
|
getPlayerModel().train(getMoveArray(mv));
|
|
|
|
} else {
|
|
humanPlayer.denyMove();
|
|
}
|
|
}
|
|
} else {
|
|
Move mv = computerPlayer.getMove(board);
|
|
playToken(mv);
|
|
|
|
// TODO
|
|
// This is the call that gets a prediction of a user's move.
|
|
// Some changes will probably be necessary to put it in the
|
|
// right place and also to get the node weights. But... all in
|
|
// due time.
|
|
getPlayerModel().getOutputNodes(getBoardState());
|
|
}
|
|
|
|
mf.updateMessage(getMessage());
|
|
boardPanel.updateIcons();
|
|
LOGGER.info("plies: " + plies++);
|
|
try {
|
|
Thread.sleep(1000L);
|
|
} catch (InterruptedException ie) {
|
|
System.out
|
|
.println("Interrupted while waiting for human view ply!");
|
|
}
|
|
}
|
|
}
|
|
} |