Anatoly Vorobey (avva) wrote,
Anatoly Vorobey
avva

Category:

о шаблонах в программировании

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

Попробую объяснить на примере кода, который недавно писал - HTML5-версии игры Jelly No Puzzle.

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

Кроме того, есть описание карты каждого уровня, начальной позиции. Оно сделано простым и наглядным - содержимое карты описывается построчно символами, пробел сооветствует пустой клетке, x - стенке, r/g/b - цветным клеткам red/green/blue соответственно. Например:
 [ "xxxxxxxxxxxxxx",
    "x            x",
    "x       r    x",
    "x       b    x",
    "x       x    x",
    "x b r        x",
    "x b r      b x",
    "xxx x      xxx",
    "xxxxx xxxxxxxx",
    "xxxxxxxxxxxxxx", ],

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

Но теперь программист доходит до более продвинутых уровней, в которых в игре появляются черные клетки. У них есть несколько особенностей, которые необходимо учесть при написании их поддержки. Это не просто еще один цвет. На карте их легко изобразить: ну, буква b у нас уже занята, так используем букву B. Но поведение у них другое.

Во-первых, черные блоки, если они соприкасаются друг с другом, не сливаются, как другие цвета. Что ж, думает программист, я добавлю в функцию doOneMerge(), главную рабочую лошадку соединения блоков, исключение: если клетки черные, не соединять.

Но тогда возникает проблема с начальной картой: в ней есть целые блоки черных клеток, которые формируются к началу игры уже готовыми. До сих их формировал вызов checkForMerges() в начале уровня, но черные клетки он теперь соединять откажется. Придется, видимо, делать исключение и тут. Пусть функция checkForMerges() пример дополнительный аргумент - если он true, то будет соединять черные, если false, то не будет. В начале уровня мы вызовем с true, а в течение игры после каждого движения - с false.

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



Есть уровни, в которых черные блоки с самого начала стоят рядом, и при этом не соединены. Это означает, что checkForMerges() в начале уровня сработает неправильно и соединит их все.

Что же делать? Кажется, нет иного выхода, как указывать на карте, какие черные клетки должны соединяться, а какие нет. Но это же очень неприятно. Придется добавлять кучу информации, когда описываешь уровень. Эта информация не влезет удобным образом в один символ, поэтому карта перестанет быть простой ASCII-картинкой, придется как-то усложнять. Можно, например, оставить место вокруг каждого символа, и ставить черточки-соединения там, где нужно:
      " x                         x",
      "                            ",
      " x b B B                   x",
      "   | |                      ",
      " x b B g-g           g     x",
      "   | |               |      ",
      " x b B B B           g B b x",
      "                            ",

В этом отрывке карты некоторые соседние 'B' соединены вместе, а некоторые нет. Но это будет довольно муторно выписывать, не говоря уж о том, что код, который считывает карту и строит из нее объекты, сильно усложнится.

Еще до того, однако, как программист пытается все это написать, ему приходит в голову одна идея. Это не гениальная идея, и надо специально отметить, что программист в этой истории (то есть я) не считает ее каким-то особенным достижением. С определенной точки зрения она буквально лежит на поверхности; но при этом верно и то, что есть много программистов, которые ее не заметят и будут продолжать примерно по указанному выше рецепту.

Идея следующая: если хотите, подумайте сами перед тем, как открытьCollapse )
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 78 comments
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →