@Pudjak

Как реализовать завершение игры «Жизнь» на Си?

Одно из условий остановки игры, если поле зацикливается.
Но как это реализовать? Знаю способ, с запуском "скрытой" игры, которая будет течь в 2 раза быстрее, и сравнивать поле этой игры с полем оригинальной каждый ход. Затем на каком то моменте поля совпадут и с этого момента запустить сравнение по ходам со стартовым первоначальным полем. Когда совпадут, получается зациклилось.
Но можно ли как-то попроще это реализовать?...

И ещё вопрос. Игра идёт в бесконечном цикле через sleep-задержку. Как можно реализовать изменение переменной в sleep, так сказать в реальном времени? Ну то есть допустим игра идёт, стоит sleep(a), a=100(милисекунд). По нажатию плюсика, например, к переменной a прибавляем ещё 100 милисекунд. Без conio.h и getch (так как Линукс)
  • Вопрос задан
  • 244 просмотра
Пригласить эксперта
Ответы на вопрос 2
mayton2019
@mayton2019
Bigdata Engineer
Отвечу на первую часть вопроса
Одно из условий остановки игры, если поле зацикливается.
Но как это реализовать? Знаю способ, с запуском "скрытой" игры, которая будет течь в 2 раза быстрее, и сравнивать поле этой игры с полем оригинальной каждый ход. Затем на каком то моменте поля совпадут и с этого момента запустить сравнение по ходам со стартовым первоначальным полем. Когда совпадут, получается зациклилось.
Но можно ли как-то попроще это реализовать?...


Я не программировал Convay-s Life т.к. было не особо интересно. Но я наблюдал работу приложения Golly. Там можно было проводить сутки напролет в экспериментах, задавая различные конфигурации клеток и вот к чему я пришел.

Невозможно докзать завершение игры просто так. Поле, даже небольшого размера может состоять из осцилляторов или ружей и пожирателей которые имеют разные периоды и могут сейчас не взаимодействовать друг с другом но внезапно пересечся через 10 000 эпох. Поэтому чтобы доказать что имеет место устойчивый период надо физически воспроизвести все эпохи.

Короче клеточный автомат имеет свойства которые невыводимы из начальной конфигурации в общем случае.

В частных случаях например когда вы знаете что такое глайдер и куда он полетит - то пожалуй можно. Но таких случаев будет мало.

Нерешенные вопросы:
1) Поле бесконечное? Как быть с конечными ресурсами оперативной памяти?
2) Поле конечное? Уничтожаем клетки (глайдеры) которые вылетают за границу поля?
3) Поле завернутое в тор (бублик)? Будем ли считать линейные трансформации поля - эквивалентными к исходному?

Данные вопросы вобщем-то тоже влияют на проблему завершения жизни Конвея.

По поводу идеи автора с удвоением времени. Может не сработать если период повтора не будет кратен двойке.
По сути надо не сравнивать x и 2x эпоху. А записывать в базу данных все x - 1 эпох и проверять все-с-последней.
Но такая сверх-задача невыполнима например с растущим бесконечным полем.

Вторая часть вопроса не так интересна. Ее можно задать отдельным вопросом в habr.
Ответ написан
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Раз поле конечное, то цикл будет обязательно, но алгоритмически понять, что вот мы уже на нем - никак нельзя.

Можно запоминать предыдущие поля. Хотя бы в виде хешей для экономия памяти. Чтобы из-за коллизии не заврешаться раньше времени, можно считать несколько принципиально разных хешей (допустим, sha256 и какой-то полиномиальный хеш), и плюс брать "слепок" от поля (какие-то 256 разбросанных по полю клеток).

Или, если поле не большое, то можно вместе с хешом хранить все поле. Если где-то хеши совпали, то дальше нужнол сравнивать уже поля целиком поклеточно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы