Skip to content

Commit c8a9943

Browse files
feat: push fix to turing/training/play/hb stats hook & added rating diff to game log
1 parent 8a8f6df commit c8a9943

File tree

14 files changed

+166
-112
lines changed

14 files changed

+166
-112
lines changed

src/api/turing/turing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export const submitTuringGuess = async (
8080
const split = rawTimeControl.split('+')
8181
const baseTimeInMinutes = parseInt(split[0], 10) / 60
8282
const timeControl = `${baseTimeInMinutes}+${split[1]}`
83+
const turingElo = data['turing_elo']
8384

8485
return {
8586
bot,
@@ -88,6 +89,7 @@ export const submitTuringGuess = async (
8889
correct,
8990
gameType,
9091
timeControl,
92+
turingElo,
9193
} as TuringSubmissionResult
9294
}
9395

src/components/Core/Header.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export const Header: React.FC = () => {
8989
<div
9090
className={`${router.pathname.startsWith('/play') && 'bg-background-1'} group relative`}
9191
>
92-
<button>Play</button>
92+
<button className="uppercase">Play</button>
9393
<div className="absolute left-0 top-[100%] z-30 hidden w-48 flex-col items-start bg-background-1 group-hover:flex">
9494
<button
9595
onClick={() => startGame('againstMaia')}
@@ -125,37 +125,37 @@ export const Header: React.FC = () => {
125125
)}
126126
<Link
127127
href="/analysis"
128-
className={`${router.pathname.startsWith('/analysis') && 'bg-background-1'} hover:bg-background-1`}
128+
className={`${router.pathname.startsWith('/analysis') && 'bg-background-1'} uppercase hover:bg-background-1`}
129129
>
130130
Analysis
131131
</Link>
132132
<Link
133133
href="/train"
134-
className={`${router.pathname.startsWith('/train') && 'bg-background-1'} hover:bg-background-1`}
134+
className={`${router.pathname.startsWith('/train') && 'bg-background-1'} uppercase hover:bg-background-1`}
135135
>
136136
Train
137137
</Link>
138138
<Link
139139
href="/openings"
140-
className={`${router.pathname.startsWith('/openings') && 'bg-background-1'} hover:bg-background-1`}
140+
className={`${router.pathname.startsWith('/openings') && 'bg-background-1'} uppercase hover:bg-background-1`}
141141
>
142142
Openings
143143
</Link>
144144
<Link
145145
href="/turing"
146-
className={`${router.pathname.startsWith('/turing') && 'bg-background-1'} hover:bg-background-1`}
146+
className={`${router.pathname.startsWith('/turing') && 'bg-background-1'} uppercase hover:bg-background-1`}
147147
>
148148
Bot-or-Not
149149
</Link>
150150
<Link
151151
href="/leaderboard"
152-
className={`${router.pathname.startsWith('/leaderboard') && 'bg-background-1'} hover:bg-background-1`}
152+
className={`${router.pathname.startsWith('/leaderboard') && 'bg-background-1'} uppercase hover:bg-background-1`}
153153
>
154154
Leaderboard
155155
</Link>
156156
<div className="group relative">
157157
<button className="-gap-1 flex items-center">
158-
<p>More</p>
158+
<p className="uppercase">More</p>
159159
<i className="material-symbols-outlined">arrow_drop_down</i>
160160
</button>
161161
<div className="absolute left-0 top-[100%] z-30 hidden w-32 flex-col items-start bg-background-1 group-hover:flex">

src/components/Misc/StatsDisplay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ export const StatsDisplay: React.FC<Props> = ({
9595
{hideSession ? null : (
9696
<div className="flex flex-col gap-1">
9797
<div className="text-xs uppercase">This session</div>
98-
<SingleStatsDisplay stats={stats.sessionStats} />
98+
<SingleStatsDisplay stats={stats.session} />
9999
</div>
100100
)}
101101
<div className="flex flex-col gap-1 text-secondary">
102102
<div className="text-xs uppercase">Lifetime</div>
103-
<SingleStatsDisplay stats={stats.lifetimeStats} />
103+
<SingleStatsDisplay stats={stats.lifetime} />
104104
</div>
105105
</div>
106106
)

src/components/Training/PuzzleLog.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { Dispatch, SetStateAction } from 'react'
33
import { TrainingGame } from 'src/types/training'
44

55
interface Props {
6-
previousGameResults: (TrainingGame & { result?: boolean })[]
6+
previousGameResults: (TrainingGame & {
7+
result?: boolean
8+
ratingDiff?: number
9+
})[]
710
setCurrentIndex: Dispatch<SetStateAction<number>>
811
}
912

@@ -17,8 +20,26 @@ export const PuzzleLog: React.FC<Props> = ({
1720
<button
1821
key={game.id}
1922
onClick={() => setCurrentIndex(index)}
20-
className={`${game.result ? 'bg-engine-4' : game.result === undefined ? 'bg-button-secondary' : 'bg-human-4'} h-7 w-7 cursor-pointer rounded-sm`}
21-
/>
23+
className={`${game.result ? 'bg-engine-4' : game.result === undefined ? 'bg-button-secondary' : 'bg-human-4'} flex h-10 w-10 cursor-pointer flex-col items-center justify-center rounded-sm`}
24+
>
25+
{game.ratingDiff ? (
26+
<>
27+
<i
28+
className={`material-symbols-outlined -mt-1 ${game.ratingDiff >= 0 ? 'text-blue-200' : 'text-red-300'}`}
29+
>
30+
{game.ratingDiff >= 0 ? 'arrow_drop_up' : 'arrow_drop_down'}
31+
</i>
32+
<p
33+
className={`-mt-2 text-xs tracking-widest ${game.ratingDiff >= 0 ? 'text-blue-200' : 'text-red-300'}`}
34+
>
35+
{game.ratingDiff >= 0 && '+'}
36+
{game.ratingDiff}
37+
</p>
38+
</>
39+
) : (
40+
<></>
41+
)}
42+
</button>
2243
))}
2344
</div>
2445
)

src/components/Turing/TuringGames.tsx

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,36 @@ export const TuringGames: React.FC = () => {
66
const { gameIds, setCurrentId, games } = useContext(TuringControllerContext)
77
return (
88
<div className="flex flex-row flex-wrap items-start justify-start gap-1 overflow-y-auto">
9-
{gameIds.map((id) => (
10-
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
11-
<span
12-
key={id}
13-
onClick={() => setCurrentId(id)}
14-
className={`${!games[id].result ? 'bg-button-secondary' : games[id].result?.correct ? 'bg-engine-4' : 'bg-human-4'} h-7 w-7 cursor-pointer rounded-sm`}
15-
/>
16-
))}
9+
{gameIds.map((id) => {
10+
const game = games[id]
11+
return (
12+
<button
13+
key={id}
14+
onClick={() => setCurrentId(id)}
15+
className={`${!game.result ? 'bg-button-secondary' : game.result?.correct ? 'bg-engine-4' : 'bg-human-4'} h-10 w-10 cursor-pointer rounded-sm`}
16+
>
17+
{game.result?.ratingDiff ? (
18+
<>
19+
<i
20+
className={`material-symbols-outlined -mt-1 ${game.result.ratingDiff >= 0 ? 'text-blue-200' : 'text-red-300'}`}
21+
>
22+
{game.result.ratingDiff >= 0
23+
? 'arrow_drop_up'
24+
: 'arrow_drop_down'}
25+
</i>
26+
<p
27+
className={`-mt-2 text-xs tracking-widest ${game.result.ratingDiff >= 0 ? 'text-blue-200' : 'text-red-300'}`}
28+
>
29+
{game.result.ratingDiff >= 0 && '+'}
30+
{game.result.ratingDiff}
31+
</p>
32+
</>
33+
) : (
34+
<></>
35+
)}
36+
</button>
37+
)
38+
})}
1739
</div>
1840
)
1941
}

src/components/Turing/TuringSubmission.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useCallback, useContext, useEffect, useState } from 'react'
33

44
import { TuringControllerContext } from 'src/contexts'
55

6-
export const TuringSubmission: React.FC = () => {
6+
export const TuringSubmission = ({ rating }: { rating: number }) => {
77
const { game, submitGuess, getNewGame, commentController } = useContext(
88
TuringControllerContext,
99
)
@@ -12,9 +12,9 @@ export const TuringSubmission: React.FC = () => {
1212

1313
const handleSubmit = useCallback(() => {
1414
if (selected) {
15-
submitGuess(selected, comment)
15+
submitGuess(selected, comment, rating)
1616
}
17-
}, [selected, submitGuess, comment])
17+
}, [selected, submitGuess, comment, rating])
1818

1919
useEffect(() => {
2020
setSelected(null)

src/contexts/TuringControllerContext/TuringControllerContext.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ export const TuringControllerContext =
1212
React.createContext<ITuringControllerContext>({
1313
game: undefined,
1414
stats: {
15-
lifetimeStats: undefined,
16-
sessionStats: { gamesWon: 0, gamesPlayed: 0 },
15+
lifetime: undefined,
16+
session: { gamesWon: 0, gamesPlayed: 0 },
1717
lastRating: 0,
1818
rating: 0,
1919
},

src/hooks/useStats/useStats.ts

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,85 +14,73 @@ export interface SingleStats {
1414
export interface AllStats {
1515
lastRating: number | undefined
1616
rating: number | undefined
17-
sessionStats: SingleStats
18-
lifetimeStats: SingleStats | undefined
17+
session: SingleStats
18+
lifetime: SingleStats | undefined
1919
}
2020

2121
type IncrementStatsFunction = (gamesPlayed: number, gamesWon: number) => void
22+
type UpdateStatsFunction = (newRating: number) => void
2223

2324
export const useStats = (
2425
apiCall: () => Promise<ApiResult>,
25-
): [AllStats, IncrementStatsFunction, () => void] => {
26-
const [statsInvalidated, setStatsInvalidated] = useState<boolean>(true)
27-
const [statsLoading, setStatsLoading] = useState<boolean>(false)
28-
29-
const [lastRating, setLastRating] = useState<number | undefined>(undefined)
30-
const [rating, setRating] = useState<number | undefined>(undefined)
31-
const [gamesPlayed, setGamesPlayed] = useState<number | undefined>(undefined)
32-
const [gamesWon, setGamesWon] = useState<number | undefined>(undefined)
33-
34-
const [sessionGamesPlayed, setSessionGamesPlayed] = useState<number>(0)
35-
const [sessionGamesWon, setSessionGamesWon] = useState<number>(0)
36-
37-
const [unloadedGamesPlayed, setUnloadedGamesPlayed] = useState<number>(0)
38-
const [unloadedGamesWon, setUnloadedGamesWon] = useState<number>(0)
39-
40-
const stats: AllStats = {
41-
lastRating: statsInvalidated ? rating : lastRating,
42-
rating: statsInvalidated ? undefined : rating,
43-
sessionStats: {
44-
gamesPlayed: sessionGamesPlayed,
45-
gamesWon: sessionGamesWon,
26+
): [AllStats, IncrementStatsFunction, UpdateStatsFunction] => {
27+
const [stats, setStats] = useState<AllStats>({
28+
rating: undefined,
29+
lastRating: undefined,
30+
session: {
31+
gamesPlayed: 0,
32+
gamesWon: 0,
4633
},
47-
lifetimeStats:
48-
gamesPlayed === undefined || gamesWon === undefined
49-
? undefined
50-
: {
51-
gamesPlayed: gamesPlayed + unloadedGamesPlayed,
52-
gamesWon: gamesWon + unloadedGamesWon,
53-
},
54-
}
34+
lifetime: undefined,
35+
})
5536

5637
useEffect(() => {
57-
if (statsInvalidated && !statsLoading) {
58-
const statsLoader = async () => {
59-
const loadedStats = await apiCall()
60-
61-
setLastRating(rating)
62-
setRating(loadedStats.rating)
63-
64-
setGamesPlayed(loadedStats.gamesPlayed)
65-
setGamesWon(loadedStats.gamesWon)
66-
67-
setUnloadedGamesPlayed(0)
68-
setUnloadedGamesWon(0)
69-
70-
setStatsInvalidated(false)
71-
setStatsLoading(false)
72-
}
73-
74-
statsLoader()
75-
setStatsLoading(true)
38+
const statsLoader = async () => {
39+
const loadedStats = await apiCall()
40+
41+
setStats((s) => ({
42+
...stats,
43+
rating: loadedStats.rating,
44+
lastRating: stats.rating,
45+
lifetime: {
46+
gamesPlayed: loadedStats.gamesPlayed,
47+
gamesWon: loadedStats.gamesWon,
48+
},
49+
}))
7650
}
77-
}, [apiCall, gamesPlayed, gamesWon, rating, statsInvalidated, statsLoading])
51+
52+
statsLoader()
53+
}, [])
7854

7955
const incrementStats: IncrementStatsFunction = useCallback(
8056
(gamesPlayed: number, gamesWon: number) => {
81-
setSessionGamesPlayed(
82-
(sessionGamesPlayed) => sessionGamesPlayed + gamesPlayed,
83-
)
84-
setSessionGamesWon((sessionGamesWon) => sessionGamesWon + gamesWon)
85-
setUnloadedGamesPlayed(gamesPlayed)
86-
setUnloadedGamesWon(gamesWon)
87-
setStatsInvalidated(true)
57+
setStats((s) => ({
58+
...s,
59+
session: {
60+
gamesPlayed: s.session.gamesPlayed + gamesPlayed,
61+
gamesWon: s.session.gamesWon + gamesWon,
62+
},
63+
lifetime: s.lifetime
64+
? {
65+
gamesPlayed: s.lifetime.gamesPlayed + gamesPlayed,
66+
gamesWon: s.lifetime.gamesWon + gamesWon,
67+
}
68+
: {
69+
gamesPlayed,
70+
gamesWon,
71+
},
72+
}))
8873
},
89-
// This needs to not have any dependencies to avoid extra games being added
9074
[],
9175
)
9276

93-
const resetLastRating = useCallback(() => {
94-
setLastRating(undefined)
77+
const updateRating = useCallback((newRating: number) => {
78+
setStats((s) => ({
79+
...s,
80+
rating: newRating,
81+
lastRating: s.rating,
82+
}))
9583
}, [])
9684

97-
return [stats, incrementStats, resetLastRating]
85+
return [stats, incrementStats, updateRating]
9886
}

src/hooks/useTuringController/useTuringController.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const useTuringController = () => {
2323

2424
const [currentId, setCurrentId] = useState<null | string>(null)
2525
const [loading, setLoading] = useState(false)
26-
const [stats, incrementStats, resetLastRating] = useStats(statsLoader)
26+
const [stats, incrementStats, updateRating] = useStats(statsLoader)
2727

2828
const getNewGame = useCallback(async () => {
2929
setLoading(true)
@@ -35,11 +35,10 @@ export const useTuringController = () => {
3535
return
3636
}
3737

38-
resetLastRating()
3938
setLoading(false)
4039
setTuringGames({ ...turingGames, [game.id]: game })
4140
setCurrentId(game.id)
42-
}, [turingGames, router, resetLastRating])
41+
}, [turingGames, router])
4342

4443
useEffect(() => {
4544
if (Object.keys(turingGames).length === 0) getNewGame()
@@ -53,20 +52,23 @@ export const useTuringController = () => {
5352
const gameIds = useMemo(() => Object.keys(turingGames), [turingGames])
5453

5554
const submitGuess = useCallback(
56-
async (guess: Color, comment = '') => {
55+
async (guess: Color, comment = '', rating: number) => {
5756
if (game && !game.result) {
5857
const result = await submitTuringGuess(game.id, guess, comment)
5958
setTuringGames({
6059
...turingGames,
61-
[game.id]: { ...game, result },
60+
[game.id]: {
61+
...game,
62+
result: { ...result, ratingDiff: result.turingElo - rating },
63+
},
6264
})
6365
commentController[1]('')
64-
// to avoid race conditions on the server, sleep
65-
await new Promise((r) => setTimeout(r, 500))
66+
67+
updateRating(result.turingElo)
6668
incrementStats(1, result.correct ? 1 : 0)
6769
}
6870
},
69-
[game, incrementStats, turingGames],
71+
[game, incrementStats, turingGames, updateRating],
7072
)
7173

7274
const commentController = useState('')

0 commit comments

Comments
 (0)