# Контракт бота v1 Загрузите один UTF-8 файл `.js` размером ≤100 КиБ, без импортов. Объявите синхронную `function move(state)`, возвращающую ровно `"up"`, `"down"`, `"left"` или `"right"` (не Promise). Координаты: `(0,0)` — левый верхний угол; `x` вправо, `y` вниз, `up` означает `y-1`. ## Состояние - `turn` — число уже завершённых ходов, первый вызов: `0`. - `board` — `{width,height,food:[{x,y}],hazards:[{x,y}]}`. - `you` — `{id,name,health,length,body:[{x,y},…]}`; голова первая. - `snakes` — все живые змеи, включая вас, в формате `you`. - `rules` — `{mode,timeoutMs,contractVersion:1}`. ## Standard: правила 1. Обычно поле 11×11, 2–6 змей, длина 3, здоровье 100; старты зеркально симметричны. 2. Все получают один снимок; головы одновременно движутся, здоровье уменьшается на 1; еда восстанавливает 100 и добавляет один сегмент. 3. После еды минимум одна еда восполняется; затем с вероятностью 15% появляется ещё одна в свободной клетке. Генератор определяется сидом. 4. Затем одновременно погибают вышедшие за поле, со здоровьем ≤0 или головой в любом теле, кроме голов. Тела погибающих тоже препятствия этого хода. 5. При встрече голов короткая погибает; равные погибают вместе. Длины сравниваются после еды. 6. Освободившийся хвост проходим. Хвост остаётся в ход поедания; на следующем без еды сдвигается, повторного роста нет. 7. Одна оставшаяся побеждает; при гибели всех — ничья последних живых. На лимите (обычно 500) выигрывают самые длинные выжившие; равенство — ничья. `royale`: каждые 25 ходов появляется опасная рамка; со следующего хода её клетки отнимают ещё 14 здоровья после еды. `constrictor`: еды и голода нет, рост каждый ход. ## Лимиты и ошибки По умолчанию: 100 мс на вызов, 32 МиБ изолята, 32 КиБ лога за матч. `console.log` разрешён; свой лог и ошибки доступны владельцу после матча. `require`, `process`, `fetch`, файлы и сеть недоступны. `Math.random()` детерминирован внутри матча. Исключение, таймаут или неверный ответ → прежнее направление, сначала `up`; ошибка записывается. Верхние переменные сохраняются между ходами, сбрасываются между матчами; аварийное превышение памяти может сбросить их раньше с записью в лог. Исходный `state` менять бессмысленно: сервер получает только направление. ## Рабочий пример Осторожно избегает занятых сейчас клеток и выбирает ближайшую еду; чужие будущие ходы неизвестны. ```js function move(state) { const dirs = { up:[0,-1], right:[1,0], down:[0,1], left:[-1,0] }; const { board, you, snakes } = state; const head = you.body[0]; const occupied = new Set(); for (const snake of snakes) for (const p of snake.body) occupied.add(`${p.x},${p.y}`); const moves = Object.entries(dirs).map(([name, [dx,dy]]) => { const x = head.x + dx, y = head.y + dy; const safe = x >= 0 && y >= 0 && x < board.width && y < board.height && !occupied.has(`${x},${y}`); const distance = board.food.reduce((best, f) => Math.min(best, Math.abs(f.x-x) + Math.abs(f.y-y)), board.width + board.height); return { name, safe, distance }; }); moves.sort((a,b) => b.safe - a.safe || a.distance - b.distance); return moves[0].name; } ```