feat : add lichess cloud eval
This commit is contained in:
@@ -57,7 +57,7 @@ export const parseEvaluationResults = (
|
||||
return parsedResults;
|
||||
};
|
||||
|
||||
const sortLines = (a: LineEval, b: LineEval): number => {
|
||||
export const sortLines = (a: LineEval, b: LineEval): number => {
|
||||
if (a.mate !== undefined && b.mate !== undefined) {
|
||||
return a.mate - b.mate;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
import { parseEvaluationResults } from "./helpers/parseResults";
|
||||
import { computeAccuracy } from "./helpers/accuracy";
|
||||
import { getWhoIsCheckmated } from "../chess";
|
||||
import { getLichessEval } from "../lichess";
|
||||
|
||||
export abstract class UciEngine {
|
||||
private worker: Worker;
|
||||
@@ -143,6 +144,14 @@ export abstract class UciEngine {
|
||||
private async evaluatePosition(fen: string, depth = 16): Promise<MoveEval> {
|
||||
console.log(`Evaluating position: ${fen}`);
|
||||
|
||||
const lichessEval = await getLichessEval(fen, this.multiPv);
|
||||
if (
|
||||
lichessEval.lines.length >= this.multiPv &&
|
||||
lichessEval.lines[0].depth >= depth
|
||||
) {
|
||||
return lichessEval;
|
||||
}
|
||||
|
||||
const results = await this.sendCommands(
|
||||
[`position fen ${fen}`, `go depth ${depth}`],
|
||||
"bestmove"
|
||||
@@ -161,6 +170,8 @@ export abstract class UciEngine {
|
||||
}: EvaluatePositionWithUpdateParams): Promise<void> {
|
||||
this.throwErrorIfNotReady();
|
||||
|
||||
const lichessEvalPromise = getLichessEval(fen, multiPv);
|
||||
|
||||
await this.stopSearch();
|
||||
await this.setMultiPv(multiPv);
|
||||
|
||||
@@ -172,6 +183,16 @@ export abstract class UciEngine {
|
||||
};
|
||||
|
||||
console.log(`Evaluating position: ${fen}`);
|
||||
|
||||
const lichessEval = await lichessEvalPromise;
|
||||
if (
|
||||
lichessEval.lines.length >= multiPv &&
|
||||
lichessEval.lines[0].depth >= depth
|
||||
) {
|
||||
setPartialEval(lichessEval);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.sendCommands(
|
||||
[`position fen ${fen}`, `go depth ${depth}`],
|
||||
"bestmove",
|
||||
|
||||
51
src/lib/lichess.ts
Normal file
51
src/lib/lichess.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { LineEval, MoveEval } from "@/types/eval";
|
||||
import { sortLines } from "./engine/helpers/parseResults";
|
||||
import {
|
||||
LichessError,
|
||||
LichessEvalBody,
|
||||
LichessResponse,
|
||||
} from "@/types/lichess";
|
||||
|
||||
export const getLichessEval = async (
|
||||
fen: string,
|
||||
multiPv = 1
|
||||
): Promise<MoveEval> => {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`https://lichess.org/api/cloud-eval?fen=${fen}&multiPv=${multiPv}`
|
||||
);
|
||||
|
||||
const data: LichessResponse<LichessEvalBody> = await res.json();
|
||||
|
||||
if ("error" in data) {
|
||||
if (data.error === LichessError.NotFound) {
|
||||
return {
|
||||
bestMove: "",
|
||||
lines: [],
|
||||
};
|
||||
}
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
const lines: LineEval[] = data.pvs.map((pv, index) => ({
|
||||
pv: pv.moves.split(" "),
|
||||
cp: pv.cp,
|
||||
mate: pv.mate,
|
||||
depth: data.depth,
|
||||
multiPv: index + 1,
|
||||
}));
|
||||
|
||||
lines.sort(sortLines);
|
||||
|
||||
return {
|
||||
bestMove: lines[0].pv[0],
|
||||
lines: lines.slice(0, multiPv),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
bestMove: "",
|
||||
lines: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -47,7 +47,7 @@ export default function LineEvaluation({ line }: Props) {
|
||||
maxWidth={{ xs: "15em", sm: "25em", md: "30em", lg: "25em" }}
|
||||
>
|
||||
{showSkeleton ? (
|
||||
<Skeleton variant="rounded" animation="wave" />
|
||||
<Skeleton variant="rounded" animation="wave" width="15em" />
|
||||
) : (
|
||||
line.pv.map(moveLineUciToSan(board.fen())).join(", ")
|
||||
)}
|
||||
|
||||
18
src/types/lichess.ts
Normal file
18
src/types/lichess.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export interface LichessErrorBody {
|
||||
error: string | LichessError;
|
||||
}
|
||||
|
||||
export interface LichessEvalBody {
|
||||
depth: number;
|
||||
pvs: {
|
||||
moves: string;
|
||||
cp?: number;
|
||||
mate?: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
export type LichessResponse<T> = T | LichessErrorBody;
|
||||
|
||||
export enum LichessError {
|
||||
NotFound = "Not found",
|
||||
}
|
||||
Reference in New Issue
Block a user