I’m learning java and wrote a recursive function search
to find the best move in a simple board game for one player using brute force.
class Game {
class Move{
int x, y, value;
//constructors
};
class Board{}; //and all necessary functions
private Move search(Board board) {
if (gameOver(board)) {
return new Move(evaluateBoard(board));
}
var bestMove = new Move();
for (var move : getMoves(board)) {
move.value = search(makeMove(board, move)).value;
if (move.value > bestMove.value) {
bestMove = move;
}
}
return bestMove;
}
}
Now I’m trying to make multi-threaded searchParallel
. I can’t use the fork and join
framework because I can’t split the function into independent parts. I tried the following but it doesn’t work
AtomicInteger threadCount = new AtomicInteger();
private static final int MAX_THREADS = 10;
ExecutorService executorService = Executors.newFixedThreadPool(MAX_THREADS);
private Move searchParallel(Board board) throws InterruptedException, ExecutionException {
if (gameOver(board)) {
return new Move(evaluateBoard(board));
}
List<Callable<Move>> tasks = new ArrayList<>();
var lock = new Object();
var bestMove = new Move();
for (var move : getMoves(board)) {
if(threadCount.get() < MAX_THREADS){
threadCount.incrementAndGet();
tasks.add(() -> {
var bestMove1 = new Move();
move.value = searchParallel(makeMove(board, move)).value;
synchronized (lock){
if (move.value > bestMove1.value) {
bestMove1 = move;
}
}
threadCount.decrementAndGet();
return bestMove1;
});
}
else {
move.value = searchParallel(makeMove(board, move)).value;
synchronized (lock) {
if (move.value > bestMove.value) {
bestMove = move;
}
}
}
}
var results = executorService.invokeAll(tasks);
for(var move : results){
if (move.get().value > bestMove.value) {
bestMove = move.get();
}
}
return bestMove;
}