«Тетрис» на Brainfuck ★

Ну разумеется я вчера не смог уснуть без того, чтобы не посмотреть что ещё мог бы написать ИИ на «Брейнфаке»! Попробовал написать «Тетрис», тем более что у меня были готовые идеи как это сделать. Правда для этого пришлось модифицировать интерпретатор. Свой собственным, разумеется, который я начал писать ещё в 2001-м году, надо бы про него рассказать тоже однажды.

Дело в том, что у «Брейнфака» нет рандомизации и ввод устроен очень просто — есть инструкцию чтения символа и всё. Правда сам язык не определяет подробности чтения символа, поэтому реализации отличаются. В основном авторы интерпретаторов делают буферизированный ввод, дожидаясь нажатия кнопки «Ввод». Правда тут тоже есть нюансы — где-то можно ввести строку, а где-то «Ввод» надо нажимать после введения каждого символа.

Чтобы приступить к «Тетрису» пришлось сделать две модификации.

Во-первых, ввести команду @, которая записывает случайное число в текущую ячейку («Брейнфак» всё сохраняет в ячейках, двигаясь по ней при помощи специальных команд). В таком расширении языка нет ничего необычного — когда он был на волне популярности, ему постоянно придумывали всякие расширения.

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

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

Чтобы каждый раз не вспоминать какие ключи нужны программе, я придумал способ как их указывать — если в начале программы на «Брейнфаке» стоит обычный шебанг, я беру параметры интерпретатора оттуда.

Скриншот игры BF TETRIS: цветные блоки заполняют поле, справа — управление (←/→ move, ↑ rotate, ↓ drop, q quit), следующий блок и счётчик линий (lines 4).

Как легко догадаться по скриншотам, нейросеть (я использовал «ГПТ-5.5») отлично справилась с задачей. Но что интересно, чтобы это сделать она реализовала ровно ту идею, про которую я писал в прошлый раз — написала генератор на ПХП, при помощи которого сгенерировала программу на «Брейнфаке». Немудрено — программа получилась монументальной — под сотню мегабайт в первой попытке.

Я даже сделал в своём интерпретаторе поддержку сжатия исходников. Наверное никому раньше не приходило в голову этим заниматься — как правило программы на «Брейнфаке» пишут люди и до таких размеров они их не доводят.

Трансляция такого огромного файла и применение оптимизаций занималось около 15—20 секунд на моём ноутбуке, так что пришлось применить ряд оптимизаций — немного переписать парсер интерпрератора, сделать кеширование и поработать над уменьшением размера кода «Тетриса».

«Тетрис» работает в консоли и, надеюсь, никому не надо объяснять, что для раскрашивания блоков и позиционирования тут широко применяются анси-коды, я их использую чуть ли не в каждой консольной программе, вряд ли кого-то это удивит.

Единственное о чём надо рассказать — как регулируется скорость игры. В «Брейнфаке» нет ничего, чтобы создавать паузы заданной длительности, но некоторые программы работают ощутимо долго. Хотя у меня и оптимизирующий интерпретатор, всё оптимизировать он не может. Поэтому мы с нейросетью просто «на глазок» подобрали код, который достаточно плохо оптимизируется и тормозит на моём ноутбуке ровно насколько, чтобы играть было комфортно.

Оставить комментарий

ИИ: Brainfuck

Три года назад я в шутку предлагал программистам переходить на «Брейнфак» — эзотерический язык программирования из восьми конструкций, который плохо давался нейросеткам. Что-то похожее на программу на этом языке они писали, но получался мусор.

Я пропустил момент, когда модели научились на нём писать. Буквально вчера догадался снова попробовать, оказалось — могут! Программу на скриншоте мне «Курсор» написал в режиме «Авто», где выбираются, в основном, слабые модели. Топовые справляются даже с такими заданиями как написать несложный эмулятор командной строки с несколькими основными командами и небольшой файловой системой!

Для человека это уже какой-то запредельный уровень. Если бы я решал эту задачу, я бы написал себе сначала какой-нибудь макроязык с трансляцией в «Брейнфак» и уже на нём написал то, что требуется.

Скриншот терминала с командой Brainfuck, генерирующей ASCII-арт из символов + и -, и подписью «Вот и всё ребята

Две вещи, с которыми модели ещё не справляются — это написание «квайна» (программы, которая выводит сама себя) и оптимизация программ на «Брейнфаке» по размеру. Даже топовые модели наотрез у меня отказываются такое писать. Даже после прямого приказа.

Интересно будет помучить этой задачкой новую модель «Антропика», которая должна появиться летом — я считаю их модели лучшими, хотя их последний «Опус» несколько разочаровал.

Добавлено позднее: справедливости ради насколько простую программу, как на картинке выше, нейросети и сейчас могут написать оптимальнее:

Скриншот терминала с командой Brainfuck, запущенной через PHP, и выводом «Вот и всё ребята» — юмористический пример использования esoteric-языка программирования.

10 комментариев

Семидесятипятилетнее вино

Папе в марте исполнилось 75 лет — юбилей и довольно значительная дата. Поэтому хотелось поздравить его как-то небанально. Они с мамой всегда в начале мая приезжают к нам в гости из Лениногорска, и мы с братишкой хотели по приезде чем-нибудь его удивить, но всю голову сломали.

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

Хорошо, что у нас есть интернет! Искомое нашлось на одном из сайтов, правда там ничего не было сказано про доставку, но после звонка и почти двухчасового обсуждения всех деталей по «Телеграму» вино было упаковано и в тот же день поехало в Казань.

Я сильно переживал как оно доедет — консультант в магазине сказал, что не все бутылки могут пережить транспортировку, поскольку в некоторых бывают трещины. Он выбрал без видимых трещин и тщательно упаковал, но я всё равно волновался.

Доехало всё шикарно, в целостности и сохранности. Сегодня подарок вручили, надеюсь и до Лениногорска он доберётся без эксцессов.

Открытая деревянная коробка с набором винных аксессуаров и бутылкой вина Barolo 1951 года на светлом деревянном полу.
Бутылка вина Mirafiore Barolo с этикеткой «Tenimenti di Barolo e Serralunga d’Alba», производитель Mirafiore Canelli (Италия), на деревянном фоне.
Бутылка шампанского с синей фольгой и этикеткой, на которой видна маркировка «МГ 030682», на фоне деревянной коробки с аксессуарами.

6 комментариев

Коммунистический массив

Я тут в мемах, которые кинули бывшие коллеги, увидел «коммунистическую сортировку» — она каждому присваивает среднее значение, и не смог пройти мимо. Написал «коммунистический массив»:

class CommunistArray extends \ArrayObject
{
    public function __construct(array $array = [])
    {
        parent::__construct(self::createCommunistArray($array));
    }

    public function offsetSet(mixed $key, mixed $value): void
    {
        parent::offsetSet($key, $value);
        $this->redistribute();
    }

    public function offsetUnset(mixed $key): void
    {
        $first = $this->getIterator()->key();

        if ($first !== null) {
            $this[$first] += $this[$key];
            parent::offsetUnset($key);
            $this->redistribute();
        }
    }

    private static function createCommunistArray(array $array): array
    {
        if ($array) {
            $avg = array_sum($array) / sizeof($array);
            return array_fill_keys(array_keys($array), $avg);
        }

        return [];
    }

    private function redistribute(): void
    {
        (void) $this->exchangeArray(self::createCommunistArray((array) $this));
    }
}

Он делает всех равными и перераспределяет блага автоматически:

$comrades = new CommunistArray([0b1, 0o0, 3e1, 0x45]);

print_r($comrades); # 25, 25, 25, 25

$comrades[2] = 4;
print_r($comrades); # 19.75, 19.75, 19.75, 19.75

unset($comrades[0]);
print_r($comrades); # 24.6875, 24.6875, 24.6875

8 комментариев

Книга с Некрасова

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

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

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

Мне достался первый томик «Химии жизни» 1923 года в отличном состоянии. Книжка редкая — тираж всего 3000 экземпляров, но вряд ли востребованная — думаю за сто с лишним лет её научная ценность упала ниже нуля.

Интересно, что её автор биохимик Владимир Сергеевич Садиков был в 1942-м году эвакуирован из Ленинграда к нам в Казань, где вскоре и скончался. Как знать, может эту книжку он привёз с собой.

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

Старинная книга с мраморным переплётом и чёрным корешком, на обложке — пустая этикетка, лежит на светло-сером фоне.
Титульный лист книги «Химия жизни», выпуск первый, «Принципы жизненного процесса», профессора В. С. Садикова, Петроград, 1923 г.

4 комментария

Книги: «Возвращение Синей Бороды»

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

Многие говорят, что он давно исписался, я, наверное, с этим тоже согласен, но почему-то всё равно не бросал его читать.

Не скажу, что мне каждый раз приходилось делать над собой усилие: некоторые его вещи давались мне легче, другие труднее, но ни через одну я не продирался так, как через текст его свежей книги «Возвращение Синей Бороды». Тут я окончательно завяз. Примерно на половине я сообразил, что мне совершенно не хочется её дочитывать.

Я очень не люблю бросать книги, возможно это какая-то моя обсессия, но эту постараюсь бросить. Вместе с писателем и его неудачным спектаклем.

5 комментариев

Есенин

Никогда не любил и не понимал стихи Есенина, мне всегда больше нравился Маяковский. Впрочем, кроме Маяковского меня вообще мало какие стихи привлекают — в этом смысле я однолюб. Впрочем, я давно догадывался, что дело в подаче. Наверное с тех пор, как услышал стихи Олеси Балтусовой в её собственном исполнении. Мы дружим больше 20 лет, но я до сих пор не воспринимаю её стихов в виде текста.

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

Только потом я узнал, что это стихи Есенина и попробовать послушать тоже самое в исполнении Безрукова. Мне совершенно не понравилось. В исполнении Легенары эти стихи звучат очень лирично, с каким-то надрывом, мне подходит, а Безруков читает, напротив, восторженно, как весенний щенок.

В общем, в восприятии стихов я очень нуждаюсь в помощи исполнителя.

Наверняка это очень примитивно — не уметь видеть стихотворную красоту самостоятельно, но что делать, пока не научился. Собственно, целенаправленного я для этого делал очень мало, нет сильной потребности, что ли…

Портрет молодого блондина в коричневом пиджаке на фоне осеннего пейзажа с рекой, городом и православным храмом с голубыми куполами.
Портрет Сергея Есенина нарисованный «Джи-Пи-Ти Имейдж 2»

18 комментариев

Мурчащий котик

У дочки в школе есть так называемая «проектная деятельность». Не особо понимаю, почему она есть в школе, а заниматься ей приходится дома, но да ладно — ещё больше я не понимаю, почему там не помогают ребёнку выбрать проект по силам.

Проект, который дочь выбрала — робокот, который должен ходить и мяукать. Насколько я понял, купить готового не вариант, надо сделать своего.

Наверное это вполне по силам девятилетнему ребёнку, который занимается робототехникой, но у дочки такого предмета в школе нет. И в тематический кружок она тоже не ходит. Так случилось, что я тоже роботов строить не умею.

У жены я не спросил, но подозреваю, что и она тоже — мы 19 лет вместе и я её ни разу не заставал за сборкой робота.

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

Белая 3D-модель лежащей кошки с видимыми слоями печати, на шее которой надет черный браслет с надписью «DIN» и оранжевыми полосками, на деревянном полу.

На принтере был срочно распечатан кот — я взял первую попавшуюся модель и увеличил её. Напечатанного кота я вскрыл снизу простым советским консервным ножом, а потом выдолбил изнутри при помощи отвёртки и узкогубцев.

Китайская хреновинка оказалась глуховатой, поэтому мурчание пришлось записывать с «Алисы», выведенной на максимальную громкость. По громкости получилось нормально, а по качеству — терпимо. Но когда я вынул хреновинку из корпуса и начал запихивать в кота по частям, оказалось, что криворукие сборщики паяли не припоем, а своими соплями — провода начали просто отламываться от места пайки.

Белая скульптура в виде лежащего животного с сетчатым узором на боку и чёрной наклейкой, лежащая на деревянном полу.

Пришлось расчехлять купленный когда-то паяльник. Паяльник при включении показал слово «CONFIG» и включаться отказался. Я подумал, что он, наверное, сломался и расстроился.

Чинить настолько сложные паяльники я умею примерно так же, как делать роботов, так что сделал то, что пришло в голову, — обновил на нём прошивку и перепривязал жало к станции. Это не помогло, но зато теперь в паяльнике у меня есть русский язык.

Выручила инструкция: пока читал, как обновить паяльник, увидел, что «CONFIG» означает всего-навсего, что ему не подходит блок питания, — он питается по ЮСБ, и я его воткнул в первый попавшийся блок, который нашёлся в ящике стола.

После «починки» я воспрял духом и работа пошла побыстрее. Быстро перепаял отвалившиеся провода (помогла привычка фотографировать всё, что я разбираю) и заодно вывел кнопку запуска мурчания коту на холку. Это место я накрыл картонной полоской, чтобы увеличить площадь нажатия.

Динамик вывел на пузико, где прореза́л отверстие и закрыл его пропитанной для жёсткости клеем кружевной тряпочкой от старой детской майки, после чего передал эстафету жене с дочкой — их задача обшить котика мехом.

10 комментариев

Задняя часть Афины

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

Сразу вспомнилось, как в советские годы мы из экономии не клеили обои за «стенкой» — мебельным гарнитуром в зале. Её всё равно невозможно было поставить куда-нибудь ещё, поэтому она всегда стояла на одном месте и смысла клеить за ней обои не было, в общем-то, никакого.

Каменная статуя лежащей фигуры с драпировкой, частично разрушенная, находится в археологическом раскопе среди грунтовых стен и камней.
Задняя сторона свеженайденной Афины; детализация увеличена сетью «Джи-Пи-Ти Имейдж 2»

6 комментариев

Кощей

Читал тут русские берестяные грамоты и наткнулся на одну, где упоминается имя или прозвище «Кощей». Таких грамот нашлось три штуки, и, наверное, есть ещё.

Я как-то вне контекста сказок это слово не встречал, даже залез в «Википедию». Раньше как-то не приходило в голову почитать что-нибудь про сказочного Кощея. Узнал много нового. У него, оказывается, ещё и отчество было — Трипетович, да ещё и возлюбленная, которую в одной из былин украл у него Иван Годинович. Впрочем, не исключено, что тут склеились два разных персонажа.

Интересно всё же — сказочный Кощей получил имя по существовавшему когда-то имени или всё-таки сначала так назвали персонажа, а уже потом его имя стало прозвищем? Теперь уж и не узнать.

Фрагмент берестяной грамоты с древнерусским текстом, написанным чернилами; верхняя строка выделена жёлтым маркером, видны повреждения и дыра в центре.
«Челобитье от Кощея и от испольщиков. У кого есть кони, и те плохи, а у иных [вовсе] нет. Чем, господин, пожалуешь крестьян? А рожь, господин, велишь мне молотить — как укажешь?» (или: «так это, как укажешь»)

4 комментария

Краеведение: что под штукатуркой?

Вот непонятно, как это вообще работает. Я уже 15 лет работаю в «Айти-парке», с того самого дня, как переехал из Москвы обратно в Казань. Все 15 лет я хожу мимо стены, что на фотографии, пусть не каждый день, но достаточно часто.

Это историческое здание, а я, как знают постоянные читатели моих заметок, очень люблю такие здания осматривать и подмечать на них различные детали.

Что там было в тот год, когда я переехал, неизвестно. Годом позже, в 2012 году, на нечёткой фотографии «Яндекс.Карт» видна вмятина, как будто Халк легонько ткнул мизинцем. Вряд ли она заинтересовала бы меня и сейчас. Но в 2016 году на «Гугл.Картах» уже едва-едва виден лёгкий контур. Качество съёмки там не очень, возможно, в жизни он был заметнее.

Из года в год он проступал всё сильнее, и лет шесть назад, судя по фото, его было сложно не заметить. Но я почему-то не замечал, пока в сентябре прошлого года, наконец, не обратил внимания.

Поспрашивал знакомых краеведов, но никто не знает, что там. Я думаю, что там какая-то табличка: на здании рядом одна есть, 18 века, если мне не изменяет память.

Как это проверить, ума не приложу, разве что гипотетическая табличка окажется металлической. Надо бы разыскать свой пинпоинтер, он лежит где-то дома и проверить. А то полгода хожу мимо и каждый раз гадаю — что же за контур проступает?

Белая стена здания с трещинами и следом от удалённой таблички, у основания — серая облицовка и трава; справа видна дорога, ворота и здание с голубой крышей.

14 комментариев

Мир в бутылке: графика

Хочу немного остановиться на том, откуда взялась графика моего проекта, который я условно пока называю «Мир в бутылке», и какие нейросети я использовал для рисования.

Первых персонажей для будущего перформанса я нарисовал в «ЧатеГПТ 5.4». На вход дал несложный промпт, что-то типа такого:

нарисуй 10 характерных персонажей-человечков в пиксельном стиле маленького размера. референс в картинке

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

Рядом стоят пиксельные персонажи: рыцарь, волшебник, орк, лучник, робот, огненная ведьма, ниндзя, девушка с розовыми волосами, викинг и зелёный инопланетянин на чёрном фоне.

Собственно, этот спрайт плюс небольшое текстовое техническое задание, где я поверхностно описал, какими возможностями будут обладать будущие персонажи, я и подал на вход «Опусу 4.7».

Картинки я на спрайты не резал: нейросеть справилась с этим самостоятельно — вырезала, сделала им прозрачный фон и даже добавила простенькую анимацию ходьбы. Кстати, позже я обнаружил, что у меня в коде оказалось два варианта спрайтов — для ходьбы влево и вправо, — и попросил оставить только один вариант, а второй делать поворотом спрайта.

Травку, камешки, насекомых и игровые предметы мне рисовал уже «Опус». С мелкими предметами он справился хорошо, а с теми, что покрупнее, — хуже. В итоге котёл, костёр, сундук и так далее я снова попросил нарисовать «ЧатГПТ». На мой взгляд, он их нарисовал слишком детализированно:

Пиксельные иконки: кувшин, закрытый и открытый сундук, надгробие, костёр, котёл, мишень, чучело и пень на белом фоне.

Поскольку их надо было сделать сильно меньше, «Опус» перерисовал новую версию «по мотивам». В итоге качество меня устроило. Текущий вариант лучше, чем было раньше, но выглядит менее натурально, чем то, что нарисовал «ЧатГПТ». В силу того, что я придерживаюсь ретро-стиля, как будто бы нужный баланс достигнут.

Гидру я рисовал в «Нанобанане 2», приложив как референс картинки персонажей. Текущий результат получился примерно с четвёртой или пятой попытки и, если честно, не кажется мне идеальным, но мне больше хотелось проектировать мир, а не возиться с графикой настолько долго.

Претензия всё та же: по сравнению с персонажами гидра чересчур детализирована.

Пиксельные спрайты гидры с тремя и пятью головами, а также двух вариантов пещеры гидры: многоуровневой с одним входом и одноуровневой с тремя входами.

Что делать дальше я пока не решил. Либо доделаю этот мир — там осталась ещё одна нереализованная задумка, либо перейду на другую платформу (кое-что заказал на «Авито») и спроектирую что-то там (идеи, опять же, есть).

4 комментария

Кафе: второй зал

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

Поэтому всё немного в недоделанном состоянии, но народу как будто в кафе стало намного больше, пришлось даже расширять цех, так что, видимо, управляющая всё делает правильно.

На красном столе у окна: тарелка с бургерами в бумаге, розовая кружка и фарфоровая фигурка лебедя с малиной.

5 комментариев

Инженерное меню в мониторе Kuycon

Искал, как обновить прошивку своего нового монитора «Куйкон», и случайно нашёл инженерное меню. Нужно зажать клавишу «≡» на пульте до его появления.

Большинство опций понятны — настройка соотношения цветов при разных точках белого, уровень подсветки, отключение показа логотипа. Термин «Burn-In» я погуглил — это защита от выгорания.

Единственное, что ставит в тупик, — непонятная опция «DefLAN», которая, судя по всему, как-то связана с сетью, но при этом выбирается язык. Я поставил русский, но ничего визуально не изменилось.

Добавлено: один из читателей расшифровал — «Default Language» («язык по умолчанию»).

Синий экран настроек панели AUO M315WAN01: цветовые профили (9300–User), подсветка (MAX 152, MID 90, MIN 52), язык RUSSIAN, Burn-In ON, LOGO OFF, время работы 97H 50M.

2 комментария

Я в Кибердянске

А я тут, оказывается, кое-что забыл показать, в телеграмном канале опубликовал, а тут — нет. Вышел очередной комикс «Кибердянска», но с моим участием:

Комикс «Кибердянск»: хакеры чинят бабок на скамейке как баги в игре, но те оказываются реальными людьми, а не NPC.

Оставить комментарий

Мир в бутылке: поведение ведьмы

Вчерашняя идея прикрутить небольшую нейросетку, которая будет выстраивать поведение ведьмы, в общем-то, провалилась. Ушло 4,5 часа, чтобы обучить простенькую трёхслойку на нескольких тысячах игровых ситуаций, но она показала прирост по сравнению с обычным поведением на основе уже существующих правил на уровне шума.

Обидно, досадно, но ладно. Там было пространство для манёвра, но слишком медленно тренируется. Чтобы ускорить, нужно переписывать весь игровой мир на какой-нибудь фреймворк для ускорения через видеокарту, а это долго даже с нейросетками. Да и качество такого переноса потом не проверишь.

Решил пойти другим путём — попробовать «дерево решений», оно легче в обучении и его проще потом разбирать. Это помогло — эксперименты пошли бойчее, и я довольно быстро увеличил метрику с 1,715601 до 1,933353, что довольно много на самом деле. Метрика там по простенькой формуле учитывает результативность кампании — удалось ли убить гидру и сколько народу выжило.

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

Дерево решений Witch Policy Tree с узлами условий и цветными листьями действий (stay, deposit, revive_danger). Пиксельный маг в углу.
Визуализированное дерево решений эксперимента №2 (в данный моменту у меня кончается эксперимент №4)

Оставить комментарий

ИИ: Claude Mythos и поиск уязвимостей

Я давно предсказывал, а месяц назад даже об этом написал, что нейросети в этом году побьют все прежние рекорды по поиску уязвимостей. Прогноз уже начинает сбываться: компания «Антропик» не стала публиковать свою модель следующего поколения «Мифос», потому что она исключительно хороша в поиске уязвимостей.

Вроде обещают показать летом, когда все крупные поставщики софта закроют выявленные этой моделью уязвимости.

Я сразу заподозрил в этом заявлении изрядную долю маркетинга и оказался прав: как показало исследование, изрядную часть уязвимостей, которые раскрыли, нашли также и модели предыдущего поколения. Тем не менее я охотно верю, что «Мифос» сильнее «Опуса», просто не думаю, что настолько, насколько это хотят показать.

В конце концов, это хороший бизнес-план — создать миф вокруг новой модели, чтобы все попросились в закрытое и, наверняка, платное бета-тестирование.

Оставить комментарий

Мир в бутылке: гидра и ведьма

Довольно интересно получается вместе с дочкой проектировать игровой мир через нейросети. Ей не хватает усидчивости, чтобы довести дело до конца, но пока я его создавал, она иногда прибегала и вкидывала какие-то идеи. Так у нас появилась лошадка, а позже — гидра. Вообще дочка хотела дракона, но мне почему-то очень хотелось гидру, в ходе переговоров сошлись на том, что гидра визуально — почти дракон.

Пиксельная сцена: персонажи на зелёном поле с тропой, сундуком, пещерой, надписью «HELP!» и водяным знаком Bolkleis.dev.
Мир в текущем его виде: появился «босс» — гидра

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

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

Не бог весть какая стратегия, но я до сих пор с ней бьюсь. Пришлось выделить поведенческий код в отдельный модуль и проводить симуляции на тысячах прогонов, чтобы отладить логику. Так удалось отладить поведение лекаря (я в разговоре с ИИ называю её «девочка»), а вот ведьма пока далека от идеала.

Скриншот терминала с результатами симуляции: успех BASELINE 36%, FIX:girl-range only 39,9%, FIX:girl-range+route 99,9%; ниже — анализ ошибок и комментарий про ведьму и гидру.
Процесс общения с «Курсором» по поводу изолированной симуляции поведения персонажей

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

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

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

Я как-то не думал, что это займёт столько времени, но планирую экспериментировать до успеха.

Оставить комментарий

Мир в бутылке: а где лошадка?

Пока программировал свой «Мир в бутылке», пришли жена и дочка и, как фанатки лошадей, потребовали ввести в игру лошадку. Я согласился с условием, что дочка нарисует прототип и хоть немного продумает механику — как именно лошадка будет себя вести.

В итоге, дочка по-быстрому нарисовала как она видит лошадь, а я двумя проходами вместе с нейросеткой довёл её до пиксельного совершенства.

Рисунок лошади в стиле Minecraft с пиксельной текстурой и синим седлом, рядом два уменьшенных пиксельных изображения той же лошади на чёрном фоне.

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

Оставить комментарий

Мир в бутылке: сжатие в картинку

Вчера я писал, что код и вероятности перехода в цепях Маркова упакованы в картинку, но не объяснил что это и для чего сделано.

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

Это позволяет, во-первых, отдавать сжатый ответ даже на тех серверах, где сжатие выключено, во-вторых, использовать иногда более продвинутые методы сжатия, которые есть в современных форматах изображений, но могут отсутствовать при сжатии данных сервером через HTTP.

Скриншот консоли: вывод сборки проекта bolklet, показывающий размеры файлов (JS, модель, спрайты), выбор формата PNG/RGB как оптимального и итоговое сжатие изображения на 89%.
Процесс сжатия в картинку — выбираем формат, который сжимает эффективнее

Сжатие при этом реализовывать в ДжаваСкрипте не нужно — браузер за нас распаковывается картинку, а мы её просто попиксельно читаем.

Поскольку веса для цепей Маркова занимают аж 3,5 мегабайта в джейсоне, я воспользовался этой идеей, чтобы поэффективнее его ужать, бинарно сериализуя его в картинку, а потом затянул туда и остальное — основной код и спрайты.

Оставить комментарий