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
141 changes: 141 additions & 0 deletions src/main/java/State/ActionGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,145 @@ private static ArrayList<Action> getActionsFromNewQueenPos(int oldX, int oldY, i

return moves;
}

public static int generateNumberOfActions(State state, int color, int depth) {
int count = 0;
int[][] queenPos = state.getQueens(color);
for (int[] oldPos : queenPos) {
// Up
for (int y = oldPos[1] + 1; y < State.BOARD_SIZE; y++) {
if (state.getPos(oldPos[0], y) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], oldPos[0], y, state);
else
break;
}

// Down
for (int y = oldPos[1] - 1; y >= 0; y--) {
if (state.getPos(oldPos[0], y) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], oldPos[0], y, state);
else
break;
}

// Left
for (int x = oldPos[0] - 1; x >= 0; x--) {
if (state.getPos(x, oldPos[1]) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], x, oldPos[1], state);
else
break;
}

// Right
for (int x = oldPos[0] + 1; x < State.BOARD_SIZE; x++) {
if (state.getPos(x, oldPos[1]) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], x, oldPos[1], state);
else
break;
}

// Up right
for (int offset = 1; offset <= Math.min(State.BOARD_SIZE - 1 - oldPos[0], State.BOARD_SIZE - 1 - oldPos[1]); offset++) {
if (state.getPos(oldPos[0] + offset, oldPos[1] + offset) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], oldPos[0] + offset, oldPos[1] + offset, state);
else
break;
}

// Up Left
for (int offset = 1; offset <= Math.min(oldPos[0], State.BOARD_SIZE - 1 - oldPos[1]); offset++) {
if (state.getPos(oldPos[0] - offset, oldPos[1] + offset) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], oldPos[0] - offset, oldPos[1] + offset, state);
else
break;
}


// Down left
for (int offset = 1; offset <= Math.min(oldPos[0], oldPos[1]); offset++) {
if (state.getPos(oldPos[0] - offset, oldPos[1] - offset) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], oldPos[0] - offset, oldPos[1] - offset, state);
else
break;
}

// Down right
for (int offset = 1; offset <= Math.min(State.BOARD_SIZE - 1 - oldPos[0], oldPos[1]); offset++) {
if (state.getPos(oldPos[0] + offset, oldPos[1] - offset) == 0)
count += getNumActionsFromNewQueenPos(oldPos[0], oldPos[1], oldPos[0] + offset, oldPos[1] - offset, state);
else
break;
}
}
return count;
}

private static int getNumActionsFromNewQueenPos(int oldX, int oldY, int newX, int newY, State state) {
int count = 0;
// Up
for (int y = newY + 1; y < State.BOARD_SIZE; y++) {
if ((newX == oldX && y == oldY) || state.getPos(newX, y) == 0)
count++;
else
break;
}

// Down
for (int y = newY - 1; y >= 0; y--) {
if ((newX == oldX && y == oldY) || state.getPos(newX, y) == 0)
count++;
else
break;
}

// Left
for (int x = newX - 1; x >= 0; x--) {
if ((x == oldX && newY == oldY) || state.getPos(x, newY) == 0)
count++;
else
break;
}

// Right
for (int x = newX + 1; x < State.BOARD_SIZE; x++) {
if ((x == oldX && newY == oldY) || state.getPos(x, newY) == 0)
count++;
else
break;
}

// Up right
for (int offset = 1; offset <= Math.min(State.BOARD_SIZE - 1 - newX, State.BOARD_SIZE - 1 - newY); offset++) {
if ((newX + offset == oldX && newY + offset == oldY) || state.getPos(newX + offset, newY + offset) == 0)
count++;
else
break;
}

// Up Left
for (int offset = 1; offset <= Math.min(newX, State.BOARD_SIZE - 1 - newY); offset++) {
if ((newX - offset == oldX && newY + offset == oldY) || state.getPos(newX - offset, newY + offset) == 0)
count++;
else
break;
}

// Down left
for (int offset = 1; offset <= Math.min(newX, newY); offset++) {
if ((newX - offset == oldX && newY - offset == oldY) || state.getPos(newX - offset, newY - offset) == 0)
count++;
else
break;
}

// Down right
for (int offset = 1; offset <= Math.min(State.BOARD_SIZE - 1 - newX, newY); offset++) {
if ((newX + offset == oldX && newY - offset == oldY) || state.getPos(newX + offset, newY - offset) == 0)
count++;
else
break;
}

return count;
}
}
60 changes: 59 additions & 1 deletion 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.Random;
import java.util.Stack;

public class Simulate {

Expand All @@ -13,7 +15,7 @@ public class Simulate {
* @return The player that won. Either State.BLACK or State.WHITE
*/
public static int simulate(Node node) {
return earlyTerminationPlayout(node);
return numberOfMovesSimulation(node);
}

/**
Expand Down Expand Up @@ -64,6 +66,62 @@ else if (blackControl > whiteControl)
}
}

private static int numberOfMovesSimulation(Node node) {
int i = 0;
final int TERMINATION_DEPTH = 20;
State state = new State(node.getState(), node.getAction());
int color = node.getColour();
int depth = node.getDepth();
ArrayList<Action> actions = ActionGenerator.generateActions(state, color, depth);
Action selectedAction;
while (actions.size() != 0 && i < TERMINATION_DEPTH) {
// Try this on 20 random moves
Stack<Integer> indices = new Stack<>();
int listLength = actions.size();
if (listLength > 100) {
Random random = new Random();
for (int k = 0; k < 20; k++) {
indices.add(random.nextInt(listLength));
}
} else {
for (int k = 0; k < listLength; k++)
indices.add(k);
}
// Calculate the number of moves for each action
int k = 0;
int maxScoreIndex = 0;
int maxNumberMoves = 0;
depth++;
color = (color == State.BLACK_QUEEN) ? State.WHITE_QUEEN : State.BLACK_QUEEN;
while (!indices.empty()) {
Action nextAction = actions.get(indices.pop());
State nextState = new State(state, nextAction);
int numMoves = ActionGenerator.generateNumberOfActions(nextState, color, depth);
if (numMoves > maxNumberMoves) {
maxNumberMoves = numMoves;
maxScoreIndex = k;
}
k++;
}
selectedAction = actions.get(maxScoreIndex);
state = new State(state, selectedAction);
actions = ActionGenerator.generateActions(state, color, depth);
i++;
}
if (i < TERMINATION_DEPTH)
return color == State.BLACK_QUEEN ? State.WHITE_QUEEN : State.BLACK_QUEEN;
else {
int blackControl = boardControlHeuristic(state, State.BLACK_QUEEN);
int whiteControl = boardControlHeuristic(state, State.WHITE_QUEEN);
if (blackControl == whiteControl)
return 0;
else if (blackControl > whiteControl)
return State.BLACK_QUEEN;
else
return State.WHITE_QUEEN;
}
}

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