fix: some boop states are not updated in produce

This commit is contained in:
hypercross 2026-04-04 15:23:56 +08:00
parent aba035f2ec
commit 0dbb4fc2ba
1 changed files with 38 additions and 29 deletions

View File

@ -193,7 +193,6 @@ export function placePiece(host: MutableSignal<BoopState>, row: number, col: num
} }
export function applyBoops(host: MutableSignal<BoopState>, placedRow: number, placedCol: number, placedType: PieceType) { export function applyBoops(host: MutableSignal<BoopState>, placedRow: number, placedCol: number, placedType: PieceType) {
const board = getBoardRegion(host);
const pieces = host.value.pieces; const pieces = host.value.pieces;
const piecesArray = Object.values(pieces); const piecesArray = Object.values(pieces);
@ -216,39 +215,49 @@ export function applyBoops(host: MutableSignal<BoopState>, placedRow: number, pl
} }
} }
for (const { part, dr, dc } of piecesToBoop) { host.produce(state => {
const [r, c] = part.position; const board = state.board;
const newRow = r + dr; const currentPieces = state.pieces;
const newCol = c + dc;
if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) { for (const { part, dr, dc } of piecesToBoop) {
const pt = part.pieceType; const [r, c] = part.position;
const pl = part.player; const newRow = r + dr;
const playerData = getPlayer(host, pl); const newCol = c + dc;
removePieceFromBoard(host, part);
incrementSupply(playerData, pt); if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) {
continue; const pt = part.pieceType;
const pl = part.player;
const playerData = state.players[pl];
// Remove piece from board
board.childIds = board.childIds.filter(id => id !== part.id);
delete board.partMap[part.position.join(',')];
delete currentPieces[part.id];
playerData[pt].placed--;
playerData[pt].supply++;
continue;
}
// Check if target cell is occupied
const targetPosKey = `${newRow},${newCol}`;
if (board.partMap[targetPosKey]) continue;
// Move piece to new position
delete board.partMap[part.position.join(',')];
part.position = [newRow, newCol];
board.partMap[targetPosKey] = part.id;
} }
});
if (isCellOccupied(host, newRow, newCol)) continue;
part.position = [newRow, newCol];
board.partMap = Object.fromEntries(
board.childIds.map(id => {
const p = pieces[id];
return [p.position.join(','), id];
})
);
}
} }
export function removePieceFromBoard(host: MutableSignal<BoopState>, part: BoopPart) { export function removePieceFromBoard(host: MutableSignal<BoopState>, part: BoopPart) {
const board = getBoardRegion(host); host.produce(state => {
const playerData = getPlayer(host, part.player); const board = state.board;
board.childIds = board.childIds.filter(id => id !== part.id); const playerData = state.players[part.player];
delete board.partMap[part.position.join(',')]; board.childIds = board.childIds.filter(id => id !== part.id);
delete host.value.pieces[part.id]; delete board.partMap[part.position.join(',')];
playerData[part.pieceType].placed--; delete state.pieces[part.id];
playerData[part.pieceType].placed--;
});
} }
const DIRECTIONS: [number, number][] = [ const DIRECTIONS: [number, number][] = [