[#1] Пишем игру Backjack (Очко). Лирика и план

Тут @NONLUCIFER поставил себе задачу написать игру BlackJack (в простонародии “Очко”). А я как раз оказался на больничном. Грех не воспользоваться таким стечением обстоятельств. Я ставлю целью помочь @NONLUCIFER а так же продемонстрировать публике свой мыслительный процесс при решении задачи. Этот процесс универсальный, точно так же я подхожу к решению рабочих задач программирования. Не все делати процесса будут описаны, не все решения будут верны с первого раза (как это обычно бывает на заданее подготовленных курсах), поэтому вовлекайтесь, будем обсуждать ваши непонятки или идеи.

О подходах и принципах

Когда мы пишем код, мы создаем “модель” явления (игры, описываем магазин или процесс оплаты билетов на концерт). Мы используем конструкции языка чтобы описать элементы явления (победа-проигрыш как true-false, карта как объект и колода карт как массив объектов). В программе описываем только часть явления, имеющую отношение к задаче. Иногда для моделирования явления достаточно использовать примитивное значение (имя пользователя - строка, победа-проигрыш - булевое значение, количество карт - булевое значение). А иногда нужно создавать классы чтобы описать явления, например класс Player может описывать данные игрока (как компьютера так и человека).

В отличии от ООП мира, где на каждый аспект создается объект, я ради простоты кода в этой задаче буду подбирать такие конструкции языка которые приведут по моему мнению к более простому коду. Строительные блоки из которых создается программа зависит от ваших возможностей: опыта, фреймверка или идеологии написания кода (функциональный стиль, ООП стиль, какой-получится-стиль).

Большое влияние на конечный код играет то как нам нужно отобразить состояние игры пользователю и как настроить взаимодействие пользователя с программой. Моя практика показывает что при дизайне кода программы нужно отталкиваться от конечного результата. Если начать писать код но не знать как будет выглядеть результат, то далеко не всегда созданная конструция “ляжет” на желаемое представление. Тут возникает дилемма: с одной стороны мы не модем сразу представить всю программу и ее нужно разрабатывать итерациями, с другой стороны принимаемые в моменте решения уменьшают пространство возможных решений на поздних итерациях. Диллема решается через стратегии набор которых будет варьироваться от опыта и вкуса пишущего а так же договоренностей в команде. Примеры. Стратегия модульности. Решения изолированы и взаимодействуют через строго ограниченные точки. Описание состояния как данных. Колода карт, рука игрока описываются данными языка программирования. Стратегия разделения доменной области (то что мы моделируем, намример игра) от способа отображения (то как мы отображем состояние игры пользователю). Например подход MVC (model-view-controller) как раз про отделение данных от отображения. Для еще одного примера глянем на реакт: он разделяет данные и способ их отображения, оставляя программисту решать задачу изменения данных (т.е. описания домена) отдельно от задачи отрисовки данных (описание шаблона).

План

  1. Продумываем все аспекты которые хотим реализовать в игре (раунды, общий счет, подсказки, итд). Изменение/добавление аспектов будет сложнее на более поздних этапах разработки.
  2. Рисуем скетч интерфейса который отобразит желаемые аспекты игры. Достаточно иметь общее представление об элементах и отображаемых пользователю данных.
  3. Смотря на аспекты игры и скетч, выписываем то каким образом они будут смоделированы в решении.
  4. Реализуем отдельные аспекты, стараясь делать их модульными (перемешивание колоды, ход пользователя, ход компьютера).

Ограничения: пишем на чистом js, пытаемся сделать код простым но не слишком простым.