Files
cs8803p4/src/model/Referee.java

205 lines
5.0 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.";
public static boolean[] getBoardState(Board brd) {
boolean[] boardState = new boolean[(Board.NUM_COLS * Board.NUM_ROWS * (Board.TileColor
.values().length - 1))];
int i = 0;
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
boardState[i] = (brd.getTile(r, c) == TileColor.BLUE);
boardState[i + 1] = (brd.getTile(r, c) == TileColor.GREEN);
boardState[i + 2] = (brd.getTile(r, c) == TileColor.RED);
boardState[i + 3] = (brd.getTile(r, c) == TileColor.YELLOW);
i += 4;
}
}
return boardState;
}
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 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 + 4] = (mv.getCell().r == r && mv.getCell().c == c);
tile++;
}
}
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()) {
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 {
getPlayerModel().getOutputNodes(getBoardState(board));
Move mv = humanPlayer.getMove(board, playerModel);
if (board.getTile(mv.getCell().r, mv.getCell().c) == TileColor.NONE) {
playToken(humanPlayer.getMove(board, playerModel));
getPlayerModel().train(getMoveArray(mv));
} else {
humanPlayer.denyMove();
}
}
} else {
Move mv = computerPlayer.getMove(board, getPlayerModel());
playToken(mv);
// 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.
// UPDATE: I made a neural network agent. This call is in there
// now. If the current agent doesn't use the neural network,
// then this doesn't need to be called. It will just train on
// random, meaningless data.
// getPlayerModel().getOutputNodes(getBoardState(board));
}
getScorePanel().updateScore(getPlayerScore());
mf.updateMessage(getMessage());
boardPanel.updateIcons();
LOGGER.info("plies: " + plies++);
try {
Thread.sleep(250L);
} catch (InterruptedException ie) {
System.out
.println("Interrupted while waiting for human view ply!");
}
}
}
}