Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/Game/cube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function canOfferDouble(
game.cube.stateKind !== 'offered' &&
(!game.cube.owner || game.cube.owner.id === player.id) &&
// Disallow repeat doubles in same turn unless Beaver is implemented
(game.cube as any).offeredThisTurnBy?.id !== player.id
game.cube.offeredThisTurnBy?.id !== player.id
)
}

Expand Down Expand Up @@ -107,13 +107,16 @@ export function acceptDouble(
...offeringPlayer,
stateKind: 'rolling',
dice: Dice.initialize(offeringPlayer.color, 'rolling'),
rollForStartValue: (offeringPlayer as any).rollForStartValue,
// Non-null: an active player mid-game has a rollForStartValue; the base
// player type declares it optional, the rolling player type requires it.
rollForStartValue: offeringPlayer.rollForStartValue!,
}
const updatedInactivePlayer: BackgammonPlayerInactive = {
...player,
stateKind: 'inactive',
dice: Dice.initialize(player.color, 'inactive'),
rollForStartValue: (player as any).rollForStartValue,
// Non-null: see above; inactive player type also requires rollForStartValue.
rollForStartValue: player.rollForStartValue!,
}

const updatedPlayers = game.players.map((p) => {
Expand All @@ -130,8 +133,10 @@ export function acceptDouble(
activePlayer: updatedActivePlayer,
inactivePlayer: updatedInactivePlayer,
activeColor: updatedActivePlayer.color,
activePlay: undefined as any,
} as any)
activePlay: undefined,
// as unknown as BackgammonGameRolling: the spread yields a generic players
// array (not the rolling-game tuple) that TS can't narrow structurally.
} as unknown as BackgammonGameRolling)
}

export function canRefuseDouble(
Expand Down
2 changes: 2 additions & 0 deletions src/Game/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export class Game {
*/
get gnuPositionId(): string {
try {
// as any: the Game class instance is structurally a BackgammonGame but
// TS does not treat the class as assignable to the discriminated union.
return exportToGnuPositionId(this as any)
} catch (error) {
logger.warn('Failed to generate gnuPositionId:', error)
Expand Down
16 changes: 8 additions & 8 deletions src/Game/turnFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -752,14 +752,14 @@ export function move(
): BackgammonGameMoving | BackgammonGameMoved | BackgammonGameCompleted {
// Push a pre-move snapshot to the turn-local undo stack
try {
const ap: any = (game as any).activePlay
const ap = game.activePlay
if (ap) {
if (!ap.undo) ap.undo = { frames: [] }
const undo = ap.undo ?? (ap.undo = { frames: [] })
const snapshot =
typeof structuredClone === 'function'
? structuredClone(game)
: (JSON.parse(JSON.stringify(game)) as any)
ap.undo.frames.push(snapshot)
: (JSON.parse(JSON.stringify(game)) as BackgammonGameMoving)
undo.frames.push(snapshot)
}
} catch (e) {
logger?.warn?.('Failed to push undo snapshot in Game.move', e)
Expand Down Expand Up @@ -1207,14 +1207,14 @@ export function executeAndRecalculate(

// Push a pre-move snapshot
try {
const ap: any = (game as any).activePlay
const ap = game.activePlay
if (ap) {
if (!ap.undo) ap.undo = { frames: [] }
const undo = ap.undo ?? (ap.undo = { frames: [] })
const snapshot =
typeof structuredClone === 'function'
? structuredClone(game)
: (JSON.parse(JSON.stringify(game)) as any)
ap.undo.frames.push(snapshot)
: (JSON.parse(JSON.stringify(game)) as BackgammonGameMoving)
undo.frames.push(snapshot)
}
} catch (e) {
logger?.warn?.('Failed to push undo snapshot before move', e)
Expand Down