Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/Tests/HeuristicTesting.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void main(String[] args) {
int numStates = 10000;
for (int i = 0; i < numStates; i++) {
State randomState = states.get(r.nextInt(states.size()));
ArrayList<Action> actions = ActionGenerator.generateActions(randomState, r.nextInt(1) + 1, 1);
ArrayList<Action> actions = ActionGenerator.generateActions(randomState, r.nextInt(1) + 1);
states.add(new State(s, actions.get(r.nextInt(actions.size()))));
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/Tree/MonteCarloTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Action search() {

boolean useMoveDictionary = root.getDepth() < 8;
if (useMoveDictionary) {
selectedAction = getMoveDictionaryMove();
return getMoveDictionaryMove();
}
try {
while (time.timeLeft()) {
Expand All @@ -59,7 +59,7 @@ public Action search() {
// Create a list of runnable tasks that will be executed in separate threads
List<Callable<Integer>> callables = new ArrayList<>();
for (Node child : children)
callables.add(() -> Simulate.simulate(child));
callables.add(() -> Simulate.simulate(child, moveDictionary));

try {
// Execute all tasks. Will block until all threads have returned a value
Expand Down
70 changes: 70 additions & 0 deletions src/main/java/Tree/Simulate.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import State.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;

public class Simulate {

Expand All @@ -16,6 +18,10 @@ public static int simulate(Node node) {
return earlyTerminationPlayout(node);
}

public static int simulate(Node node, int[] moveDictionary) {
return moveDictionarySimulate(node, moveDictionary);
}

/**
* @param node
* @return The result from a completely random playout of moves
Expand Down Expand Up @@ -64,6 +70,70 @@ else if (blackControl > whiteControl)
}
}

private static int moveDictionarySimulate(Node node, int[] moveDictionary) {
final int TERMINATION_DEPTH = 20;
ArrayList<Action> actions = new ArrayList<>(Arrays.asList(node.getPossibleActions()));
int depth = 0;
State state = node.getState();
int color = node.getColour();
while(actions.size() != 0 && depth < TERMINATION_DEPTH) {
// Get the top actions from the move dictionary
int[][] queens = node.getColour() == State.BLACK_QUEEN ? node.getState().getQueens(State.BLACK_QUEEN) :
node.getState().getQueens(State.WHITE_QUEEN);
PriorityQueue<int[]> topActions = getDictionaryMoves(queens, moveDictionary);
Action selected;
do {
int[] k = topActions.poll();
selected = new Action(k[1], k[2], k[3], k[4], k[5], k[6]);
} while (!actions.contains(selected));
state = new State(state, selected);
color = color == State.BLACK_QUEEN ? State.WHITE_QUEEN : State.BLACK_QUEEN;
actions = ActionGenerator.generateActions(state, color);
depth++;
}
double heuristicValue = Heuristics.bigPoppa(state, color);
if (heuristicValue > 0)
return State.BLACK_QUEEN;
else
return State.WHITE_QUEEN;
}

private static PriorityQueue<int[]> getDictionaryMoves(int[][] queens, int[] moveDictionary) {
/*
Gets the most common actions made from our move dictionary for the queens specified in the input array. The
priority queue sorts based on the action weight (how often it is used).
*/
PriorityQueue<int[]> topActions = new PriorityQueue<>((o1, o2) -> (o2[0]) - (o1[0]));
for (int[] queen : queens) {
int x = queen[0];
int y = queen[1];
// Parse through all the possible actions
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
StringBuilder sb = new StringBuilder();
sb.append(j < 10 ? "0" + j : j + "");
sb.append(i < 10 ? "0" + i : i + "");
sb.append(y == 0 ? "0" + x : x + y * 10);
int index = Integer.parseInt(sb.toString());
int num = moveDictionary[index];
/*
The index is formatted AANNOO where OO is the old index, NN is the new index, and AA is the
index of the arrow shot. AS such, we need to extract and convert each number which is an int
from 0 to 99 into an (x,y) coordinates
*/
int oldX = index % 10;
int oldY = (index % 100) / 10;
int newX = (index % 1000) / 100;
int newY = (index % 10000) / 1000;
int arrowX = (index % 100000) / 10000;
int arrowY = (index % 1000000) / 100000;
topActions.offer(new int[]{num, oldX, oldY, newX, newY, arrowX, arrowY});
}
}
}
return topActions;
}

private static int boardControlHeuristic(State state, int colour) {
int[][] queens = state.getQueens(colour);
byte[][] board = new byte[State.BOARD_SIZE][State.BOARD_SIZE];
Expand Down