From 2b9562d0626e0f2182e3d19cbabf54769c44c63c Mon Sep 17 00:00:00 2001 From: Hedgemon4 Date: Sat, 25 Mar 2023 11:13:14 -0700 Subject: [PATCH 1/2] Started alternate simulate --- src/main/java/Tree/Simulate.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/Tree/Simulate.java b/src/main/java/Tree/Simulate.java index 1fc49d4..c56504e 100644 --- a/src/main/java/Tree/Simulate.java +++ b/src/main/java/Tree/Simulate.java @@ -64,6 +64,10 @@ else if (blackControl > whiteControl) } } + private static int moveDictionarySimulate(Node node) { + + } + private static int boardControlHeuristic(State state, int colour) { int[][] queens = state.getQueens(colour); byte[][] board = new byte[State.BOARD_SIZE][State.BOARD_SIZE]; From 762d4f1399dc91fc3d9ec2cf0ae23f1132cdef45 Mon Sep 17 00:00:00 2001 From: Hedgemon4 Date: Sat, 25 Mar 2023 12:35:07 -0700 Subject: [PATCH 2/2] Started coding move dictionary simulation --- src/main/java/Tests/HeuristicTesting.java | 2 +- src/main/java/Tree/MonteCarloTree.java | 4 +- src/main/java/Tree/Simulate.java | 68 ++++++++++++++++++++++- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/main/java/Tests/HeuristicTesting.java b/src/main/java/Tests/HeuristicTesting.java index eade447..21c26f1 100644 --- a/src/main/java/Tests/HeuristicTesting.java +++ b/src/main/java/Tests/HeuristicTesting.java @@ -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 actions = ActionGenerator.generateActions(randomState, r.nextInt(1) + 1, 1); + ArrayList actions = ActionGenerator.generateActions(randomState, r.nextInt(1) + 1); states.add(new State(s, actions.get(r.nextInt(actions.size())))); } diff --git a/src/main/java/Tree/MonteCarloTree.java b/src/main/java/Tree/MonteCarloTree.java index e4c74b9..9f91f30 100644 --- a/src/main/java/Tree/MonteCarloTree.java +++ b/src/main/java/Tree/MonteCarloTree.java @@ -42,7 +42,7 @@ public Action search() { boolean useMoveDictionary = root.getDepth() < 8; if (useMoveDictionary) { - selectedAction = getMoveDictionaryMove(); + return getMoveDictionaryMove(); } try { while (time.timeLeft()) { @@ -59,7 +59,7 @@ public Action search() { // Create a list of runnable tasks that will be executed in separate threads List> 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 diff --git a/src/main/java/Tree/Simulate.java b/src/main/java/Tree/Simulate.java index c56504e..f087262 100644 --- a/src/main/java/Tree/Simulate.java +++ b/src/main/java/Tree/Simulate.java @@ -3,6 +3,8 @@ import State.*; import java.util.ArrayList; +import java.util.Arrays; +import java.util.PriorityQueue; public class Simulate { @@ -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 @@ -64,8 +70,68 @@ else if (blackControl > whiteControl) } } - private static int moveDictionarySimulate(Node node) { + private static int moveDictionarySimulate(Node node, int[] moveDictionary) { + final int TERMINATION_DEPTH = 20; + ArrayList 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 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 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 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) {