Skip to content

Commit cf84d4c

Browse files
Add round 2 candidates challenges
1 parent 3202761 commit cf84d4c

3 files changed

Lines changed: 76 additions & 14 deletions

File tree

src/constants/candidates.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,48 @@ export const CANDIDATES_EXTRA_IDEAS: CandidateIdea[] = [
7272
]
7373

7474
// Drop live tournament moments here as PGN or FEN during the event.
75-
export const CANDIDATES_FEATURED_POSITIONS: CandidatePosition[] = []
75+
export const CANDIDATES_FEATURED_POSITIONS: CandidatePosition[] = [
76+
{
77+
id: 'rd2-defend-like-hikaru',
78+
title: 'Rd2 Challenge 1: Defend like Hikaru',
79+
subtitle: 'Can you hold the position like Hikaru did?',
80+
summary: 'Nakamura is under pressure. Black to move and defend accurately.',
81+
tag: 'Featured',
82+
accent: 'red',
83+
fen: '2r3k1/2q2ppp/5n2/p1p1p3/4P2P/1PQ3P1/P4PB1/2R3K1 b - - 0 25',
84+
playerColor: 'black',
85+
maiaVersion: 'maia_kdd_1900',
86+
targetMoveNumber: 8,
87+
},
88+
{
89+
id: 'rd2-pragg-french',
90+
title: "Rd2 Challenge 2: Hold off Pragg's French",
91+
subtitle:
92+
'Can you defend the White side after some inaccuracies in the French?',
93+
summary:
94+
'White to move in a tense French structure. Defend the position accurately.',
95+
tag: 'Featured',
96+
accent: 'amber',
97+
fen: 'r1b2rk1/6pp/ppqbpn2/2pp4/3P1P2/2N1B3/PPPQB1PP/4RR1K b - - 1 16',
98+
playerColor: 'white',
99+
maiaVersion: 'maia_kdd_1800',
100+
targetMoveNumber: 8,
101+
},
102+
{
103+
id: 'rd2-be-like-bluebaum',
104+
title: 'Rd2 Challenge 3: Be like Bluebaum',
105+
subtitle:
106+
'Bluebaum had less space, but held the draw anyway. Try to do the same.',
107+
summary:
108+
'Bluebaum-style defense and coordination. Black to move and find the right plan.',
109+
tag: 'Featured',
110+
accent: 'blue',
111+
fen: '4rb1r/pp1k1pp1/2p1nnb1/3p2Np/3P3P/2P1NPP1/PP3K2/R1B2B1R b - - 3 19',
112+
playerColor: 'black',
113+
maiaVersion: 'maia_kdd_1900',
114+
targetMoveNumber: 8,
115+
},
116+
]
76117

77118
// Warm-up cards keep the page useful before round one begins.
78119
export const CANDIDATES_WARMUP_POSITIONS: CandidatePosition[] = [

src/lib/positionLinks.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ export const buildPositionPlayLink = (options: PositionLinkOptions): string => {
112112
const params = new URLSearchParams()
113113
const normalizedFen = normalizeFen(options.fen)
114114
const forcedPlayerColor =
115-
options.forcedPlayerColor ?? inferPlayerColorFromFen(normalizedFen)
115+
options.forcedPlayerColor ??
116+
options.playerColor ??
117+
inferPlayerColorFromFen(normalizedFen)
116118

117119
params.set('fen', normalizedFen)
118120
params.set('maiaVersion', 'maia_kdd_1500')

src/pages/candidates.tsx

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ const accentClasses: Record<CandidatePosition['accent'], string> = {
5555
const completedAccentClass =
5656
'border-emerald-300/35 bg-[radial-gradient(circle_at_top,rgba(52,211,153,0.18),transparent_62%),rgba(255,255,255,0.03)]'
5757

58+
const ChallengeSectionTitle: React.FC<{ title: string }> = ({ title }) => (
59+
<div className="md:col-span-2 xl:col-span-3">
60+
<p className="text-sm uppercase tracking-[0.24em] text-white/40">{title}</p>
61+
</div>
62+
)
63+
5864
const PositionBoard: React.FC<{
5965
position: CandidatePosition
6066
completed?: boolean
@@ -184,10 +190,6 @@ export default function CandidatesPage() {
184190
const [completedChallengeIds, setCompletedChallengeIds] = useState<string[]>(
185191
[],
186192
)
187-
const positions = useMemo(
188-
() => [...CANDIDATES_FEATURED_POSITIONS, ...CANDIDATES_WARMUP_POSITIONS],
189-
[],
190-
)
191193
const completedChallengeId =
192194
typeof router.query.completedChallenge === 'string'
193195
? router.query.completedChallenge
@@ -242,7 +244,7 @@ export default function CandidatesPage() {
242244
FIDE Candidates Tournament 2026
243245
</h1>
244246
<p className="mt-2 text-sm uppercase tracking-[0.2em] text-white/45">
245-
Round 1
247+
Round 2
246248
</p>
247249
<div className="mt-4 flex flex-wrap gap-3">
248250
<Link
@@ -265,13 +267,30 @@ export default function CandidatesPage() {
265267
</a>
266268
</div>
267269
</header>
268-
{positions.map((position) => (
269-
<PositionPill
270-
key={position.id}
271-
position={position}
272-
completed={completedChallengeIds.includes(position.id)}
273-
/>
274-
))}
270+
{CANDIDATES_FEATURED_POSITIONS.length > 0 ? (
271+
<>
272+
<ChallengeSectionTitle title="Round 2 Challenges" />
273+
{CANDIDATES_FEATURED_POSITIONS.map((position) => (
274+
<PositionPill
275+
key={position.id}
276+
position={position}
277+
completed={completedChallengeIds.includes(position.id)}
278+
/>
279+
))}
280+
</>
281+
) : null}
282+
{CANDIDATES_WARMUP_POSITIONS.length > 0 ? (
283+
<>
284+
<ChallengeSectionTitle title="Round 1 Challenges" />
285+
{CANDIDATES_WARMUP_POSITIONS.map((position) => (
286+
<PositionPill
287+
key={position.id}
288+
position={position}
289+
completed={completedChallengeIds.includes(position.id)}
290+
/>
291+
))}
292+
</>
293+
) : null}
275294
</div>
276295
</main>
277296
</>

0 commit comments

Comments
 (0)