
com.fathzer.games.perft.ForkJoinPerfT Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of games-core Show documentation
Show all versions of games-core Show documentation
A core library to help implement two players games.
The newest version!
package com.fathzer.games.perft;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
import com.fathzer.games.MoveGenerator;
import com.fathzer.games.MoveGenerator.MoveConfidence;
/** A Perft test based on the fork/join multi-threaded framework.
* @see PerfTBuilder
*/
class ForkJoinPerfT extends MultiThreadedPerfT {
@SuppressWarnings({"serial", "java:S1948"})
private class DivideJob extends RecursiveTask> {
M move;
CountTask task;
DivideJob(M move, CountTask task) {
this.move = move;
this.task = task;
}
@Override
public Divide compute() {
return new Divide<>(move, task.compute());
}
}
@SuppressWarnings({"serial", "java:S1948"})
private class CountTask extends RecursiveTask {
private final MoveGenerator board;
private final int depth;
private final PerfTResult perftResult;
CountTask(MoveGenerator board, int depth, PerfTResult result) {
this.board = board;
this.depth = depth;
this.perftResult = result;
}
@Override
protected Long compute() {
if (isInterrupted() || depth==0) {
return 1L;
}
final List moves = getMoves(board);
perftResult.addMovesFound(moves.size());
if (depth==1 && !playLeaves) {
return (long)moves.size();
}
return depth >= 4 ? forkedCount(moves) : count(moves);
}
protected long forkedCount(final List moves) {
final Collection tasks = new ArrayList<>(moves.size());
for (M move : moves) {
if (board.makeMove(move, moveType)) {
perftResult.addMoveMade();
tasks.add(new CountTask(board.fork(), depth-1, perftResult));
board.unmakeMove();
}
}
tasks.forEach(RecursiveTask::fork);
return tasks.stream().mapToLong(ForkJoinTask::join).sum();
}
protected long count(final List moves) {
long count = 0;
for (M move : moves) {
if (board.makeMove(move, moveType)) {
perftResult.addMoveMade();
count += new CountTask(board, depth-1, perftResult).compute();
board.unmakeMove();
}
}
return count;
}
}
ForkJoinPerfT(ForkJoinPool exec, MoveGenerator board, int depth, boolean playLeaves, MoveConfidence moveType) {
super(exec, board, depth, playLeaves, moveType);
}
@Override
void compute(List moves) {
final List jobs = moves.stream().map(move -> getDivideJob(move, result)).filter(Objects::nonNull).toList();
jobs.stream().forEach(((ForkJoinPool)exec)::submit);
addDivides(jobs.stream().map(job -> (Future>) job).toList());
}
private DivideJob getDivideJob(M move, PerfTResult result) {
if (!board.makeMove(move, moveType)) {
return null;
}
result.addMoveMade();
final DivideJob job = new DivideJob(move, new CountTask(board.fork(), depth - 1, result));
board.unmakeMove();
return job;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy