// 终端字符盘面:点顶六边形按行错位显示。每格 4 字符宽,相邻行错开 2 字符。 import type { HexBoard } from '../src/board'; export function renderAscii(board: HexBoard, path?: number[]): string { const stepOf = new Map(); if (path) path.forEach((c, i) => stepOf.set(c, i + 1)); let minR = Infinity; let maxR = -Infinity; let minX = Infinity; for (const c of board.cells) { minR = Math.min(minR, c.r); maxR = Math.max(maxR, c.r); minX = Math.min(minX, 2 * c.q + c.r); } const lines: string[] = []; for (let r = minR; r <= maxR; r++) { const row = board.cells.filter((c) => c.r === r).sort((a, b) => a.q - b.q); let line = ''; for (const c of row) { const col = (2 * c.q + c.r - minX) * 2; while (line.length < col) line += ' '; let tok: string; if (path) { const s = stepOf.get(c.index); tok = s === undefined ? ' . ' : String(s).padStart(2) + ' '; if (c.clue !== null && s !== undefined) tok = String(s).padStart(2) + (s === c.clue ? '*' : '!'); } else { tok = c.clue !== null ? `[${c.clue}]`.padStart(3) : ` ${c.id.slice(0, 2).padEnd(2)}`; } line += tok.padEnd(4); } lines.push(line.replace(/\s+$/, '')); } if (board.walls.length) { lines.push('墙: ' + board.walls.map((w) => `${board.cells[w.a].id}|${board.cells[w.b].id}`).join(' ')); } if (board.spinners.length) { lines.push( '转墙: ' + board.spinners .map((sp) => { const e = sp.edges.map((x) => (x ? `${board.cells[x[0]].id}|${board.cells[x[1]].id}` : '外')).join(' → '); return `${board.cells[sp.cell].id}/${sp.corner} 相位${sp.phase} [${e}]`; }) .join(' '), ); } return lines.join('\n'); } export function pathToIds(board: HexBoard, path: number[]): string { return path.map((i) => board.cells[i].id).join(','); }