Шахматы на чистом sed

:

В Линуксе и многих других системах существует утилита командной строки sed («сед») — это несложный редактор, которые преобразует текст, попадающий ему на вход при помощи несложных команд.

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

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

Вообще, это не первая игра на «седе», существует, например, Тетрис и Арканоид, но моя игра, похоже, обошла их по размеру и интеллекту.

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

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

Сложнее всего было с числами — как их вычитать, складывать, сравнивать, если в «седе» вообще нет арифметики? Пришлось изобрести свой формат хранения чисел, например, «111::11» означает 302 (число кодируется количеством единиц, десятки разделяются двоеточием), вся математика над этими числами делается при помощи набора регулярных выражений и переходов между ними.

Вот кусочек логики вычитания (вся функция занимает 59 строк):

Почти сразу я придумал объединять примитивы в какое-то подобие высокоуровневых команд и хранить стек таких команд рядом с данными (больше-то негде). Учился по дороге, если просматривать коммиты, можно увидеть какие-то находки, которые потом дальше расползаются по всему коду.

Должен сразу предупредить — игра ощутимо медленная, на моём «Макбуке Про» (2,9ГГц, Интел Ай7) ответный ход к «e2 e4» просчитывается 6,3 секунды. Впрочем, шахматы учат терпению, так что это не должно быть помехой.

# кстати, можете сравнить производительность своего компьютера с моим при помощи команды
printf "\ne2 e4\nq\n" | time sed -f chess.sed

Из ограничений, которые я себе поставил — не использовать расширения GNU sed и расширенные регулярные выражения.

Итак, что же вышло?

Запрограммированы позиционная оценка и оценка наличия фигур на доске (алгоритмы оценок взял из книги «Программирование шахмат и других логических игр» Корнилова Евгения Николаевича), перебор ходов (вложенности нет, перебирается только ближайший ход), обнаружение шаха и мата, дошедшая до конца доски пешка преобразуется в ферзя.

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

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