prevent RCHOICES from being shared across calls, to address #479
the next call always clobbers this global and will cause the previous running thread to crash, its value is only useful in the current callmaster
parent
a91b8418b2
commit
14dcb5ac95
|
@ -96,9 +96,6 @@ public class MCTSAI implements MagicAI {
|
|||
|
||||
private final boolean CHEAT;
|
||||
|
||||
//cache the set of choices at the root to avoid recomputing it all the time
|
||||
private List<Object[]> RCHOICES;
|
||||
|
||||
//cache nodes to reuse them in later decision
|
||||
private final LRUCache<Long, MCTSGameTree> CACHE = new LRUCache<Long, MCTSGameTree>(1000);
|
||||
|
||||
|
@ -118,7 +115,7 @@ public class MCTSAI implements MagicAI {
|
|||
aiGame.hideHiddenCards();
|
||||
}
|
||||
final MagicEvent event = aiGame.getNextEvent();
|
||||
RCHOICES = event.getArtificialChoiceResults(aiGame);
|
||||
final List<Object[]> RCHOICES = event.getArtificialChoiceResults(aiGame);
|
||||
|
||||
final int size = RCHOICES.size();
|
||||
|
||||
|
@ -146,7 +143,7 @@ public class MCTSAI implements MagicAI {
|
|||
final Runnable updateTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TreeUpdate(this, root, aiGame, executor, queue, END_TIME);
|
||||
TreeUpdate(this, root, aiGame, executor, queue, END_TIME, RCHOICES);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -177,7 +174,7 @@ public class MCTSAI implements MagicAI {
|
|||
}
|
||||
}
|
||||
|
||||
log(outputChoice(scorePlayer, root, START_TIME, bestC, sims));
|
||||
log(outputChoice(scorePlayer, root, START_TIME, bestC, sims, RCHOICES));
|
||||
|
||||
return startGame.map(RCHOICES.get(bestC));
|
||||
}
|
||||
|
@ -217,7 +214,8 @@ public class MCTSAI implements MagicAI {
|
|||
final MagicGame aiGame,
|
||||
final ExecutorService executor,
|
||||
final BlockingQueue<Runnable> queue,
|
||||
final long END_TIME
|
||||
final long END_TIME,
|
||||
final List<Object[]> RCHOICES
|
||||
) {
|
||||
|
||||
//prioritize backpropagation tasks
|
||||
|
@ -238,7 +236,7 @@ public class MCTSAI implements MagicAI {
|
|||
//pass in a clone of the state,
|
||||
//genNewTreeNode grows the tree by one node
|
||||
//and returns the path from the root to the new node
|
||||
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
|
||||
final LinkedList<MCTSGameTree> path = growTree(root, rootGame, RCHOICES);
|
||||
|
||||
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
|
||||
|
||||
|
@ -299,7 +297,8 @@ public class MCTSAI implements MagicAI {
|
|||
final MCTSGameTree root,
|
||||
final long START_TIME,
|
||||
final int bestC,
|
||||
final int sims
|
||||
final int sims,
|
||||
final List<Object[]> RCHOICES
|
||||
) {
|
||||
|
||||
final StringBuilder out = new StringBuilder();
|
||||
|
@ -344,15 +343,15 @@ public class MCTSAI implements MagicAI {
|
|||
return out.toString().trim();
|
||||
}
|
||||
|
||||
private LinkedList<MCTSGameTree> growTree(final MCTSGameTree root, final MagicGame game) {
|
||||
private LinkedList<MCTSGameTree> growTree(final MCTSGameTree root, final MagicGame game, final List<Object[]> RCHOICES) {
|
||||
final LinkedList<MCTSGameTree> path = new LinkedList<MCTSGameTree>();
|
||||
boolean found = false;
|
||||
MCTSGameTree curr = root;
|
||||
path.add(curr);
|
||||
|
||||
for (List<Object[]> choices = getNextChoices(game);
|
||||
for (List<Object[]> choices = getNextChoices(game, RCHOICES);
|
||||
!choices.isEmpty() && !Thread.currentThread().isInterrupted();
|
||||
choices = getNextChoices(game)) {
|
||||
choices = getNextChoices(game, RCHOICES)) {
|
||||
|
||||
assert choices.size() > 0 : "ERROR! No choice at start of genNewTreeNode";
|
||||
|
||||
|
@ -491,7 +490,7 @@ public class MCTSAI implements MagicAI {
|
|||
return new int[]{aiChoices, oppChoices};
|
||||
}
|
||||
|
||||
private List<Object[]> getNextChoices(final MagicGame game) {
|
||||
private List<Object[]> getNextChoices(final MagicGame game, final List<Object[]> RCHOICES) {
|
||||
//disable fast choices
|
||||
game.setFastChoices(false);
|
||||
|
||||
|
|
Loading…
Reference in New Issue