function makeMove(variant: VariantKey, board: Board, uci: string) { if (!board.turn) board.fmvn++; const turn = board.turn = !board.turn; if (uci.includes('@')) { board.pieces[square(uci.slice(2, 4))] = (turn ? uci[0].toLowerCase() : uci[0]) as Piece; return; } const move = decomposeUci(uci), from = square(move[0]), p = board.pieces[from]; let to = square(move[1]), capture = board.pieces[to]; if (p === 'p' || p === 'P') { if (uci[0] !== uci[2] && !capture) { // en passant delete board.pieces[to + (turn ? 8 : -8)]; capture = turn ? 'p' : 'P'; } } if (p === 'k' || p === 'K') { // castling var frCastle = capture && isBlack(p) === isBlack(capture); if (frCastle || squareDist(from, to) > 1) { delete board.pieces[from]; if (frCastle) delete board.pieces[to]; if (to < from) { if (!frCastle) delete board.pieces[turn ? square('a8') : square('a1')]; to = turn ? square('c8') : square('c1'); board.pieces[to + 1] = turn ? 'r' : 'R'; } else { if (!frCastle) delete board.pieces[turn ? square('h8') : square('h1')]; to = turn ? square('g8') : square('g1'); board.pieces[to - 1] = turn ? 'r' : 'R'; } board.pieces[to] = p; board[p] = to; return; } board[p] = to; } if (move[2]) board.pieces[to] = (turn ? move[2] : move[2].toUpperCase()) as Piece; else board.pieces[to] = p; delete board.pieces[from]; // atomic explosion if (variant === 'atomic' && capture) { delete board.pieces[to]; kingMovesTo(to).forEach(function (o) { if (board.pieces[o] !== 'p' && board.pieces[o] !== 'P') delete board.pieces[o]; }); } }
function makeAutoShapesFromUci(uci: Uci, brush: string, modifiers?: any): DrawShape[] { const move = decomposeUci(uci); return [{ orig: move[0], dest: move[1], brush: brush, modifiers: modifiers }]; }
function san(board: Board, uci: string): string { if (uci.includes('@')) return fixCrazySan(uci); var move = decomposeUci(uci); var from = square(move[0]); var to = square(move[1]); var p = board.pieces[from]; if (!p) return '--'; var d = board.pieces[to]; var pt = p.toLowerCase(); // pawn moves if (pt === 'p') { let san; if (uci[0] === uci[2]) san = move[1]; else san = uci[0] + 'x' + move[1]; if (move[2]) san += '=' + move[2].toUpperCase(); return san; } // castling if (pt == 'k' && ((d && isBlack(p) === isBlack(d)) || squareDist(from, to) > 1)) { if (to < from) return 'O-O-O'; else return 'O-O'; } var san = pt.toUpperCase(); // disambiguate normal moves var candidates: Square[] = []; if (pt == 'k') candidates = kingMovesTo(to); else if (pt == 'n') candidates = knightMovesTo(to); else if (pt == 'r') candidates = slidingMovesTo(to, ROOK_DELTAS, board); else if (pt == 'b') candidates = slidingMovesTo(to, BISHOP_DELTAS, board); else if (pt == 'q') candidates = slidingMovesTo(to, QUEEN_DELTAS, board); let rank = false, file = false, i: number; for (i = 0; i < candidates.length; i++) { if (candidates[i] === from || board.pieces[candidates[i]] !== p) continue; if ((from >> 3) === (candidates[i] >> 3)) file = true; if ((from & 7) === (candidates[i] & 7)) rank = true; else file = true; } if (file) san += uci[0]; if (rank) san += uci[1]; // target if (d) san += 'x'; san += move[1]; return san; }
return function() { if (vm.mode === 'view') return; if (!pathOps.contains(vm.path, vm.initialPath)) return; var playedByColor = vm.node.ply % 2 === 1 ? 'white' : 'black'; if (playedByColor !== puzzle.color) return; var nodes = vm.nodeList.slice(pathOps.size(vm.initialPath) + 1).map(function(node) { return { uci: node.uci, castle: node.san.startsWith('O-O') }; }); var progress = puzzle.lines; for (var i in nodes) { if (progress[nodes[i].uci]) progress = progress[nodes[i].uci]; else if (nodes[i].castle) progress = progress[altCastles[nodes[i].uci]] || 'fail'; else progress = 'fail'; if (typeof progress === 'string') break; } if (typeof progress === 'string') { vm.node.puzzle = progress; return progress; } var nextKey = Object.keys(progress)[0] if (progress[nextKey] === 'win') { vm.node.puzzle = 'win'; return 'win'; } // from here we have a next move vm.node.puzzle = 'good'; var opponentUci = decomposeUci(nextKey); var promotion = opponentUci[2] ? sanToRole[opponentUci[2].toUpperCase()] : null; var move: any = { orig: opponentUci[0], dest: opponentUci[1], fen: vm.node.fen, path: vm.path }; if (promotion) move.promotion = promotion; return move; };
export function makeShapesFromUci(color: Color, uci: Uci, brush: string, modifiers?: any): DrawShape[] { const move = decomposeUci(uci); if (uci[1] === '@') return [ { orig: move[1], brush }, pieceDrop(move[1] as cg.Key, sanToRole[uci[0].toUpperCase()], color) ]; const shapes: DrawShape[] = [{ orig: move[0], dest: move[1], brush, modifiers }]; if (move[2]) shapes.push(pieceDrop(move[1]!, move[2] as cg.Role, color)); return shapes; }
function playUci(uci) { var move = decomposeUci(uci); if (!move[2]) sendMove(move[0], move[1]) else sendMove(move[0], move[1], sanToRole[move[2].toUpperCase()]); };