Files
cs8803p4/src/model/playerModel/PlayerModel.java
Marshall 24096b50a8 - Updated the Node interface and its implementations to include a strength() function. This is a double value between 0 and 1 representing the percent activation.
- Updated the PlayerModel to fix a bug in the high score tracking.
- Created HighScoreDialog.java, which displays the high scores from a PlayerModel. In the future, it will have a "New Game" button so that it can be used to transition between games.
2012-04-26 13:04:41 -04:00

160 lines
3.8 KiB
Java

package model.playerModel;
import java.util.Random;
import model.Board;
import model.playerModel.node.InputNode;
import model.playerModel.node.SigmoidNode;
public class PlayerModel {
public static final Random rand = new Random();
private final SigmoidNode[] hiddenLayer;
private final int[] highScore = new int[10];
private int highScoresAchieved = 0;
// One node for each tile-color combination, plus one for each upcoming
// tile-color combination.
private final InputNode[] inputNode = new InputNode[(Board.NUM_COLS
* Board.NUM_ROWS * (Board.TileColor.values().length - 1))];
private int nextHighInGames = 0;
// One node for each tile plus four for the colors to be selected.
// outputNode[0] is blue.
// outputNode[1] is green.
// outputNode[2] is red.
// outputNode[3] is yellow.
// outputNode[4] through outputNode[n] represent grid spaces. A true means
// that the player is predicted to place on that tile.
// They should be read from the top-left to bottom-right, across rows.
// Ideally, the network should return only one true between 0 and 3 and only
// one true between 4 and n, representing one color and the tile in which it
// should be placed.
private final SigmoidNode[] outputNode = new SigmoidNode[(Board.NUM_COLS * Board.NUM_ROWS) + 4];
public PlayerModel() {
for (int i = 0; i < highScore.length; i++) {
highScore[i] = -1;
}
hiddenLayer = new SigmoidNode[inputNode.length
+ ((inputNode.length * 2) / 3)];
for (int i = 0; i < inputNode.length; i++) {
inputNode[i] = new InputNode();
}
for (int i = 0; i < hiddenLayer.length; i++) {
hiddenLayer[i] = new SigmoidNode();
for (int j = 0; j < inputNode.length; j++) {
hiddenLayer[i].addNode(inputNode[j], 1);
}
}
for (int i = 0; i < outputNode.length; i++) {
outputNode[i] = new SigmoidNode();
for (int j = 0; j < hiddenLayer.length; j++) {
outputNode[i].addNode(hiddenLayer[j], 1);
}
}
}
public int[] getHighScores() {
return highScore;
}
public boolean[] getPrediction(boolean[] input) {
if (input.length == inputNode.length) {
boolean[] prediction = new boolean[outputNode.length];
for (int i = 0; i < input.length; i++) {
inputNode[i].setStimulation(input[i]);
}
for (int i = 0; i < prediction.length; i++) {
prediction[i] = outputNode[i].axon();
}
return prediction;
}
return null;
}
public GameGoal getTargetScore() {
GameGoal goal;
int targetScore;
int highScore = getHighScore();
if (highScoresAchieved == 0) {
goal = new GameGoal(0, true);
nextHighInGames = 1;
}
else if (nextHighInGames == 0) {
// Set next game for high score.
nextHighInGames = (int) (Math.pow(highScoresAchieved + 1, 2) / 2);
// Return high score times increase percentage.
targetScore = highScore / (2 * (highScoresAchieved + 1));
if (targetScore <= highScore) {
targetScore = highScore + 1;
}
goal = new GameGoal(targetScore, true);
}
else {
double scoreReduction = .1 * rand.nextDouble();
targetScore = (int) (highScore - (highScore * scoreReduction));
if (targetScore >= highScore) {
targetScore = highScore - 1;
}
goal = new GameGoal(targetScore, false);
}
return goal;
}
public void logGame(int score) {
if (highScore[0] == -1) {
highScore[0] = score;
}
else {
loop: for (int i = 0; i < highScore.length; i++) {
if (score > highScore[i]) {
for (int j = highScore.length - 2; j >= i; j--) {
highScore[j + 1] = highScore[j];
}
highScore[i] = score;
break loop;
}
}
}
highScoresAchieved += (score == highScore[0]) ? 1 : 0;
nextHighInGames--;
}
public void train(boolean[] example) {
if (example.length == outputNode.length) {
for (int i = 0; i < outputNode.length; i++) {
outputNode[i].learn(example[i]);
}
}
}
private int getHighScore() {
return highScore[0];
}
}