Я заробляю на життя інфраструктурою. Розподілені системи, CI/CD pipelines, Terraform — робота, де один неправильний стан в одному місці тихо ламає все, що йде далі. І от одного вечора, без жодної причини, я вирішив написати шахи на React — і правило en passant разом із логікою мату виявилися найскладнішою задачею на управління станом за останні роки. Мене ніхто не просив. Ні клієнта, ні тікета, ні дедлайна. Просто хотілося зрозуміти, чи можу я змоделювати щось по-справжньому складне на TypeScript і не збожеволіти при цьому.

Шістдесят чотири клітинки. Тридцять дві фігури. Практично нескінченна кількість легальних станів партії. На папері звучить як проєкт на вихідні. Намалювати дошку — це справді пів дня: сітка, компоненти фігур, drag-обробники, готово. А от змусити гру реально дотримуватися правил — ось тут я почав сумніватися у своїх життєвих рішеннях.

Намалювати легко. Правила — ось де біль.

Ось чого вам не кажуть, коли ви сідаєте писати шахи на React: візуал — це тривіальні 10%. Решта 90% — це звід правил, який людство писало комітетом п'ятсот років, і в кожного правила є крайовий випадок, готовий вас принизити.

React узяв на себе дошку й відмальовування фігур. Усю важку роботу з ігровою логікою витягнув TypeScript, і без нього я навряд чи дійшов би до кінця. Коли ти валідуєш шахові ходи, runtime-помилка — це не просто баг, це нелегальний хід, якого ніхто не помітить, поки дошка вже не зламана. Типобезпечна генерація ходів ловила цілі класи помилок ще до того, як вони потрапляли на екран.

А потім пішли правила, які просто не вміщаються в голові:

  • Перевірка на шах після кожного ходу. Причому не лише твого — треба довести, що твій власний король не лишається під шахом після того, як хід відіграв. Тобто симулюєш хід, скануєш зону атаки кожної ворожої фігури й відкочуєш назад.
  • У рокіровки чотири умови, і всі мають виконуватися одночасно. Король не ходив. Тура не ходила. Між ними порожньо. І король не під шахом, не проходить через битне поле й не стає під шах. Я перечитав регламент FIDE двічі, щоб зробити це правильно.
  • Перетворення пішака — звучить просто, поки не треба звести докупи UI і перехід стану.

En passant виніс мені мозок

En passant — найзаплутаніше правило в шахах, і воно стає ще заплутанішим у той момент, коли до тебе доходить: твій код має пам'ятати, що було на минулому ході, щоб валідувати поточний. Пішак б'є поле, яке перестрибнув пішак суперника, — але тільки одразу, тільки на один хід. І раптом твій валідатор ходів перестає бути чистою функцією від поточної дошки. Йому потрібна історія. Одне це правило змусило мене повністю переосмислити, як я взагалі зберігаю стан партії.

А потім — мат. Українською «пат» і «мат» відрізняються однією буквою. У TypeScript це абсолютно різні дерева логіки. Мат: король під шахом і не має жодного легального ходу, щоб піти. Пат: король не під шахом, але легальних ходів немає взагалі — і це нічия, а не поразка. Переплутаєш — і код не викине помилку. Він просто мовчки оголосить не того переможця.

Три вечори я налагоджував сценарій, де король рокірувався просто через битне поле. Код не скаржився. Тести, що в мене були, цього не ловили. Я помітив, лише коли зіграв сам із собою повну партію й подумав: «стоп — так же не можна». Такий баг про себе не заявляє. Він просто сидить і тихо лишається неправильним.

Чого шахи навчили мене в інфраструктурі

Ось що мене здивувало. Цей дурнуватий шаховий проєкт навчив мене управління станом більше, ніж будь-який туторіал з Redux, що я проходив.

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

Моделювання пов'язаних правил, де одне неправильне значення ламає все далі по ланцюжку, напряму переноситься на логіку CI/CD, на Terraform-плани — на все, де коректність справді важлива. Шахова дошка просто зробила збої видимими так, як зламаний pipeline вміє рідко.

Збери те, що тебе лякає

Сенс був не в тому, щоб написати новий Chess.com. Сенс був у тому, щоб узяти щось складне й довести до кінця.

Якщо всі твої пет-проєкти легкі — ти лишаєшся в зоні комфорту. Візьми той, від якого трохи не по собі. Правило en passant, логіка мату, чотири умови рокіровки — нічого з цього не було в описі вакансії. І все це зробило мене кращим інженером. Збери те, що тебе трохи лякає. Так і ростеш.

Який пет-проєкт навчив тебе того, чого не навчив жоден курс?