Skip to content

Repository files navigation

Игра, созданная с ИИ с одного промта. Тест 6: игра «ЗИМНИК» - ночное ралли по замёрзшей реке: подсказки штурмана извлекаются из геометрии трассы и никогда не врут, а норматив ставит ИИ-водитель, проехав трассу до вас. Python + pygame.

ЗИМНИК

Ночной тайм-триал по замёрзшей реке. Зимник — это дорога, которой летом не существует: её каждый год заново укатывают по льду, обставляют вешками со светоотражайкой и ездят, пока река держит. Здесь по такой дороге едете вы, один, ночью, на север. Штурман читает повороты вслух, фары выхватывают из темноты вешки и спины сугробов, под колёсами то укатанный снег, который держит, то чёрный лёд, который нет. Против вас никого — только норматив штурмана и призрак вашего же лучшего заезда, который стартует вместе с вами и не прощает ни одной ошибки.

скриншот

Это шестая моя игра на питоне: после шутера, рогалика, tower defense, мини-гольфа и подводного хоррора захотелось скорости. Но скорость сама по себе скучна — интересен контракт с ней: игра, где можно ехать быстрее, чем видишь, ровно потому, что кто-то рядом видит дальше тебя. Весь дизайн держится на голосе штурмана: он говорит — вы верите — вы живы. В темноте по-другому не ездят.

Ассетов по традиции ноль: машина, ели, избушка с тёплым окном, северное сияние — всё рисуется кодом при запуске. Звук двигателя, шорох заноса, ветер — три бесконечных петли, синтезированные математикой, в добавок к ним пара десятков разовых эффектов. Ни одной картинки, ни одного wav.

Как запустить

Нужен Python 3.8+ и pygame. На Windows ставить руками ничего не надо.

Windows, в один клик

  1. Скачайте папку с проектом и распакуйте куда угодно. Именно распакуйте, из архива запускать бесполезно.
  2. Дважды кликните PLAY.bat.
  3. Откроется консоль. Первый запуск идёт около полуминуты: скрипт найдёт Python (или поставит его через winget) и докачает pygame, примерно 10 МБ.
  4. Когда появится «Запускаю», откроется окно игры. Консоль не закрывайте.
  5. В меню нажмите Enter — и на старт.

Можно и без bat-файла: правый клик по run.ps1 → «Выполнить с помощью PowerShell». Копировать текст скрипта в консоль не надо — при копипасте он не знает, где лежит; от этого он защищён, но всё равно не надо.

Linux и macOS

python3 -m pip install -r requirements.txt
python3 main.py

Хотите конкретную трассу — передайте её код: python3 main.py 8F3KQ.

Если что-то пошло не так — консоль моргнула и закрылась → запустите run.ps1 правой кнопкой, текст ошибки останется на экране; «выполнение сценариев отключено» → запускайте через PLAY.bat; «python не является внутренней или внешней командой» → переставьте Python с галочкой «Add Python to PATH».

Управление

W / стрелка вверх    газ
S / стрелка вниз     тормоз, а из остановки — задний ход
A, D / стрелки       руль
ПРОБЕЛ               ручник: срывает зад, вход в шпильку
T                    вытащить машину из сугроба на дорогу
R                    рестарт заезда      N — новая трасса
H                    памятка штурмана    ESC — пауза

Подсказки читаются как в ралли: «правый 2» — правый поворот крутизны два, единица почти разворот, пятёрка едва изгиб. «Длинный» — дуга затяжная, «сразу» — следующий поворот приклеен к этому, «лёд!» — впереди большая проплешина чёрного льда. Цифра в углу растёт с шириной: подсказка прилетает загодя, расстояние расчитано от вашей скорости — на 150 км/ч штурман говорит раньше, чем на 60.

Горячие клавиши по физическим клавишам, так что работают в любой раскладке.

Как оно устроено

Трасса — предложение из ралли-ходов. Генератор не рисует случайную кривую, а составляет стейдж из слов: прямая, дуга радиуса R, связка, шпилька. Дуги начинаются по касательной к текущему курсу, поэтому линия гладкая по построению, а радиусы берутся прямо из категорий будущих подсказок — какую трассу генератор написал, такую штурман и прочитает. Два инварианта проверяются тестом на пяти сидах: ни один поворот не круче минимального радиуса и река нигде не пересекает саму себя (плохой бросок костей просто перегенерируется со следующего под-сида).

Штурман не врёт. Подсказки не придуманы дизайнером — они извлечены из геометрии: кривизна считается по трём точкам, сегментируется, категория берётся из радиуса, «длинный» из длины дуги, «сразу» из зазора между поворотами. Тест перебирает каждый поворот каждой трассы и сверяет слово «правый»/«левый» со знаком кривизны в этом месте. Услышали — верьте.

Норматив — не выдумка, а протокол заезда. Перед вашим стартом трасса отдаётся ИИ-водителю: чистый pure pursuit по осевой плюс скоростной бюджет — для каждой точки впереди из радиуса выводится предельная скорость, тормозная кривая подтягивает её к текущему моменту. Он едет ту же физику тем же шагом 1/120, и его время — это par. Побьёте — золото. То есть каждая трасса доказуемо проезжаема: её уже проехали до вас.

Призрак. Лучший заезд пишется в JSON на 20 Гц и в следующий раз едет рядом полупрозрачным. В первый раз вместо него едет сам штурман — есть у кого поучиться траектории. Дельта в метрах живёт под таймером: зелёная — вы впереди своей тени, красная — темп потерян в течении заезда.

Физика. Скорость раскладывается на продольную и боковую относительно корпуса. Продольная получает газ, тормоз и сопротивление; боковая только затухает — и скорость этого затухания и есть всё дорожное покрытие: укатанный снег съедает занос быстро, чёрный лёд почти не съедает, ручник не даёт съедать нарочно. Сугроб — мягкая стена: хватает, толкает обратно, на скорости бьёт. Случайности в физике нет вовсе — призрак и норматив поэтому честны до сантиметра.

Ночь. Мир рисуется как днём, потом умножается на карту света: бледная луна везде, тёплый конус фар впереди, красное дыхание габаритов сзади. Вешки отвечают фарам по-настоящему: искра ретрорефлектора загорается только когда конус до неё достаёт. Сверху всем этим дышит сияние.

Записи. JSON и только JSON — никакого pickle, файл сохранения не должен уметь выполнять код. Рекорды и призраки лежат по кодам трасс: код вида 8F3KQ можно отправить другу, у него будет та же река.

Файлы:

main.py      окно, состояния, ввод по сканкодам
settings.py  весь баланс и палитра числами
track.py     генератор ходов, лёд, вешки, подсказки
physics.py   дрифт-модель и сугробы
ai_driver.py pure pursuit + скоростной бюджет = норматив
engine.py    заезд: отсчёт, время, подсказки, призрак, медали
graphics.py  машина, ели, сияние, приборка — всё кодом
renderer.py  карта света, кокпит, экраны
sounds.py    синтезатор: три петли и разовые
savegame.py  JSON-рекорды с призраками
tests/       headless-тест

Тест проверяет 132 вещи: оба инварианта генератора на пяти сидах, честность каждого «правый/левый» на всех поворотах трассы, разгон, предел скорости, торможение с переходом в задний ход, разницу сцепления снега и льда с точностью до констант, ручник, сугроб с ударом и с гарантией «в лес не уедешь», детерминизм физики, что ИИ-водитель финиширует все пять трасс и его время воспроизводимо, отсчёт, порядок подсказок, спасение из сугроба, «РАЗВОРОТ», медали, перезапись рекорда только в лучшую сторону, битый файл рекордов и все экраны:

SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy python tests/smoke_test.py

Он же ставит кадр для скриншота выше.

Чего пока нет

Метели — сейчас снег идёт для настроения, а хочется степеней бедствия, когда фары упираются в белую стену и остаётся один голос штурмана. Геймпада и руля — просятся сюда очевидно. Соперников в лоб на узком льду — вот где был бы настоящий ужас, почище всякой подводной твари.

Мой рекорд на трассе 00007 — на четыре с половиной секунды быстрее норматива. Сколько сугробов стоил этот заезд, я не скажу, а призрак знает, но молчит.

Лицензия

MIT. Берите, ломайте, переделывайте. Папка проекта называется zimnik.

RustamChu, 2026

About

Создать игру через промт ИИ из 100 символов 6 тест

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages