/
docNemo
/
tactic-hack-core
Обзор
Документация
Войти
/
docNemo
/
tactic-hack-core
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/placement.ts
50 строк
2 KB
neo
Implement rules engine: geometry, placement, attack reducer, replay, projection, deduction, protocol types
19 июл 2026, 00:03
19 июл 2026, 00:03
d1403fb
Код
Авторство
О чём код?
import { sharedAxis } from "./geometry.js"; import { Cell, inBounds, sameCell, SHIPS_PER_PLAYER } from "./types.js"; export type PlacementError = | "outOfBounds" | "cellOccupied" | "cellOnLine" | "wrongShipCount"; export type PlacementResult = | { ok: true } | { ok: false; code: PlacementError }; /** * Можно ли поставить корабль в `cell` при уже установленных `ships`: * клетка в поле, не занята кораблём и не пересекается линией другого корабля. */ export function validateShipPlacement( ships: readonly Cell[], cell: Cell, ): PlacementResult { if (!inBounds(cell)) return { ok: false, code: "outOfBounds" }; if (ships.some((ship) => sameCell(ship, cell))) { return { ok: false, code: "cellOccupied" }; } if (ships.some((ship) => sharedAxis(ship, cell) !== null)) { return { ok: false, code: "cellOnLine" }; } return { ok: true }; } export function canPlaceShip(ships: readonly Cell[], cell: Cell): boolean { return validateShipPlacement(ships, cell).ok; } /** * Валидация финальной расстановки: ровно SHIPS_PER_PLAYER кораблей, * каждый последующий допустим относительно предыдущих (инвариант * «неатакующих ферзей»: никакие два не делят строку, столбец, диагональ). */ export function validatePlacement(ships: readonly Cell[]): PlacementResult { if (ships.length !== SHIPS_PER_PLAYER) { return { ok: false, code: "wrongShipCount" }; } for (let i = 0; i < ships.length; i++) { const result = validateShipPlacement(ships.slice(0, i), ships[i]!); if (!result.ok) return result; } return { ok: true }; }