From 5392644e36f0c4d515a6085a0681e15c875a4737 Mon Sep 17 00:00:00 2001 From: Francisco Salgueiro Date: Wed, 29 Nov 2023 00:36:55 +0000 Subject: [PATCH] add color to engines --- src/atoms/atoms.ts | 5 +++ src/components/boards/Board.tsx | 30 ++++++++++++----- src/components/boards/BoardAnalysis.tsx | 6 ++-- .../panels/analysis/AnalysisPanel.tsx | 3 -- src/components/panels/analysis/BestMoves.tsx | 33 ++++++++++++------- .../panels/analysis/CoresSlider.tsx | 6 ++-- .../panels/analysis/DepthSlider.tsx | 3 ++ .../panels/analysis/EngineSettingsForm.tsx | 11 +++++-- src/components/panels/analysis/HashSlider.tsx | 3 ++ .../panels/analysis/LinesSlider.tsx | 4 ++- src/components/panels/analysis/styles.ts | 6 ++-- 11 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/atoms/atoms.ts b/src/atoms/atoms.ts index c4060f5e..be7dfb9f 100644 --- a/src/atoms/atoms.ts +++ b/src/atoms/atoms.ts @@ -228,6 +228,11 @@ const pgnOptionsFamily = atomFamily((tab: string) => ); export const currentPgnOptionsAtom = tabValue(pgnOptionsFamily); +const arrowsFamily = atomFamily((tab: string) => + atom(new Map()) +); +export const currentArrowsAtom = tabValue(arrowsFamily); + // Game type GameState = "settingUp" | "playing" | "gameOver"; diff --git a/src/components/boards/Board.tsx b/src/components/boards/Board.tsx index ef98dd7d..6e8c014b 100644 --- a/src/components/boards/Board.tsx +++ b/src/components/boards/Board.tsx @@ -63,11 +63,12 @@ import EvalBar from "./EvalBar"; import PromotionModal from "./PromotionModal"; import "./board.css"; import { match } from "ts-pattern"; +import { arrowColors } from "../panels/analysis/BestMoves"; interface ChessboardProps { dirty: boolean; currentNode: TreeNode; - arrows: string[]; + arrows: Map; headers: GameHeaders; root: TreeNode; editingMode: boolean; @@ -211,17 +212,28 @@ function Board({ } } - let shapes: DrawShape[] = - showArrows && arrows.length > 0 - ? arrows.map((move, i) => { + let shapes: DrawShape[] = []; + if (showArrows && arrows.size > 0) { + const entries = Array.from(arrows.entries()).sort((a, b) => a[0] - b[0]); + for (const [i, moves] of entries) { + if (i < 4) { + for (const [j, move] of moves.entries()) { const { from, to } = parseUci(move); - return { + if (shapes.find((s) => s.orig === from && s.dest === to)) continue; + shapes.push({ orig: from, dest: to, - brush: i === 0 ? "paleBlue" : "paleGrey", - }; - }) - : []; + brush: + j === 0 + ? arrowColors[i] + : "pale" + + arrowColors[i].charAt(0).toUpperCase() + + arrowColors[i].slice(1), + }); + } + } + } + } if (currentNode.shapes.length > 0) { shapes = shapes.concat(currentNode.shapes); diff --git a/src/components/boards/BoardAnalysis.tsx b/src/components/boards/BoardAnalysis.tsx index 20f6e6de..a75cfabb 100644 --- a/src/components/boards/BoardAnalysis.tsx +++ b/src/components/boards/BoardAnalysis.tsx @@ -31,6 +31,7 @@ import GameNotation from "./GameNotation"; import { useAtom, useAtomValue } from "jotai"; import { autoSaveAtom, + currentArrowsAtom, currentTabAtom, currentTabSelectedAtom, } from "@/atoms/atoms"; @@ -42,7 +43,7 @@ import { getMainLine } from "@/utils/chess"; function BoardAnalysis() { const [editingMode, toggleEditingMode] = useToggle(); const [reportingMode, toggleReportingMode] = useToggle(); - const [arrows, setArrows] = useState([]); + const [arrows, setArrows] = useAtom(currentArrowsAtom); const [currentTab, setCurrentTab] = useAtom(currentTabAtom); const autoSave = useAtomValue(autoSaveAtom); const dispatch = useContext(TreeDispatchContext); @@ -55,7 +56,7 @@ function BoardAnalysis() { const currentNode = getNodeAtPath(root, position); useEffect(() => { - setArrows([]); + setArrows(new Map()); }, [position]); const saveFile = useCallback(async () => { @@ -166,7 +167,6 @@ function BoardAnalysis() { void; toggleReportingMode: () => void; inProgress: boolean; setInProgress: React.Dispatch>; @@ -129,7 +127,6 @@ function AnalysisPanel({ diff --git a/src/components/panels/analysis/BestMoves.tsx b/src/components/panels/analysis/BestMoves.tsx index 7cc6850a..2d5ad355 100644 --- a/src/components/panels/analysis/BestMoves.tsx +++ b/src/components/panels/analysis/BestMoves.tsx @@ -1,5 +1,6 @@ import { activeTabAtom, + currentArrowsAtom, engineMovesFamily, tabEngineSettingsFamily, } from "@/atoms/atoms"; @@ -55,10 +56,11 @@ const useStyles = createStyles((theme) => ({ }, })); +export const arrowColors = ["blue", "green", "red", "yellow"]; + interface BestMovesProps { id: number; engine: Engine; - setArrows: (arrows: string[]) => void; fen: string; halfMoves: number; } @@ -66,7 +68,6 @@ interface BestMovesProps { export default function BestMovesComponent({ id, engine, - setArrows, fen, halfMoves, }: BestMovesProps) { @@ -78,6 +79,7 @@ export default function BestMovesComponent({ const [settings, setSettings] = useAtom( tabEngineSettingsFamily({ engine: engine, tab: activeTab! }) ); + const [, setArrows] = useAtom(currentArrowsAtom); const engineVariations = useMemo(() => ev.get(fen) ?? [], [ev, fen]); @@ -116,13 +118,14 @@ export default function BestMovesComponent({ type: "SET_SCORE", payload: ev[0].score, }); - if (id === 0) { - setArrows( - ev.map((ev) => { - return ev.uciMoves[0]; - }) + setArrows((prev) => { + const newMap = new Map(prev); + newMap.set( + id, + ev.map((ev) => ev.uciMoves[0]) ); - } + return newMap; + }); }); } }); @@ -166,6 +169,14 @@ export default function BestMovesComponent({ newMap.set(fen, bestMoves); return newMap; }); + setArrows((prev) => { + const newMap = new Map(prev); + newMap.set( + id, + bestMoves.map((ev) => ev.uciMoves[0]) + ); + return newMap; + }); } }); } @@ -185,7 +196,7 @@ export default function BestMovesComponent({ { setSettings((prev) => ({ ...prev, enabled: !prev.enabled })); }} @@ -280,6 +291,7 @@ export default function BestMovesComponent({ engine={engine} settings={settings} setSettings={setSettings} + color={id < 4 ? arrowColors[id] : theme.primaryColor} /> @@ -288,8 +300,7 @@ export default function BestMovesComponent({ animate={progress < 100 && settings.enabled && !isGameOver} size="xs" striped={progress < 100 && !settings.enabled} - // color={threat ? "red" : "blue"} - color={threat ? "red" : theme.primaryColor} + color={id < 4 ? arrowColors[id] : theme.primaryColor} /> diff --git a/src/components/panels/analysis/CoresSlider.tsx b/src/components/panels/analysis/CoresSlider.tsx index 3c218d09..d414edda 100644 --- a/src/components/panels/analysis/CoresSlider.tsx +++ b/src/components/panels/analysis/CoresSlider.tsx @@ -1,11 +1,13 @@ import { SegmentedControl, useMantineTheme } from "@mantine/core"; -export default function CoresSlide({ +export default function CoresSlider({ value, setValue, + color, }: { value: number; setValue: (v: number) => void; + color?: string; }) { const theme = useMantineTheme(); const values = Array.from( @@ -16,7 +18,7 @@ export default function CoresSlide({ return ( setValue(parseInt(v))} data={values.map((v) => v.toString())} diff --git a/src/components/panels/analysis/DepthSlider.tsx b/src/components/panels/analysis/DepthSlider.tsx index 92ae895d..75e22603 100644 --- a/src/components/panels/analysis/DepthSlider.tsx +++ b/src/components/panels/analysis/DepthSlider.tsx @@ -7,9 +7,11 @@ import { useStyles } from "./styles"; export default function DepthSlider({ value, setValue, + color, }: { value: GoMode; setValue: (v: GoMode) => void; + color?: string; }) { const [tempValue, setTempValue] = useState(value); const MARKS = [ @@ -46,6 +48,7 @@ export default function DepthSlider({ min={10} max={60} value={v} + color={color} label={(v) => (v === 60 ? "Infinite" : v)} onChange={(v) => handleSliderChange(v, setTempValue)} onChangeEnd={(v) => handleSliderChange(v, setValue)} diff --git a/src/components/panels/analysis/EngineSettingsForm.tsx b/src/components/panels/analysis/EngineSettingsForm.tsx index 45be922e..d64d7f86 100644 --- a/src/components/panels/analysis/EngineSettingsForm.tsx +++ b/src/components/panels/analysis/EngineSettingsForm.tsx @@ -4,6 +4,7 @@ import { Button, Center, Group, + MantineColor, Modal, NumberInput, Select, @@ -14,7 +15,6 @@ import { Tooltip, } from "@mantine/core"; import React, { memo, useState } from "react"; -import CoresSlide from "./CoresSlider"; import DepthSlider from "./DepthSlider"; import LinesSlider from "./LinesSlider"; import { @@ -30,11 +30,13 @@ import { appDataDir, resolve } from "@tauri-apps/api/path"; import { readTextFile, writeTextFile } from "@tauri-apps/api/fs"; import { Engine } from "@/utils/engines"; import { useAtom } from "jotai"; +import CoresSlider from "./CoresSlider"; interface EngineSettingsProps { engine: Engine; settings: EngineSettings; setSettings: (fn: (prev: EngineSettings) => EngineSettings) => void; + color?: MantineColor; minimal?: boolean; } @@ -42,6 +44,7 @@ function EngineSettingsForm({ engine, settings, setSettings, + color, minimal, }: EngineSettingsProps) { const [advancedOptions, setAdvancedOptions] = useState(false); @@ -118,6 +121,7 @@ function EngineSettingsForm({ setSettings((prev) => ({ ...prev, go: v }))} + color={color} /> ) : ( @@ -156,6 +160,7 @@ function EngineSettingsForm({ options: { ...prev.options, multipv: v }, })) } + color={color} /> )} @@ -164,7 +169,7 @@ function EngineSettingsForm({ Number of cores - setSettings((prev) => ({ @@ -172,6 +177,7 @@ function EngineSettingsForm({ options: { ...prev.options, threads: v }, })) } + color={color} /> @@ -187,6 +193,7 @@ function EngineSettingsForm({ options: { ...prev.options, hash: v }, })) } + color={color} /> diff --git a/src/components/panels/analysis/HashSlider.tsx b/src/components/panels/analysis/HashSlider.tsx index 441be52f..b4a5f815 100644 --- a/src/components/panels/analysis/HashSlider.tsx +++ b/src/components/panels/analysis/HashSlider.tsx @@ -9,9 +9,11 @@ import { useStyles } from "./styles"; export default function HashSlider({ value, setValue, + color, }: { value: number; setValue: (v: number) => void; + color?: string; }) { const [tempValue, setTempValue] = useState(Math.log2(value)); const { classes } = useStyles(); @@ -29,6 +31,7 @@ export default function HashSlider({ setValue(2 ** v)} diff --git a/src/components/panels/analysis/LinesSlider.tsx b/src/components/panels/analysis/LinesSlider.tsx index b2276704..7ea76a05 100644 --- a/src/components/panels/analysis/LinesSlider.tsx +++ b/src/components/panels/analysis/LinesSlider.tsx @@ -3,16 +3,18 @@ import { SegmentedControl, useMantineTheme } from "@mantine/core"; export default function DepthSlider({ value, setValue, + color, }: { value: number; setValue: (v: number) => void; + color?: string; }) { const theme = useMantineTheme(); return ( setValue(parseInt(v))} diff --git a/src/components/panels/analysis/styles.ts b/src/components/panels/analysis/styles.ts index c5de0aeb..32ef6f73 100644 --- a/src/components/panels/analysis/styles.ts +++ b/src/components/panels/analysis/styles.ts @@ -11,8 +11,8 @@ export const useStyles = createStyles((theme) => ({ backgroundColor: theme.white, color: theme.colors.gray[5], border: - rem(1) + - " solid " + - "light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-2))", + rem(1) + " solid " + theme.colorScheme === "dark" + ? theme.colors.dark[2] + : theme.colors.gray[3], }, }));