Skip to content

Commit b9a9fd8

Browse files
fix: bugs with play mode
1 parent f458371 commit b9a9fd8

1 file changed

Lines changed: 40 additions & 20 deletions

File tree

src/hooks/useOpeningDrillController/useOpeningDrillController.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useMemo, useCallback, useEffect } from 'react'
1+
import { useState, useMemo, useCallback, useEffect, useRef } from 'react'
22
import { Chess, PieceSymbol } from 'chess.ts'
33
import { getGameMove } from 'src/api/play/play'
44
import { useTreeController } from '../useTreeController'
@@ -96,12 +96,27 @@ export const useOpeningDrillController = (selections: OpeningSelection[]) => {
9696
currentSelection?.playerColor || 'white',
9797
)
9898

99+
// Set board orientation based on player color
100+
useEffect(() => {
101+
if (currentSelection?.playerColor) {
102+
controller.setOrientation(currentSelection.playerColor)
103+
}
104+
}, [currentSelection?.playerColor, controller])
105+
99106
// Sync controller when switching selections
100107
useEffect(() => {
101-
if (currentDrillGame?.tree) {
108+
if (currentDrillGame?.tree && currentDrillGame.moves.length === 0) {
109+
// Only reset to root if no moves have been made
102110
controller.setCurrentNode(currentDrillGame.tree.getRoot())
111+
} else if (currentDrillGame?.tree && currentDrillGame.moves.length > 0) {
112+
// Navigate to the last move if moves exist
113+
const mainLine = currentDrillGame.tree.getMainLine()
114+
const targetNode = mainLine[currentDrillGame.moves.length] // moves.length is 0-based, but mainLine includes root at index 0
115+
if (targetNode) {
116+
controller.setCurrentNode(targetNode)
117+
}
103118
}
104-
}, [currentSelectionIndex, currentDrillGame?.tree, controller])
119+
}, [currentSelectionIndex, controller])
105120

106121
// Determine if it's the player's turn
107122
const isPlayerTurn = useMemo(() => {
@@ -135,35 +150,34 @@ export const useOpeningDrillController = (selections: OpeningSelection[]) => {
135150
if (!currentDrillGame || !controller.currentNode || !isPlayerTurn) return
136151

137152
try {
138-
// Add the player's move to the game tree
153+
// Validate the move first
139154
const chess = new Chess(controller.currentNode.fen)
140-
const moveObj = chess.move({
141-
from: moveUci.slice(0, 2),
142-
to: moveUci.slice(2, 4),
143-
promotion: moveUci[4] ? (moveUci[4] as PieceSymbol) : undefined,
144-
})
155+
const moveObj = chess.move(moveUci, { sloppy: true })
145156

146157
if (!moveObj) return
147158

159+
// Add the move to the game tree
148160
const newNode = currentDrillGame.tree.addMoveToMainLine(moveUci)
149161
if (newNode) {
150-
controller.setCurrentNode(newNode)
151-
152-
// Update the drill game
162+
// Update the drill game state first
153163
const updatedGame = {
154164
...currentDrillGame,
155165
moves: [...currentDrillGame.moves, moveUci],
156166
currentFen: newNode.fen,
157167
}
168+
158169
setDrillGames((prev) => ({
159170
...prev,
160171
[currentSelection.id]: updatedGame,
161172
}))
162173

174+
// Then update the controller to the new node
175+
controller.setCurrentNode(newNode)
176+
163177
// Get Maia's response after a short delay
164178
setTimeout(async () => {
165-
await makeMaiaMove(newNode)
166-
}, 500)
179+
await makeMaiaMoveRef.current(newNode)
180+
}, 800)
167181
}
168182
} catch (error) {
169183
console.error('Error making player move:', error)
@@ -179,7 +193,7 @@ export const useOpeningDrillController = (selections: OpeningSelection[]) => {
179193

180194
try {
181195
const response = await getGameMove(
182-
currentDrillGame.moves,
196+
[],
183197
currentSelection.maiaVersion,
184198
fromNode.fen,
185199
null,
@@ -191,18 +205,20 @@ export const useOpeningDrillController = (selections: OpeningSelection[]) => {
191205
if (maiaMove) {
192206
const newNode = currentDrillGame.tree.addMoveToMainLine(maiaMove)
193207
if (newNode) {
194-
controller.setCurrentNode(newNode)
195-
196-
// Update the drill game
208+
// Update the drill game state first
197209
const updatedGame = {
198210
...currentDrillGame,
199211
moves: [...currentDrillGame.moves, maiaMove],
200212
currentFen: newNode.fen,
201213
}
214+
202215
setDrillGames((prev) => ({
203216
...prev,
204217
[currentSelection.id]: updatedGame,
205218
}))
219+
220+
// Then update the controller to the new node
221+
controller.setCurrentNode(newNode)
206222
}
207223
}
208224
} catch (error) {
@@ -212,6 +228,10 @@ export const useOpeningDrillController = (selections: OpeningSelection[]) => {
212228
[currentDrillGame, controller, currentSelection],
213229
)
214230

231+
// Store makeMaiaMove in a ref to avoid circular dependencies
232+
const makeMaiaMoveRef = useRef(makeMaiaMove)
233+
makeMaiaMoveRef.current = makeMaiaMove
234+
215235
// Handle initial Maia move if needed
216236
useEffect(() => {
217237
if (
@@ -222,10 +242,10 @@ export const useOpeningDrillController = (selections: OpeningSelection[]) => {
222242
) {
223243
// It's Maia's turn to move first
224244
setTimeout(() => {
225-
makeMaiaMove(controller.currentNode)
245+
makeMaiaMoveRef.current(controller.currentNode)
226246
}, 1000)
227247
}
228-
}, [currentDrillGame, controller.currentNode, isPlayerTurn, makeMaiaMove])
248+
}, [currentDrillGame, controller.currentNode, isPlayerTurn])
229249

230250
// Switch to a different opening selection
231251
const switchToSelection = useCallback(

0 commit comments

Comments
 (0)