fix: fix onitama black orientation

This commit is contained in:
hypercross 2026-04-08 09:00:25 +08:00
parent 98a12b9266
commit 5b310f400d
1 changed files with 36 additions and 18 deletions

View File

@ -34,6 +34,22 @@ function playerHasCard(state: OnitamaState, player: PlayerType, cardName: string
return cardList.includes(cardName); return cardList.includes(cardName);
} }
/**
*
* 180
*/
function getCardMoveCandidates(state: OnitamaState, cardName: string, player: PlayerType) {
const card = state.cards[cardName];
const candidates = card.moveCandidates;
// 黑方需要将卡牌旋转180度
if (player === 'black') {
return candidates.map(m => ({ dx: -m.dx, dy: -m.dy }));
}
return candidates;
}
/** /**
* *
*/ */
@ -42,7 +58,7 @@ function isValidMove(state: OnitamaState, cardName: string, fromX: number, fromY
if (!playerHasCard(state, player, cardName)) { if (!playerHasCard(state, player, cardName)) {
return `玩家 ${player} 不拥有卡牌 ${cardName}`; return `玩家 ${player} 不拥有卡牌 ${cardName}`;
} }
// 检查起始位置是否有玩家的棋子 // 检查起始位置是否有玩家的棋子
const fromPawn = getPawnAtPosition(state, fromX, fromY); const fromPawn = getPawnAtPosition(state, fromX, fromY);
if (!fromPawn) { if (!fromPawn) {
@ -51,34 +67,35 @@ function isValidMove(state: OnitamaState, cardName: string, fromX: number, fromY
if (fromPawn.owner !== player) { if (fromPawn.owner !== player) {
return `位置 (${fromX}, ${fromY}) 的棋子不属于玩家 ${player}`; return `位置 (${fromX}, ${fromY}) 的棋子不属于玩家 ${player}`;
} }
// 检查卡牌是否存在 // 检查卡牌是否存在
const card = state.cards[cardName]; const card = state.cards[cardName];
if (!card) { if (!card) {
return `卡牌 ${cardName} 不存在`; return `卡牌 ${cardName} 不存在`;
} }
// 计算移动偏移量 // 计算移动偏移量
const dx = toX - fromX; const dx = toX - fromX;
const dy = toY - fromY; const dy = toY - fromY;
// 检查移动是否在卡牌的移动候选项中 // 检查移动是否在卡牌的移动候选项中黑方需要旋转180度
const isValid = card.moveCandidates.some(m => m.dx === dx && m.dy === dy); const candidates = getCardMoveCandidates(state, cardName, player);
const isValid = candidates.some(m => m.dx === dx && m.dy === dy);
if (!isValid) { if (!isValid) {
return `卡牌 ${cardName} 不支持移动 (${dx}, ${dy})`; return `卡牌 ${cardName} 不支持移动 (${dx}, ${dy})`;
} }
// 检查目标位置是否在棋盘内 // 检查目标位置是否在棋盘内
if (!isInBounds(toX, toY)) { if (!isInBounds(toX, toY)) {
return `目标位置 (${toX}, ${toY}) 超出棋盘范围`; return `目标位置 (${toX}, ${toY}) 超出棋盘范围`;
} }
// 检查目标位置是否有己方棋子 // 检查目标位置是否有己方棋子
const toPawn = getPawnAtPosition(state, toX, toY); const toPawn = getPawnAtPosition(state, toX, toY);
if (toPawn && toPawn.owner === player) { if (toPawn && toPawn.owner === player) {
return `目标位置 (${toX}, ${toY}) 已有己方棋子`; return `目标位置 (${toX}, ${toY}) 已有己方棋子`;
} }
return null; return null;
} }
@ -236,26 +253,27 @@ const checkWin = registry.register({
*/ */
function getAvailableMoves(state: OnitamaState, player: PlayerType): Array<{card: string, fromX: number, fromY: number, toX: number, toY: number}> { function getAvailableMoves(state: OnitamaState, player: PlayerType): Array<{card: string, fromX: number, fromY: number, toX: number, toY: number}> {
const moves: Array<{card: string, fromX: number, fromY: number, toX: number, toY: number}> = []; const moves: Array<{card: string, fromX: number, fromY: number, toX: number, toY: number}> = [];
// 获取玩家的所有卡牌 // 获取玩家的所有卡牌
const cardNames = player === 'red' ? state.redCards : state.blackCards; const cardNames = player === 'red' ? state.redCards : state.blackCards;
// 获取玩家的所有棋子 // 获取玩家的所有棋子
const playerPawns = Object.values(state.pawns).filter(p => p.owner === player && p.regionId === 'board'); const playerPawns = Object.values(state.pawns).filter(p => p.owner === player && p.regionId === 'board');
// 对于每张卡牌 // 对于每张卡牌
for (const cardName of cardNames) { for (const cardName of cardNames) {
const card = state.cards[cardName]; // 获取旋转后的移动候选项黑方需要旋转180度
const candidates = getCardMoveCandidates(state, cardName, player);
// 对于每个棋子 // 对于每个棋子
for (const pawn of playerPawns) { for (const pawn of playerPawns) {
const [fromX, fromY] = pawn.position; const [fromX, fromY] = pawn.position;
// 对于卡牌的每个移动 // 对于卡牌的每个移动
for (const move of card.moveCandidates) { for (const move of candidates) {
const toX = fromX + move.dx; const toX = fromX + move.dx;
const toY = fromY + move.dy; const toY = fromY + move.dy;
// 检查移动是否合法 // 检查移动是否合法
if (isInBounds(toX, toY)) { if (isInBounds(toX, toY)) {
const targetPawn = getPawnAtPosition(state, toX, toY); const targetPawn = getPawnAtPosition(state, toX, toY);
@ -267,7 +285,7 @@ function getAvailableMoves(state: OnitamaState, player: PlayerType): Array<{card
} }
} }
} }
return moves; return moves;
} }