feat : add engines choices
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "/engines/stockfish-wasm/stockfish-nnue-16.js",
|
"source": "/engines/**",
|
||||||
"headers": [
|
"headers": [
|
||||||
{
|
{
|
||||||
"key": "Cross-Origin-Embedder-Policy",
|
"key": "Cross-Origin-Embedder-Policy",
|
||||||
@@ -30,6 +30,19 @@
|
|||||||
{
|
{
|
||||||
"key": "Cross-Origin-Opener-Policy",
|
"key": "Cross-Origin-Opener-Policy",
|
||||||
"value": "same-origin"
|
"value": "same-origin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Cache-Control",
|
||||||
|
"value": "public, max-age=3600, immutable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "/engines/stockfish-16-wasm/nn-5af11540bbfe.nnue",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"key": "Cache-Control",
|
||||||
|
"value": "public, max-age=31536000, immutable"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const nextConfig = (phase) =>
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
source: "/engines/stockfish-wasm/stockfish-nnue-16.js",
|
source: "/engines/:blob*",
|
||||||
headers: [
|
headers: [
|
||||||
{
|
{
|
||||||
key: "Cross-Origin-Embedder-Policy",
|
key: "Cross-Origin-Embedder-Policy",
|
||||||
|
|||||||
BIN
public/engines/stockfish-16-wasm/nn-5af11540bbfe.nnue
Normal file
BIN
public/engines/stockfish-16-wasm/nn-5af11540bbfe.nnue
Normal file
Binary file not shown.
14
public/engines/stockfish-16-wasm/stockfish-nnue-16-single.js
Normal file
14
public/engines/stockfish-16-wasm/stockfish-nnue-16-single.js
Normal file
File diff suppressed because one or more lines are too long
BIN
public/engines/stockfish-16-wasm/stockfish-nnue-16-single.wasm
Normal file
BIN
public/engines/stockfish-16-wasm/stockfish-nnue-16-single.wasm
Normal file
Binary file not shown.
@@ -1,3 +1,4 @@
|
|||||||
|
import { Stockfish11 } from "@/lib/engine/stockfish11";
|
||||||
import { Stockfish16 } from "@/lib/engine/stockfish16";
|
import { Stockfish16 } from "@/lib/engine/stockfish16";
|
||||||
import { UciEngine } from "@/lib/engine/uciEngine";
|
import { UciEngine } from "@/lib/engine/uciEngine";
|
||||||
import { EngineName } from "@/types/enums";
|
import { EngineName } from "@/types/enums";
|
||||||
@@ -9,6 +10,10 @@ export const useEngine = (engineName: EngineName | undefined) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!engineName) return;
|
if (!engineName) return;
|
||||||
|
|
||||||
|
if (engineName.includes("stockfish_16") && !Stockfish16.isSupported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const engine = pickEngine(engineName);
|
const engine = pickEngine(engineName);
|
||||||
engine.init().then(() => {
|
engine.init().then(() => {
|
||||||
setEngine(engine);
|
setEngine(engine);
|
||||||
@@ -25,6 +30,12 @@ export const useEngine = (engineName: EngineName | undefined) => {
|
|||||||
const pickEngine = (engine: EngineName): UciEngine => {
|
const pickEngine = (engine: EngineName): UciEngine => {
|
||||||
switch (engine) {
|
switch (engine) {
|
||||||
case EngineName.Stockfish16:
|
case EngineName.Stockfish16:
|
||||||
return new Stockfish16();
|
return new Stockfish16(false);
|
||||||
|
case EngineName.Stockfish16NNUE:
|
||||||
|
return new Stockfish16(true);
|
||||||
|
case EngineName.Stockfish11:
|
||||||
|
return new Stockfish11();
|
||||||
|
default:
|
||||||
|
throw new Error(`Engine ${engine} does not exist ?!`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
8
src/lib/engine/stockfish11.ts
Normal file
8
src/lib/engine/stockfish11.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { EngineName } from "@/types/enums";
|
||||||
|
import { UciEngine } from "./uciEngine";
|
||||||
|
|
||||||
|
export class Stockfish11 extends UciEngine {
|
||||||
|
constructor() {
|
||||||
|
super(EngineName.Stockfish11, "engines/stockfish-11.js");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,17 +2,29 @@ import { EngineName } from "@/types/enums";
|
|||||||
import { UciEngine } from "./uciEngine";
|
import { UciEngine } from "./uciEngine";
|
||||||
|
|
||||||
export class Stockfish16 extends UciEngine {
|
export class Stockfish16 extends UciEngine {
|
||||||
constructor() {
|
constructor(nnue?: boolean) {
|
||||||
const isWasmSupported = Stockfish16.isWasmSupported();
|
if (!Stockfish16.isSupported()) {
|
||||||
|
throw new Error("Stockfish 16 is not supported");
|
||||||
const enginePath = isWasmSupported
|
|
||||||
? "engines/stockfish-wasm/stockfish-nnue-16.js"
|
|
||||||
: "engines/stockfish.js";
|
|
||||||
|
|
||||||
super(EngineName.Stockfish16, enginePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static isWasmSupported() {
|
const isMultiThreadSupported = Stockfish16.isMultiThreadSupported();
|
||||||
|
if (!isMultiThreadSupported) console.log("Single thread mode");
|
||||||
|
|
||||||
|
const enginePath = isMultiThreadSupported
|
||||||
|
? "engines/stockfish-16-wasm/stockfish-nnue-16.js"
|
||||||
|
: "engines/stockfish-16-wasm/stockfish-nnue-16-single.js";
|
||||||
|
|
||||||
|
const customEngineInit = async () => {
|
||||||
|
await this.sendCommands(
|
||||||
|
[`setoption name Use NNUE value ${!!nnue}`, "isready"],
|
||||||
|
"readyok"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
super(EngineName.Stockfish16, enginePath, customEngineInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static isSupported() {
|
||||||
return (
|
return (
|
||||||
typeof WebAssembly === "object" &&
|
typeof WebAssembly === "object" &&
|
||||||
WebAssembly.validate(
|
WebAssembly.validate(
|
||||||
@@ -20,4 +32,8 @@ export class Stockfish16 extends UciEngine {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static isMultiThreadSupported() {
|
||||||
|
return SharedArrayBuffer !== undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,16 @@ export abstract class UciEngine {
|
|||||||
private engineName: EngineName;
|
private engineName: EngineName;
|
||||||
private multiPv = 3;
|
private multiPv = 3;
|
||||||
private skillLevel: number | undefined = undefined;
|
private skillLevel: number | undefined = undefined;
|
||||||
|
private customEngineInit?: () => Promise<void>;
|
||||||
|
|
||||||
constructor(engineName: EngineName, enginePath: string) {
|
constructor(
|
||||||
|
engineName: EngineName,
|
||||||
|
enginePath: string,
|
||||||
|
customEngineInit?: () => Promise<void>
|
||||||
|
) {
|
||||||
this.engineName = engineName;
|
this.engineName = engineName;
|
||||||
this.worker = new Worker(enginePath);
|
this.worker = new Worker(enginePath);
|
||||||
|
this.customEngineInit = customEngineInit;
|
||||||
|
|
||||||
console.log(`${engineName} created`);
|
console.log(`${engineName} created`);
|
||||||
}
|
}
|
||||||
@@ -31,6 +37,7 @@ export abstract class UciEngine {
|
|||||||
public async init(): Promise<void> {
|
public async init(): Promise<void> {
|
||||||
await this.sendCommands(["uci"], "uciok");
|
await this.sendCommands(["uci"], "uciok");
|
||||||
await this.setMultiPv(this.multiPv, true);
|
await this.setMultiPv(this.multiPv, true);
|
||||||
|
await this.customEngineInit?.();
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
console.log(`${this.engineName} initialized`);
|
console.log(`${this.engineName} initialized`);
|
||||||
}
|
}
|
||||||
@@ -94,7 +101,7 @@ export abstract class UciEngine {
|
|||||||
await this.sendCommands(["stop", "isready"], "readyok");
|
await this.sendCommands(["stop", "isready"], "readyok");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sendCommands(
|
protected async sendCommands(
|
||||||
commands: string[],
|
commands: string[],
|
||||||
finalMessage: string,
|
finalMessage: string,
|
||||||
onNewMessage?: (messages: string[]) => void
|
onNewMessage?: (messages: string[]) => void
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
import { Grid, List, Typography } from "@mui/material";
|
import { Grid, List, Typography } from "@mui/material";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
import { boardAtom, engineMultiPvAtom, gameAtom } from "../states";
|
import {
|
||||||
|
boardAtom,
|
||||||
|
engineMultiPvAtom,
|
||||||
|
engineNameAtom,
|
||||||
|
gameAtom,
|
||||||
|
} from "../states";
|
||||||
import LineEvaluation from "./lineEvaluation";
|
import LineEvaluation from "./lineEvaluation";
|
||||||
import { useCurrentPosition } from "../hooks/useCurrentPosition";
|
import { useCurrentPosition } from "../hooks/useCurrentPosition";
|
||||||
import { LineEval } from "@/types/eval";
|
import { LineEval } from "@/types/eval";
|
||||||
import { EngineName } from "@/types/enums";
|
|
||||||
import EngineSettingsButton from "@/sections/engineSettings/engineSettingsButton";
|
import EngineSettingsButton from "@/sections/engineSettings/engineSettingsButton";
|
||||||
import Accuracies from "./accuracies";
|
import Accuracies from "./accuracies";
|
||||||
import MoveInfo from "./moveInfo";
|
import MoveInfo from "./moveInfo";
|
||||||
@@ -13,7 +17,8 @@ import Opening from "./opening";
|
|||||||
|
|
||||||
export default function ReviewPanelBody() {
|
export default function ReviewPanelBody() {
|
||||||
const linesNumber = useAtomValue(engineMultiPvAtom);
|
const linesNumber = useAtomValue(engineMultiPvAtom);
|
||||||
const position = useCurrentPosition(EngineName.Stockfish16);
|
const engineName = useAtomValue(engineNameAtom);
|
||||||
|
const position = useCurrentPosition(engineName);
|
||||||
const game = useAtomValue(gameAtom);
|
const game = useAtomValue(gameAtom);
|
||||||
const board = useAtomValue(boardAtom);
|
const board = useAtomValue(boardAtom);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Icon } from "@iconify/react";
|
|||||||
import {
|
import {
|
||||||
engineDepthAtom,
|
engineDepthAtom,
|
||||||
engineMultiPvAtom,
|
engineMultiPvAtom,
|
||||||
|
engineNameAtom,
|
||||||
evaluationProgressAtom,
|
evaluationProgressAtom,
|
||||||
gameAtom,
|
gameAtom,
|
||||||
gameEvalAtom,
|
gameEvalAtom,
|
||||||
@@ -11,11 +12,11 @@ import { getEvaluateGameParams } from "@/lib/chess";
|
|||||||
import { useGameDatabase } from "@/hooks/useGameDatabase";
|
import { useGameDatabase } from "@/hooks/useGameDatabase";
|
||||||
import { LoadingButton } from "@mui/lab";
|
import { LoadingButton } from "@mui/lab";
|
||||||
import { useEngine } from "@/hooks/useEngine";
|
import { useEngine } from "@/hooks/useEngine";
|
||||||
import { EngineName } from "@/types/enums";
|
|
||||||
import { logAnalyticsEvent } from "@/lib/firebase";
|
import { logAnalyticsEvent } from "@/lib/firebase";
|
||||||
|
|
||||||
export default function AnalyzeButton() {
|
export default function AnalyzeButton() {
|
||||||
const engine = useEngine(EngineName.Stockfish16);
|
const engineName = useAtomValue(engineNameAtom);
|
||||||
|
const engine = useEngine(engineName);
|
||||||
const [evaluationProgress, setEvaluationProgress] = useAtom(
|
const [evaluationProgress, setEvaluationProgress] = useAtom(
|
||||||
evaluationProgressAtom
|
evaluationProgressAtom
|
||||||
);
|
);
|
||||||
@@ -49,7 +50,7 @@ export default function AnalyzeButton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logAnalyticsEvent("analyze_game", {
|
logAnalyticsEvent("analyze_game", {
|
||||||
engine: EngineName.Stockfish16,
|
engine: engineName,
|
||||||
depth: engineDepth,
|
depth: engineDepth,
|
||||||
multiPv: engineMultiPv,
|
multiPv: engineMultiPv,
|
||||||
nbPositions: params.fens.length,
|
nbPositions: params.fens.length,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { EngineName } from "@/types/enums";
|
||||||
import { CurrentPosition, GameEval } from "@/types/eval";
|
import { CurrentPosition, GameEval } from "@/types/eval";
|
||||||
import { Chess } from "chess.js";
|
import { Chess } from "chess.js";
|
||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
@@ -11,6 +12,7 @@ export const boardOrientationAtom = atom(true);
|
|||||||
export const showBestMoveArrowAtom = atom(true);
|
export const showBestMoveArrowAtom = atom(true);
|
||||||
export const showPlayerMoveIconAtom = atom(true);
|
export const showPlayerMoveIconAtom = atom(true);
|
||||||
|
|
||||||
|
export const engineNameAtom = atom<EngineName>(EngineName.Stockfish16);
|
||||||
export const engineDepthAtom = atom(16);
|
export const engineDepthAtom = atom(16);
|
||||||
export const engineMultiPvAtom = atom(3);
|
export const engineMultiPvAtom = atom(3);
|
||||||
export const evaluationProgressAtom = atom(0);
|
export const evaluationProgressAtom = atom(0);
|
||||||
|
|||||||
@@ -14,9 +14,15 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
Grid,
|
Grid,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { engineDepthAtom, engineMultiPvAtom } from "../analysis/states";
|
import {
|
||||||
|
engineNameAtom,
|
||||||
|
engineDepthAtom,
|
||||||
|
engineMultiPvAtom,
|
||||||
|
} from "../analysis/states";
|
||||||
import ArrowOptions from "./arrowOptions";
|
import ArrowOptions from "./arrowOptions";
|
||||||
import { useAtomLocalStorage } from "@/hooks/useAtomLocalStorage";
|
import { useAtomLocalStorage } from "@/hooks/useAtomLocalStorage";
|
||||||
|
import { Stockfish16 } from "@/lib/engine/stockfish16";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -32,6 +38,16 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
|
|||||||
"engine-multi-pv",
|
"engine-multi-pv",
|
||||||
engineMultiPvAtom
|
engineMultiPvAtom
|
||||||
);
|
);
|
||||||
|
const [engineName, setEngineName] = useAtomLocalStorage(
|
||||||
|
"engine-name",
|
||||||
|
engineNameAtom
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!Stockfish16.isSupported()) {
|
||||||
|
setEngineName(EngineName.Stockfish11);
|
||||||
|
}
|
||||||
|
}, [setEngineName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
||||||
@@ -40,8 +56,10 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
|
|||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent sx={{ paddingBottom: 0 }}>
|
<DialogContent sx={{ paddingBottom: 0 }}>
|
||||||
<Typography>
|
<Typography>
|
||||||
Stockfish 16 is the only engine available now, more engine choices
|
Stockfish 16 Lite (HCE) is the default engine. It offers the best
|
||||||
will come soon !
|
balance between speed and strength. Stockfish 16 is the strongest
|
||||||
|
engine available, but please note that it requires a one time download
|
||||||
|
of 40MB.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid
|
<Grid
|
||||||
marginTop={4}
|
marginTop={4}
|
||||||
@@ -60,12 +78,20 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
|
|||||||
id="dialog-select"
|
id="dialog-select"
|
||||||
displayEmpty
|
displayEmpty
|
||||||
input={<OutlinedInput label="Engine" />}
|
input={<OutlinedInput label="Engine" />}
|
||||||
value={EngineName.Stockfish16}
|
value={engineName}
|
||||||
disabled={true}
|
onChange={(e) => setEngineName(e.target.value as EngineName)}
|
||||||
sx={{ width: 200 }}
|
sx={{ width: 280, maxWidth: "100%" }}
|
||||||
>
|
>
|
||||||
{Object.values(EngineName).map((engine) => (
|
{Object.values(EngineName).map((engine) => (
|
||||||
<MenuItem key={engine} value={engine}>
|
<MenuItem
|
||||||
|
key={engine}
|
||||||
|
value={engine}
|
||||||
|
disabled={
|
||||||
|
engine.includes("stockfish_16")
|
||||||
|
? !Stockfish16.isSupported()
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
>
|
||||||
{engineLabel[engine]}
|
{engineLabel[engine]}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
@@ -104,5 +130,7 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const engineLabel: Record<EngineName, string> = {
|
const engineLabel: Record<EngineName, string> = {
|
||||||
[EngineName.Stockfish16]: "Stockfish 16",
|
[EngineName.Stockfish16]: "Stockfish 16 Lite (HCE)",
|
||||||
|
[EngineName.Stockfish16NNUE]: "Stockfish 16 (40MB download)",
|
||||||
|
[EngineName.Stockfish11]: "Stockfish 11",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import {
|
|||||||
playerColorAtom,
|
playerColorAtom,
|
||||||
isGameInProgressAtom,
|
isGameInProgressAtom,
|
||||||
gameDataAtom,
|
gameDataAtom,
|
||||||
|
enginePlayNameAtom,
|
||||||
} from "./states";
|
} from "./states";
|
||||||
import { useChessActions } from "@/hooks/useChessActions";
|
import { useChessActions } from "@/hooks/useChessActions";
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
import { useScreenSize } from "@/hooks/useScreenSize";
|
import { useScreenSize } from "@/hooks/useScreenSize";
|
||||||
import { Color, EngineName } from "@/types/enums";
|
import { Color } from "@/types/enums";
|
||||||
import { useEngine } from "@/hooks/useEngine";
|
import { useEngine } from "@/hooks/useEngine";
|
||||||
import { uciMoveParams } from "@/lib/chess";
|
import { uciMoveParams } from "@/lib/chess";
|
||||||
import Board from "@/components/board";
|
import Board from "@/components/board";
|
||||||
@@ -17,7 +18,8 @@ import { useGameData } from "@/hooks/useGameData";
|
|||||||
|
|
||||||
export default function BoardContainer() {
|
export default function BoardContainer() {
|
||||||
const screenSize = useScreenSize();
|
const screenSize = useScreenSize();
|
||||||
const engine = useEngine(EngineName.Stockfish16);
|
const engineName = useAtomValue(enginePlayNameAtom);
|
||||||
|
const engine = useEngine(engineName);
|
||||||
const game = useAtomValue(gameAtom);
|
const game = useAtomValue(gameAtom);
|
||||||
const playerColor = useAtomValue(playerColorAtom);
|
const playerColor = useAtomValue(playerColorAtom);
|
||||||
const { makeMove: makeGameMove } = useChessActions(gameAtom);
|
const { makeMove: makeGameMove } = useChessActions(gameAtom);
|
||||||
|
|||||||
@@ -24,10 +24,13 @@ import {
|
|||||||
playerColorAtom,
|
playerColorAtom,
|
||||||
isGameInProgressAtom,
|
isGameInProgressAtom,
|
||||||
gameAtom,
|
gameAtom,
|
||||||
|
enginePlayNameAtom,
|
||||||
} from "../states";
|
} from "../states";
|
||||||
import { useChessActions } from "@/hooks/useChessActions";
|
import { useChessActions } from "@/hooks/useChessActions";
|
||||||
import { playGameStartSound } from "@/lib/sounds";
|
import { playGameStartSound } from "@/lib/sounds";
|
||||||
import { logAnalyticsEvent } from "@/lib/firebase";
|
import { logAnalyticsEvent } from "@/lib/firebase";
|
||||||
|
import { Stockfish16 } from "@/lib/engine/stockfish16";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -39,6 +42,10 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
|
|||||||
"engine-skill-level",
|
"engine-skill-level",
|
||||||
engineSkillLevelAtom
|
engineSkillLevelAtom
|
||||||
);
|
);
|
||||||
|
const [engineName, setEngineName] = useAtomLocalStorage(
|
||||||
|
"engine-play-name",
|
||||||
|
enginePlayNameAtom
|
||||||
|
);
|
||||||
const [playerColor, setPlayerColor] = useAtom(playerColorAtom);
|
const [playerColor, setPlayerColor] = useAtom(playerColorAtom);
|
||||||
const setIsGameInProgress = useSetAtom(isGameInProgressAtom);
|
const setIsGameInProgress = useSetAtom(isGameInProgressAtom);
|
||||||
const { reset: resetGame } = useChessActions(gameAtom);
|
const { reset: resetGame } = useChessActions(gameAtom);
|
||||||
@@ -55,12 +62,18 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
|
|||||||
setIsGameInProgress(true);
|
setIsGameInProgress(true);
|
||||||
|
|
||||||
logAnalyticsEvent("play_game", {
|
logAnalyticsEvent("play_game", {
|
||||||
engine: EngineName.Stockfish16,
|
engine: engineName,
|
||||||
skillLevel,
|
skillLevel,
|
||||||
playerColor,
|
playerColor,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!Stockfish16.isSupported()) {
|
||||||
|
setEngineName(EngineName.Stockfish11);
|
||||||
|
}
|
||||||
|
}, [setEngineName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
||||||
<DialogTitle marginY={1} variant="h5">
|
<DialogTitle marginY={1} variant="h5">
|
||||||
@@ -68,8 +81,10 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
|
|||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent sx={{ paddingBottom: 0 }}>
|
<DialogContent sx={{ paddingBottom: 0 }}>
|
||||||
<Typography>
|
<Typography>
|
||||||
Stockfish 16 is the only engine available now, more engine choices
|
Stockfish 16 Lite (HCE) is the default engine. It offers the best
|
||||||
will come soon !
|
balance between speed and strength. Stockfish 16 is the strongest
|
||||||
|
engine available, but please note that it requires a one time download
|
||||||
|
of 40MB.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid
|
<Grid
|
||||||
marginTop={4}
|
marginTop={4}
|
||||||
@@ -88,12 +103,20 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
|
|||||||
id="dialog-select"
|
id="dialog-select"
|
||||||
displayEmpty
|
displayEmpty
|
||||||
input={<OutlinedInput label="Engine" />}
|
input={<OutlinedInput label="Engine" />}
|
||||||
value={EngineName.Stockfish16}
|
value={engineName}
|
||||||
disabled={true}
|
onChange={(e) => setEngineName(e.target.value as EngineName)}
|
||||||
sx={{ width: 200 }}
|
sx={{ width: 280, maxWidth: "100%" }}
|
||||||
>
|
>
|
||||||
{Object.values(EngineName).map((engine) => (
|
{Object.values(EngineName).map((engine) => (
|
||||||
<MenuItem key={engine} value={engine}>
|
<MenuItem
|
||||||
|
key={engine}
|
||||||
|
value={engine}
|
||||||
|
disabled={
|
||||||
|
engine.includes("stockfish_16")
|
||||||
|
? !Stockfish16.isSupported()
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
>
|
||||||
{engineLabel[engine]}
|
{engineLabel[engine]}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
@@ -145,5 +168,7 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const engineLabel: Record<EngineName, string> = {
|
const engineLabel: Record<EngineName, string> = {
|
||||||
[EngineName.Stockfish16]: "Stockfish 16",
|
[EngineName.Stockfish16]: "Stockfish 16 Lite (HCE)",
|
||||||
|
[EngineName.Stockfish16NNUE]: "Stockfish 16 (40MB download)",
|
||||||
|
[EngineName.Stockfish11]: "Stockfish 11",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Color } from "@/types/enums";
|
import { Color, EngineName } from "@/types/enums";
|
||||||
import { CurrentPosition } from "@/types/eval";
|
import { CurrentPosition } from "@/types/eval";
|
||||||
import { Chess } from "chess.js";
|
import { Chess } from "chess.js";
|
||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
@@ -6,5 +6,6 @@ import { atom } from "jotai";
|
|||||||
export const gameAtom = atom(new Chess());
|
export const gameAtom = atom(new Chess());
|
||||||
export const gameDataAtom = atom<CurrentPosition>({});
|
export const gameDataAtom = atom<CurrentPosition>({});
|
||||||
export const playerColorAtom = atom<Color>(Color.White);
|
export const playerColorAtom = atom<Color>(Color.White);
|
||||||
|
export const enginePlayNameAtom = atom<EngineName>(EngineName.Stockfish16);
|
||||||
export const engineSkillLevelAtom = atom<number>(1);
|
export const engineSkillLevelAtom = atom<number>(1);
|
||||||
export const isGameInProgressAtom = atom(false);
|
export const isGameInProgressAtom = atom(false);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ export enum GameOrigin {
|
|||||||
|
|
||||||
export enum EngineName {
|
export enum EngineName {
|
||||||
Stockfish16 = "stockfish_16",
|
Stockfish16 = "stockfish_16",
|
||||||
|
Stockfish16NNUE = "stockfish_16_nnue",
|
||||||
|
Stockfish11 = "stockfish_11",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MoveClassification {
|
export enum MoveClassification {
|
||||||
|
|||||||
Reference in New Issue
Block a user