суббота, 26 мая 2012 г.

Жизнь - Игра (Conway's Game of Life)


Игра́ «Жизнь» (англ. Conway's Game of Life) — клеточный автомат, придуманный английским математиком Джоном Конвеем в 1970 году.

Пост "вдогонку" Перестаньте писать классы


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


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

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

Исходники можно скачать тут: GameOfLife.zip

Несколько интересных комментариев по коду:

- Почему реализация калькулятора в виде GetLeftTop, GetTop...
Потому что это проще, чем другие алгоритмы. Задача сразу сведена к двумерной плоскости и обсчет соседних точек в таком виде _ОЧЕНЬ_ читабелен, понятен и не требует дополнительных знаний. Это очень важно в командой работе и совместном владении кодом (даже если кроме меня больше никого нет, то Я сейчас и Я год назад - это два очень разных человека).
"Неэффективно" и аналогичные претензии к производительности: предполагается графика, а по сравнению с графикой несколько сотен обращений в массивы по индексам - это мелочь. Решать надо явные проблемы, а на данном этапе производительность - это гипотетическая проблема. я буду ей заниматься когда она обретет 100%ую вероятность свершившегося события.

- Откуда вообще калькулятор? Почему сделан отдельно от основной конструкции?
Калькулятор - это логика вычислений. Логика - это тесты. А тесты должны быть минимальны.
Поэтому ни в коем случае нельзя тестировать логику обсчета крайних значений матрицы поля на значениях "живая точка/мертвая точка": в такой тест вовлекается логика вычисления "живой/мертвый", которую я хочу тестировать отдельно. С помощью калькулятора я не только "хочу", но и "могу".
Кроме того, очевидно что логика такого обсчета - вещь заменяемая и ее замена не должна вызывать изменений в основной конструкции. Поэтому этот алгоритм должен быть вынесен в отдельную конструкцию. Пока что обе конструкции - это статические функции, но я не знаю насколько долго все так и останется.

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

=======================
И несколько комментариев по выбору языка/алгоритма/исходной информации:

- Почему C# /NUnit
"Знакомый молоток". Вся задача направлена на демонстрацию процесса решения задачи, нет смысла вставлять палки в колеса в виде java или функциональных языков.

- "Гугл - найдется все"
Решение неинтересно в свете того что я хочу видеть процесс работы над задачей от самого начала.
Понятно, что короткое гугление вернет десяток вариантов решения задачи на C# да еще и с графической реализацией.

- Производительность
Это вообще очень специфичная область работы со специфичными требованиями к соискателям. Эта специфика сразу акцентируется и в описании вакансии, и в описании задачи. В моем гипотетическом случае ничего такого нет и оптимизация плучит внимание "по факту проблем".