diff --git a/src/components/slider.tsx b/src/components/slider.tsx
index 5459307..117a227 100644
--- a/src/components/slider.tsx
+++ b/src/components/slider.tsx
@@ -1,13 +1,13 @@
import { Grid2 as Grid, Slider as MuiSlider, Typography } from "@mui/material";
-interface Props {
+export interface Props {
value: number;
setValue: (value: number) => void;
min: number;
max: number;
label: string;
size?: number;
- marksFilter?: number;
+ step?: number;
}
export default function Slider({
@@ -17,7 +17,7 @@ export default function Slider({
value,
setValue,
size,
- marksFilter = 1,
+ step = 1,
}: Props) {
return (
- {label}
+ {`${label}: ${value}`}
({
- value: i + min,
- label: `${i + min}`,
- })).filter((_, i) => i % marksFilter === 0)}
- step={1}
- valueLabelDisplay="off"
+ step={step}
+ valueLabelDisplay="auto"
value={value}
onChange={(_, value) => setValue(value as number)}
aria-labelledby={`input-${label}`}
diff --git a/src/lib/engine/uciEngine.ts b/src/lib/engine/uciEngine.ts
index b3c145f..27bdd60 100644
--- a/src/lib/engine/uciEngine.ts
+++ b/src/lib/engine/uciEngine.ts
@@ -92,6 +92,20 @@ export class UciEngine {
this.multiPv = multiPv;
}
+ private async setLimitStrength(on: boolean) {
+ await this.broadcastCommands(
+ [`setoption name UCI_LimitStrength value ${on}`, "isready"],
+ "readyok"
+ );
+ }
+
+ private async setElo(elo: number) {
+ await this.broadcastCommands(
+ [`setoption name UCI_Elo value ${elo}`, "isready"],
+ "readyok"
+ );
+ }
+
private async setSkillLevel(skillLevel: number, initCase = false) {
if (!initCase) {
if (skillLevel === this.skillLevel) return;
@@ -352,11 +366,12 @@ export class UciEngine {
public async getEngineNextMove(
fen: string,
- skillLevel: number,
+ elo: number,
depth = 16
): Promise {
this.throwErrorIfNotReady();
- await this.setSkillLevel(skillLevel);
+ await this.setLimitStrength(true);
+ await this.setElo(elo);
console.log(`Evaluating position: ${fen}`);
diff --git a/src/sections/play/board.tsx b/src/sections/play/board.tsx
index d00b5c3..1f39114 100644
--- a/src/sections/play/board.tsx
+++ b/src/sections/play/board.tsx
@@ -1,6 +1,6 @@
import { useAtomValue } from "jotai";
import {
- engineSkillLevelAtom,
+ engineEloAtom,
gameAtom,
playerColorAtom,
isGameInProgressAtom,
@@ -24,7 +24,7 @@ export default function BoardContainer() {
const { white, black } = usePlayersData(gameAtom);
const playerColor = useAtomValue(playerColorAtom);
const { makeMove: makeGameMove } = useChessActions(gameAtom);
- const engineSkillLevel = useAtomValue(engineSkillLevelAtom);
+ const engineElo = useAtomValue(engineEloAtom);
const isGameInProgress = useAtomValue(isGameInProgressAtom);
const gameFen = game.fen();
@@ -40,10 +40,7 @@ export default function BoardContainer() {
) {
return;
}
- const move = await engine.getEngineNextMove(
- gameFen,
- engineSkillLevel - 1
- );
+ const move = await engine.getEngineNextMove(gameFen, engineElo);
if (move) makeGameMove(uciMoveParams(move));
};
playEngineMove();
diff --git a/src/sections/play/gameSettings/gameSettingsDialog.tsx b/src/sections/play/gameSettings/gameSettingsDialog.tsx
index 6c6a21f..e1c6dfc 100644
--- a/src/sections/play/gameSettings/gameSettingsDialog.tsx
+++ b/src/sections/play/gameSettings/gameSettingsDialog.tsx
@@ -20,7 +20,7 @@ import {
import { useAtomLocalStorage } from "@/hooks/useAtomLocalStorage";
import { useAtom, useSetAtom } from "jotai";
import {
- engineSkillLevelAtom,
+ engineEloAtom,
playerColorAtom,
isGameInProgressAtom,
gameAtom,
@@ -40,9 +40,9 @@ interface Props {
}
export default function GameSettingsDialog({ open, onClose }: Props) {
- const [skillLevel, setSkillLevel] = useAtomLocalStorage(
- "engine-skill-level",
- engineSkillLevelAtom
+ const [engineElo, setEngineElo] = useAtomLocalStorage(
+ "engine-elo",
+ engineEloAtom
);
const [engineName, setEngineName] = useAtomLocalStorage(
"engine-play-name",
@@ -56,20 +56,16 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
onClose();
resetGame({
whiteName:
- playerColor === Color.White
- ? "You"
- : `${engineLabel[engineName].small} level ${skillLevel}`,
+ playerColor === Color.White ? "You" : engineLabel[engineName].small,
blackName:
- playerColor === Color.Black
- ? "You"
- : `${engineLabel[engineName].small} level ${skillLevel}`,
+ playerColor === Color.Black ? "You" : engineLabel[engineName].small,
});
playGameStartSound();
setIsGameInProgress(true);
logAnalyticsEvent("play_game", {
engine: engineName,
- skillLevel,
+ engineElo,
playerColor,
});
};
@@ -130,12 +126,12 @@ export default function GameSettingsDialog({ open, onClose }: Props) {
diff --git a/src/sections/play/states.ts b/src/sections/play/states.ts
index 0958acd..e5f5394 100644
--- a/src/sections/play/states.ts
+++ b/src/sections/play/states.ts
@@ -8,4 +8,5 @@ export const gameDataAtom = atom({});
export const playerColorAtom = atom(Color.White);
export const enginePlayNameAtom = atom(EngineName.Stockfish17Lite);
export const engineSkillLevelAtom = atom(1);
+export const engineEloAtom = atom(1200);
export const isGameInProgressAtom = atom(false);