Ускоряем Game of Life.
Планер (Glider) |
- Если у клетки ровно три живых соседа, то в ней "зарождается" жизнь;
- Если у клетки есть два или три соседа, и она жива, то она продолжает жить, иначе она "погибает" - от "одиночества" или от "перенаселения".
На rosettacode.org можно найти десятки реализаций. Но ни одной на Objective-C. Постараемся восполнить этот пробел.
'Преждевременная оптимизация - корень всех зол' (с) Дональд Кнут
Не будем спорить с маэстро и сделаем простейшую реализацию алгоритма: двойной массив, в котором будут храниться NSNumber - если клетка жива или NSNull - если нет заполним случайными числами:Инициализируем "вселенную" игры Жизнь. |
Быстрый способ сделать deep copy массива |
Функция neighborsCount считает количество живых соседей. Запускаем с полем в 10000 клеток и получаем среднее время выполнения около 0,039 с, а это 25 кадров в секунду (FPS), и это без учета времени на отрисовку. (Да, даже при такой скорости пользователь ничего не увидит, но и 10000 -это не много.)
Игра жизнь |
Первое-же что приходит в голову - создать этот массив один раз и просто менять из местами, в конце каждой итерации. Так реализованы большинство алгоритмов на RosettaCode.
Реализуем, запускаем, меряем: 0.024 секунды (1.6 кратное ускорение / 42 FPS). Уже не плохо, но ведь можно еще?
Если внимательно посмотреть, то видно, что для вычисления столбца совершенно не нужно держать в памяти все старые значения. Вполне достаточно только знать старые значения предыдущего и текущего столбца (следующий столбец, который также необходим в расчетах еще не был изменен, поэтому можно его использовать напрямую):
Игра "Жизнь" (Conway's Game of Life) |
Комментарии
Отправить комментарий