Skip to content

Commit

Permalink
feat: add capability to analyze Lichess games with any Maia version
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinjosethomas committed Nov 18, 2024
1 parent 01f9127 commit 800fcb1
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 45 deletions.
29 changes: 21 additions & 8 deletions src/api/analysis/analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,26 @@ export const getAnalyzedTournamentGame = async (gameId = ['FkgYSri1']) => {
} as any as AnalyzedGame
}

export const getAnalyzedLichessGame = async (id: string, pgn: string) => {
const res = await fetch(buildUrl('analysis/analyze_user_game'), {
method: 'POST',
body: pgn,
headers: {
'Content-Type': 'text/plain',
export const getAnalyzedLichessGame = async (
id: string,
pgn: string,
maia_model = 'maia_kdd_1500',
) => {
const res = await fetch(
buildUrl(
'analysis/analyze_user_game?' +
new URLSearchParams({
maia_model,
}),
),
{
method: 'POST',
body: pgn,
headers: {
'Content-Type': 'text/plain',
},
},
})
)

if (res.status === 401) {
throw new Error('Unauthorized')
Expand Down Expand Up @@ -245,5 +257,6 @@ export const getAnalyzedLichessGame = async (id: string, pgn: string) => {
gameType,
termination,
positionEvaluations,
} as any as AnalyzedGame
pgn,
} as AnalyzedGame
}
12 changes: 8 additions & 4 deletions src/components/AnalysisGameList/AnalysisGameList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
useContext,
useEffect,
useMemo,
useState,
useRef,
useMemo,
Dispatch,
useState,
useEffect,
useContext,
SetStateAction,
} from 'react'
import { motion } from 'framer-motion'
Expand All @@ -14,6 +14,7 @@ import { AnalysisListContext, GameControllerContext } from 'src/contexts'

interface AnalysisGameListProps {
currentId: string[] | null
currentMaiaModel: string
loadNewTournamentGame: (
newId: string[],
setCurrentMove: Dispatch<SetStateAction<number>>,
Expand All @@ -22,11 +23,13 @@ interface AnalysisGameListProps {
id: string,
pgn: string,
setCurrentMove: Dispatch<SetStateAction<number>>,
currentMaiaModel: string,
) => Promise<void>
}

const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
currentId,
currentMaiaModel,
loadNewTournamentGame,
loadNewLichessGames,
}) => {
Expand Down Expand Up @@ -143,6 +146,7 @@ const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
game.id,
game.pgn,
controller.setCurrentIndex,
currentMaiaModel,
)
setLoadingIndex(null)
}}
Expand Down
11 changes: 6 additions & 5 deletions src/hooks/useAnalysisController/useAnalysisController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,14 @@ export const useAnalysisController = (
])

const data = useMemo(() => {
if (!plotData[currentMaiaModel]) return []
return plotData[currentMaiaModel][controller.currentIndex]
}, [controller.currentIndex, currentMaiaModel, plotData])

const positionEvaluation = useMemo(
() => game.positionEvaluations[currentMaiaModel][controller.currentIndex],
[controller.currentIndex, currentMaiaModel, game.positionEvaluations],
)
// const positionEvaluation = useMemo(
// () => game.positionEvaluations[currentMaiaModel][controller.currentIndex],
// [controller.currentIndex, currentMaiaModel, game.positionEvaluations],
// )

const moveEvaluation = useMemo(() => {
if (currentMove) {
Expand Down Expand Up @@ -414,7 +415,7 @@ export const useAnalysisController = (
maiaModels,
currentMaiaModel,
setCurrentMaiaModel,
positionEvaluation,
// positionEvaluation,
currentMove,
setCurrentMove,
moveEvaluation,
Expand Down
1 change: 0 additions & 1 deletion src/hooks/useStockfishEngine/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class Engine {
}

private onMessage(msg: string) {
console.log(msg)
const matches = [
...msg.matchAll(
/info depth (\d+) seldepth (\d+) multipv (\d+) score (?:cp (-?\d+)|mate (-?\d+)).+ pv ((?:\S+\s*)+)/g,
Expand Down
113 changes: 86 additions & 27 deletions src/pages/analysis/[...id].tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, {
useMemo,
Dispatch,
useState,
useEffect,
useContext,
useCallback,
Dispatch,
SetStateAction,
} from 'react'
import Head from 'next/head'
Expand Down Expand Up @@ -37,6 +37,18 @@ import AnalysisGameList from 'src/components/AnalysisGameList/AnalysisGameList'
import { HorizontalEvaluationBar } from 'src/components/HorizontalEvaluationBar'
import { GameControllerContext } from 'src/contexts/GameControllerContext/GameControllerContext'

const MAIA_MODELS = [
'maia_kdd_1100',
'maia_kdd_1200',
'maia_kdd_1300',
'maia_kdd_1400',
'maia_kdd_1500',
'maia_kdd_1600',
'maia_kdd_1700',
'maia_kdd_1800',
'maia_kdd_1900',
]

const AnalysisPage: NextPage = () => {
const { openedModals, setInstructionsModalProps: setInstructionsModalProps } =
useContext(ModalContext)
Expand Down Expand Up @@ -81,10 +93,11 @@ const AnalysisPage: NextPage = () => {
id: string,
pgn: string,
setCurrentMove?: Dispatch<SetStateAction<number>>,
currentMaiaModel = 'maia_kdd_1500',
) => {
let game
try {
game = await getAnalyzedLichessGame(id, pgn)
game = await getAnalyzedLichessGame(id, pgn, currentMaiaModel)
} catch (e) {
router.push('/401')
return
Expand All @@ -107,7 +120,7 @@ const AnalysisPage: NextPage = () => {
if (queryId[1] == 'lichess') {
const pgn = await getLichessGamePGN(queryId[0])

getAndSetLichessGames(queryId[0], pgn)
getAndSetLichessGames(queryId[0], pgn, undefined)
} else {
getAndSetTournamentGame(queryId)
}
Expand All @@ -119,16 +132,13 @@ const AnalysisPage: NextPage = () => {
<>
{analyzedGame ? (
<Analysis
currentId={currentId}
analyzedGame={analyzedGame}
setAnalyzedGame={setAnalyzedGame}
initialIndex={index ? Number(index) : 0}
initialOrientation={orientation == 'black' ? 'black' : 'white'}
listController={
<AnalysisGameList
currentId={currentId}
loadNewTournamentGame={getAndSetTournamentGame}
loadNewLichessGames={getAndSetLichessGames}
/>
}
getAndSetTournamentGame={getAndSetTournamentGame}
getAndSetLichessGames={getAndSetLichessGames}
/>
) : (
<Loading />
Expand All @@ -138,18 +148,34 @@ const AnalysisPage: NextPage = () => {
}

interface Props {
currentId: string[]
getAndSetTournamentGame: (
newId: string[],
setCurrentMove?: Dispatch<SetStateAction<number>>,
) => Promise<void>
getAndSetLichessGames: (
id: string,
pgn: string,
setCurrentMove?: Dispatch<SetStateAction<number>>,
currentMaiaModel?: string,
) => Promise<void>
analyzedGame: AnalyzedGame
initialIndex: number
initialOrientation: Color
listController: React.ReactNode

setAnalyzedGame: Dispatch<SetStateAction<AnalyzedGame | undefined>>
}

const Analysis: React.FC<Props> = ({
currentId,
analyzedGame,
initialIndex,
initialOrientation,
listController,
getAndSetTournamentGame,
getAndSetLichessGames,
setAnalyzedGame,
}: Props) => {
const router = useRouter()
const { theme } = useContext(ThemeContext)
const { width } = useContext(WindowSizeContext)
const isMobile = useMemo(() => width > 0 && width <= 670, [width])
Expand All @@ -161,7 +187,6 @@ const Analysis: React.FC<Props> = ({
moves,
data,
controller,
maiaModels,
setCurrentMaiaModel,
currentMaiaModel,
moveEvaluation,
Expand Down Expand Up @@ -192,6 +217,37 @@ const Analysis: React.FC<Props> = ({
})
}

const updateMaiaModel = async (model: string) => {
if (analyzedGame.type === 'tournament') {
setCurrentMaiaModel(model)
} else if (analyzedGame.type === 'pgn') {
if (analyzedGame.maiaEvaluations[model]) {
setCurrentMaiaModel(model)
return
}

let game
try {
game = await getAnalyzedLichessGame(
analyzedGame.id,
analyzedGame.pgn as string,
model,
)
} catch (e) {
router.push('/401')
return
}
const evals = game.maiaEvaluations[model]
if (evals) {
const newAnalyzedGame = { ...analyzedGame }
newAnalyzedGame.maiaEvaluations[model] = evals

setAnalyzedGame(newAnalyzedGame)
setCurrentMaiaModel(model)
}
}
}

useEffect(() => {
let topStockfishMove, topMaiaMove
const maia =
Expand Down Expand Up @@ -320,24 +376,24 @@ const Analysis: React.FC<Props> = ({
<div className="flex flex-col">
<p>Analyze using:</p>
<select
disabled={maiaModels.length === 1}
className={`cursor-pointer rounded border-none bg-human-4 p-2 outline-none ${maiaModels.length === 1 ? 'cursor-not-allowed' : 'cursor-pointer'}`}
value={currentMaiaModel}
onChange={(e) => {
setCurrentMaiaModel(e.target.value)
}}
className="cursor-pointer rounded border-none bg-human-4 p-2 outline-none"
onChange={(e) => updateMaiaModel(e.target.value)}
>
{maiaModels.map((model) => (
{MAIA_MODELS.map((model) => (
<option value={model} key={model}>
{model.replace('maia_kdd_', 'Maia ')}
</option>
))}
</select>
</div>

<ContinueAgainstMaia launchContinue={launchContinue} />

{listController}
<AnalysisGameList
currentId={currentId}
currentMaiaModel={currentMaiaModel}
loadNewTournamentGame={getAndSetTournamentGame}
loadNewLichessGames={getAndSetLichessGames}
/>
</div>
<div className="relative flex aspect-square w-full max-w-[75vh]">
<GameBoard
Expand Down Expand Up @@ -541,19 +597,22 @@ const Analysis: React.FC<Props> = ({
<select
className="w-full cursor-pointer rounded border-none bg-human-4 p-2 outline-none"
value={currentMaiaModel}
onChange={(e) => {
setCurrentMaiaModel(e.target.value)
}}
onChange={(e) => updateMaiaModel(e.target.value)}
>
{maiaModels.map((model) => (
{MAIA_MODELS.map((model) => (
<option value={model} key={model}>
{model.replace('maia_kdd_', 'Maia ')}
</option>
))}
</select>
</div>
<ContinueAgainstMaia launchContinue={launchContinue} />
{listController}
<AnalysisGameList
currentId={currentId}
currentMaiaModel={currentMaiaModel}
loadNewTournamentGame={getAndSetTournamentGame}
loadNewLichessGames={getAndSetLichessGames}
/>
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/types/analysis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface AnalyzedGame extends Game {
positionEvaluations: { [model: string]: PositionEvaluation[] }
availableMoves: AvailableMoves[]
type: EvaluationType
pgn?: string
}

export interface Termination {
Expand Down

0 comments on commit 800fcb1

Please sign in to comment.