UNPKG

shogiground

Version:
399 lines 14.8 kB
import { callUserFunction, opposite, pieceNameOf, samePiece } from './util.js'; import { addToHand, removeFromHand } from './hands.js'; export function toggleOrientation(state) { state.orientation = opposite(state.orientation); state.animation.current = state.draggable.current = state.promotion.current = state.hovered = state.selected = state.selectedPiece = undefined; } export function reset(state) { unselect(state); unsetPremove(state); unsetPredrop(state); cancelPromotion(state); state.animation.current = state.draggable.current = state.hovered = undefined; } export function setPieces(state, pieces) { for (const [key, piece] of pieces) { if (piece) state.pieces.set(key, piece); else state.pieces.delete(key); } } export function setChecks(state, checksValue) { if (Array.isArray(checksValue)) { state.checks = checksValue; } else { if (checksValue === true) checksValue = state.turnColor; if (checksValue) { const checks = []; for (const [k, p] of state.pieces) { if (state.highlight.checkRoles.includes(p.role) && p.color === checksValue) checks.push(k); } state.checks = checks; } else state.checks = undefined; } } function setPremove(state, orig, dest, prom) { unsetPredrop(state); state.premovable.current = { orig, dest, prom }; callUserFunction(state.premovable.events.set, orig, dest, prom); } export function unsetPremove(state) { if (state.premovable.current) { state.premovable.current = undefined; callUserFunction(state.premovable.events.unset); } } function setPredrop(state, piece, key, prom) { unsetPremove(state); state.predroppable.current = { piece, key, prom }; callUserFunction(state.predroppable.events.set, piece, key, prom); } export function unsetPredrop(state) { if (state.predroppable.current) { state.predroppable.current = undefined; callUserFunction(state.predroppable.events.unset); } } export function baseMove(state, orig, dest, prom) { const origPiece = state.pieces.get(orig), destPiece = state.pieces.get(dest); if (orig === dest || !origPiece) return false; const captured = destPiece && destPiece.color !== origPiece.color ? destPiece : undefined, promPiece = prom && promotePiece(state, origPiece); if (dest === state.selected || orig === state.selected) unselect(state); state.pieces.set(dest, promPiece || origPiece); state.pieces.delete(orig); state.lastDests = [orig, dest]; state.lastPiece = undefined; state.checks = undefined; callUserFunction(state.events.move, orig, dest, prom, captured); callUserFunction(state.events.change); return captured || true; } export function baseDrop(state, piece, key, prom) { var _a; const pieceCount = ((_a = state.hands.handMap.get(piece.color)) === null || _a === void 0 ? void 0 : _a.get(piece.role)) || 0; if (!pieceCount && !state.droppable.spare) return false; const promPiece = prom && promotePiece(state, piece); if (key === state.selected || (!state.droppable.spare && pieceCount === 1 && state.selectedPiece && samePiece(state.selectedPiece, piece))) unselect(state); state.pieces.set(key, promPiece || piece); state.lastDests = [key]; state.lastPiece = piece; state.checks = undefined; if (!state.droppable.spare) removeFromHand(state, piece); callUserFunction(state.events.drop, piece, key, prom); callUserFunction(state.events.change); return true; } function baseUserMove(state, orig, dest, prom) { const result = baseMove(state, orig, dest, prom); if (result) { state.movable.dests = undefined; state.droppable.dests = undefined; state.turnColor = opposite(state.turnColor); state.animation.current = undefined; } return result; } function baseUserDrop(state, piece, key, prom) { const result = baseDrop(state, piece, key, prom); if (result) { state.movable.dests = undefined; state.droppable.dests = undefined; state.turnColor = opposite(state.turnColor); state.animation.current = undefined; } return result; } export function userDrop(state, piece, key, prom) { const realProm = prom || state.promotion.forceDropPromotion(piece, key); if (canDrop(state, piece, key)) { const result = baseUserDrop(state, piece, key, realProm); if (result) { unselect(state); callUserFunction(state.droppable.events.after, piece, key, realProm, { premade: false }); return true; } } else if (canPredrop(state, piece, key)) { setPredrop(state, piece, key, realProm); unselect(state); return true; } unselect(state); return false; } export function userMove(state, orig, dest, prom) { const realProm = prom || state.promotion.forceMovePromotion(orig, dest); if (canMove(state, orig, dest)) { const result = baseUserMove(state, orig, dest, realProm); if (result) { unselect(state); const metadata = { premade: false }; if (result !== true) metadata.captured = result; callUserFunction(state.movable.events.after, orig, dest, realProm, metadata); return true; } } else if (canPremove(state, orig, dest)) { setPremove(state, orig, dest, realProm); unselect(state); return true; } unselect(state); return false; } export function basePromotionDialog(state, piece, key) { const promotedPiece = promotePiece(state, piece); if (state.viewOnly || state.promotion.current || !promotedPiece) return false; state.promotion.current = { piece, promotedPiece, key, dragged: !!state.draggable.current }; state.hovered = key; return true; } export function promotionDialogDrop(state, piece, key) { if (canDropPromote(state, piece, key) && (canDrop(state, piece, key) || canPredrop(state, piece, key))) { if (basePromotionDialog(state, piece, key)) { callUserFunction(state.promotion.events.initiated); return true; } } return false; } export function promotionDialogMove(state, orig, dest) { if (canMovePromote(state, orig, dest) && (canMove(state, orig, dest) || canPremove(state, orig, dest))) { const piece = state.pieces.get(orig); if (piece && basePromotionDialog(state, piece, dest)) { callUserFunction(state.promotion.events.initiated); return true; } } return false; } function promotePiece(s, piece) { const promRole = s.promotion.promotesTo(piece.role); return promRole !== undefined ? { color: piece.color, role: promRole } : undefined; } export function deletePiece(state, key) { if (state.pieces.delete(key)) callUserFunction(state.events.change); } export function selectSquare(state, key, prom, force) { callUserFunction(state.events.select, key); // unselect if selecting selected key, keep selected for drag if (!state.draggable.enabled && state.selected === key) { callUserFunction(state.events.unselect, key); unselect(state); return; } // try moving/dropping if (state.selectable.enabled || force || (state.selectable.forceSpares && state.selectedPiece && state.droppable.spare)) { if (state.selectedPiece && userDrop(state, state.selectedPiece, key, prom)) return; else if (state.selected && userMove(state, state.selected, key, prom)) return; } if ((state.selectable.enabled || state.draggable.enabled || force) && (isMovable(state, key) || isPremovable(state, key))) { setSelected(state, key); } } export function selectPiece(state, piece, spare, force, api) { callUserFunction(state.events.pieceSelect, piece); if (state.selectable.addSparesToHand && state.droppable.spare && state.selectedPiece) { addToHand(state, { role: state.selectedPiece.role, color: piece.color }); callUserFunction(state.events.change); unselect(state); } else if (!api && !state.draggable.enabled && state.selectedPiece && samePiece(state.selectedPiece, piece)) { callUserFunction(state.events.pieceUnselect, piece); unselect(state); } else if ((state.selectable.enabled || state.draggable.enabled || force) && (isDroppable(state, piece, !!spare) || isPredroppable(state, piece))) { setSelectedPiece(state, piece); state.droppable.spare = !!spare; } else { unselect(state); } } export function setSelected(state, key) { unselect(state); state.selected = key; setPreDests(state); } export function setSelectedPiece(state, piece) { unselect(state); state.selectedPiece = piece; setPreDests(state); } export function setPreDests(state) { state.premovable.dests = state.predroppable.dests = undefined; if (state.selected && isPremovable(state, state.selected) && state.premovable.generate) state.premovable.dests = state.premovable.generate(state.selected, state.pieces); else if (state.selectedPiece && isPredroppable(state, state.selectedPiece) && state.predroppable.generate) state.predroppable.dests = state.predroppable.generate(state.selectedPiece, state.pieces); } export function unselect(state) { state.selected = state.selectedPiece = state.premovable.dests = state.predroppable.dests = state.promotion.current = undefined; state.droppable.spare = false; } function isMovable(state, orig) { const piece = state.pieces.get(orig); return (!!piece && (state.activeColor === 'both' || (state.activeColor === piece.color && state.turnColor === piece.color))); } function isDroppable(state, piece, spare) { var _a; return ((spare || !!((_a = state.hands.handMap.get(piece.color)) === null || _a === void 0 ? void 0 : _a.get(piece.role))) && (state.activeColor === 'both' || (state.activeColor === piece.color && state.turnColor === piece.color))); } export function canMove(state, orig, dest) { var _a, _b; return (orig !== dest && isMovable(state, orig) && (state.movable.free || !!((_b = (_a = state.movable.dests) === null || _a === void 0 ? void 0 : _a.get(orig)) === null || _b === void 0 ? void 0 : _b.includes(dest)))); } export function canDrop(state, piece, dest) { var _a, _b; return (isDroppable(state, piece, state.droppable.spare) && (state.droppable.free || state.droppable.spare || !!((_b = (_a = state.droppable.dests) === null || _a === void 0 ? void 0 : _a.get(pieceNameOf(piece))) === null || _b === void 0 ? void 0 : _b.includes(dest)))); } function canMovePromote(state, orig, dest) { const piece = state.pieces.get(orig); return !!piece && state.promotion.movePromotionDialog(orig, dest); } function canDropPromote(state, piece, key) { return !state.droppable.spare && state.promotion.dropPromotionDialog(piece, key); } function isPremovable(state, orig) { const piece = state.pieces.get(orig); return (!!piece && state.premovable.enabled && state.activeColor === piece.color && state.turnColor !== piece.color); } function isPredroppable(state, piece) { var _a; return (!!((_a = state.hands.handMap.get(piece.color)) === null || _a === void 0 ? void 0 : _a.get(piece.role)) && state.predroppable.enabled && state.activeColor === piece.color && state.turnColor !== piece.color); } export function canPremove(state, orig, dest) { return (orig !== dest && isPremovable(state, orig) && !!state.premovable.generate && state.premovable.generate(orig, state.pieces).includes(dest)); } export function canPredrop(state, piece, dest) { const destPiece = state.pieces.get(dest); return (isPredroppable(state, piece) && (!destPiece || destPiece.color !== state.activeColor) && !!state.predroppable.generate && state.predroppable.generate(piece, state.pieces).includes(dest)); } export function isDraggable(state, piece) { return (state.draggable.enabled && (state.activeColor === 'both' || (state.activeColor === piece.color && (state.turnColor === piece.color || state.premovable.enabled)))); } export function playPremove(state) { const move = state.premovable.current; if (!move) return false; const orig = move.orig, dest = move.dest, prom = move.prom; let success = false; if (canMove(state, orig, dest)) { const result = baseUserMove(state, orig, dest, prom); if (result) { const metadata = { premade: true }; if (result !== true) metadata.captured = result; callUserFunction(state.movable.events.after, orig, dest, prom, metadata); success = true; } } unsetPremove(state); return success; } export function playPredrop(state) { const drop = state.predroppable.current; if (!drop) return false; const piece = drop.piece, key = drop.key, prom = drop.prom; let success = false; if (canDrop(state, piece, key)) { if (baseUserDrop(state, piece, key, prom)) { callUserFunction(state.droppable.events.after, piece, key, prom, { premade: true }); success = true; } } unsetPredrop(state); return success; } export function cancelMoveOrDrop(state) { unsetPremove(state); unsetPredrop(state); unselect(state); } export function cancelPromotion(state) { if (!state.promotion.current) return; unselect(state); state.promotion.current = undefined; state.hovered = undefined; callUserFunction(state.promotion.events.cancel); } export function stop(state) { state.activeColor = state.movable.dests = state.droppable.dests = state.draggable.current = state.animation.current = state.promotion.current = state.hovered = undefined; cancelMoveOrDrop(state); } //# sourceMappingURL=board.js.map