// ============ AURA — Chess board + pipeline ============ const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA } = React; // Unicode pieces. Uppercase = white, lowercase = black. const PIECE_GLYPH = { 'K':'♔','Q':'♕','R':'♖','B':'♗','N':'♘','P':'♙', 'k':'♚','q':'♛','r':'♜','b':'♝','n':'♞','p':'♟' }; const INITIAL_BOARD = [ ['r','n','b','q','k','b','n','r'], ['p','p','p','p','p','p','p','p'], ['','','','','','','',''], ['','','','','','','',''], ['','','','','','','',''], ['','','','','','','',''], ['P','P','P','P','P','P','P','P'], ['R','N','B','Q','K','B','N','R'] ]; const isWhite = (p) => p && p === p.toUpperCase(); const isBlack = (p) => p && p === p.toLowerCase(); function inB(r, c) { return r >= 0 && r < 8 && c >= 0 && c < 8; } // Basic legal moves per piece (no check detection, no castling/en-passant). function pieceMoves(board, r, c) { const p = board[r][c]; if (!p) return []; const moves = []; const own = isWhite(p) ? isWhite : isBlack; const enemy = isWhite(p) ? isBlack : isWhite; const t = p.toLowerCase(); const slide = (dirs) => { for (const [dr, dc] of dirs) { let nr = r + dr, nc = c + dc; while (inB(nr, nc)) { if (!board[nr][nc]) moves.push([nr, nc]); else { if (enemy(board[nr][nc])) moves.push([nr, nc]); break; } nr += dr; nc += dc; } } }; if (t === 'p') { const dir = isWhite(p) ? -1 : 1; const startRow = isWhite(p) ? 6 : 1; if (inB(r + dir, c) && !board[r + dir][c]) { moves.push([r + dir, c]); if (r === startRow && !board[r + 2 * dir][c]) moves.push([r + 2 * dir, c]); } for (const dc of [-1, 1]) { const nr = r + dir, nc = c + dc; if (inB(nr, nc) && board[nr][nc] && enemy(board[nr][nc])) moves.push([nr, nc]); } } else if (t === 'n') { [[-2,-1],[-2,1],[-1,-2],[-1,2],[1,-2],[1,2],[2,-1],[2,1]].forEach(([dr, dc]) => { const nr = r + dr, nc = c + dc; if (inB(nr, nc) && (!board[nr][nc] || enemy(board[nr][nc]))) moves.push([nr, nc]); }); } else if (t === 'b') { slide([[-1,-1],[-1,1],[1,-1],[1,1]]); } else if (t === 'r') { slide([[-1,0],[1,0],[0,-1],[0,1]]); } else if (t === 'q') { slide([[-1,-1],[-1,1],[1,-1],[1,1],[-1,0],[1,0],[0,-1],[0,1]]); } else if (t === 'k') { for (let dr = -1; dr <= 1; dr++) for (let dc = -1; dc <= 1; dc++) { if (!dr && !dc) continue; const nr = r + dr, nc = c + dc; if (inB(nr, nc) && (!board[nr][nc] || enemy(board[nr][nc]))) moves.push([nr, nc]); } } return moves; } function allMoves(board, side) { // side: 'w' or 'b' const out = []; for (let r = 0; r < 8; r++) for (let c = 0; c < 8; c++) { const p = board[r][c]; if (!p) continue; if (side === 'w' && !isWhite(p)) continue; if (side === 'b' && !isBlack(p)) continue; for (const [nr, nc] of pieceMoves(board, r, c)) out.push({ from: [r, c], to: [nr, nc] }); } return out; } function applyMove(board, from, to) { const nb = board.map(row => row.slice()); let p = nb[from[0]][from[1]]; nb[from[0]][from[1]] = ''; // Auto-promote pawn to queen if (p === 'P' && to[0] === 0) p = 'Q'; if (p === 'p' && to[0] === 7) p = 'q'; nb[to[0]][to[1]] = p; return nb; } function ChessBoard() { const [board, setBoard] = useStateA(INITIAL_BOARD); const [turn, setTurn] = useStateA('w'); const [sel, setSel] = useStateA(null); const [last, setLast] = useStateA(null); // {from, to} const [status, setStatus] = useStateA('Tu turno'); const [depth, setDepth] = useStateA(3); const selectableMoves = useMemoA(() => { if (!sel) return []; return pieceMoves(board, sel[0], sel[1]); }, [board, sel]); // AURA move useEffectA(() => { if (turn !== 'b') return; setStatus('AURA pensando...'); const start = performance.now(); // simulate thinking const tm = setTimeout(() => { const moves = allMoves(board, 'b'); if (moves.length === 0) { setStatus('Sin movimientos. Empate o jaque mate.'); return; } // crude scoring: prefer captures const scored = moves.map(m => { const target = board[m.to[0]][m.to[1]]; const val = { p:1, n:3, b:3, r:5, q:9, k:100 }[target?.toLowerCase()] || 0; return { ...m, score: val + Math.random() * 0.5 }; }); scored.sort((a,b) => b.score - a.score); // pick top 3 randomly to add variety const pick = scored[Math.floor(Math.random() * Math.min(3, scored.length))]; const nb = applyMove(board, pick.from, pick.to); setBoard(nb); setLast({ from: pick.from, to: pick.to }); setTurn('w'); setStatus('Tu turno'); setDepth(d => 1 + Math.floor(Math.random() * 4)); }, 800 + Math.random() * 600); return () => clearTimeout(tm); }, [turn, board]); const onSq = (r, c) => { if (turn !== 'w') return; const p = board[r][c]; if (sel) { // try to move const valid = selectableMoves.some(([nr, nc]) => nr === r && nc === c); if (valid) { const nb = applyMove(board, sel, [r, c]); setBoard(nb); setLast({ from: sel, to: [r, c] }); setSel(null); setTurn('b'); return; } if (p && isWhite(p)) { setSel([r, c]); return; } setSel(null); } else if (p && isWhite(p)) { setSel([r, c]); } }; const reset = () => { setBoard(INITIAL_BOARD); setSel(null); setLast(null); setTurn('w'); setStatus('Tu turno'); }; return (
{t.aura.sub}
{tr.body}
{s.desc}