Неизменный игровой объект, основной вопрос о функциональном программировании

Я нахожусь в процессе попытки 'узнать больше', и 'извлекают уроки из' функционального программирования и идеи неизменности, являющейся хорошим для параллелизма, и т.д.

Как осуществление мысли я вообразил простую игру, куда символ текста Mario-эсквайра может работать и перейти вокруг с врагами, которые стреляют в него...

Затем я пытался вообразить это записанное функциональное использование неизменных объектов.

Это подняло некоторые вопросы, которые озадачили меня (быть Императивом программист OO).

1) Если мой маленький парень в праве перемещений положения x10, y100, 1 единица делает меня просто, повторно инстанцирует его использующий его старые значения с +1 к его x позиции (например, x11, y100)?

2) (Если мое первое предположение корректно), Если мой входной поток перемещает мало права парня, 1 единица и мой вражеский поток AI стреляют в маленького парня и твердость enemy-ai-thread перед входным потоком затем, мой парень освободит здоровье, то после входного разрешения потока, получите его назад и право перемещения...

Это означает, что я не могу fire-&-forget мои потоки даже с неизменностью? Я должен отослать свои потоки, чтобы сделать их вещь, затем новую () маленький парень синхронно, когда у меня есть результаты обеих потоковых операций? или есть ли простое 'функциональное' решение?

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

3) (Снова, если мое первое предположение корректно), Делает постоянно инстанцирующие новые экземпляры объекта (например, парень Mario) имеют ужасные издержки, которые делают его очень серьезным/важным проектным решением?

РЕДАКТИРОВАНИЕ Извините за это дополнительное редактирование, я не был тем, о чем хорошая практика идет здесь, развивают вопросы...

4) Если неизменность - что-то, что я должен бороться за и даже перейти, хотя обручи инстанцирования новых версий объектов, которые изменились... И Если я инстанцирую своего парня каждый раз, когда он перемещается (только с другим положением) разве, у меня нет точно тех же проблем, как я был бы, если он был изменяем? в так же, что что-то, что сослалось на него однажды вовремя, на самом деле смотрит на старые значения?.. Чем больше я рою в это, тем вращение большего количества моей головы как генерация новых версий того же самого с отличающимися значениями просто походит на переменчивость через взлом.: ¬?

Я предполагаю, что мой вопрос: Как это должно работать? и как это выгодно законченный просто видоизменение его положения?

for(ever)//simplified game-loop update or "tick" method
{
   if(Keyboard.IsDown(Key.Right)
      guy = new Guy(guy){location = new Point(guy.Location.x +1, guy.Location.y)};
}

Также сбивающий с толку: вышеупомянутый код означает, что парень изменяем! (даже если его свойства не),

4.5) Это вообще возможно с полностью неизменным парнем?

Спасибо,

J.

8
задан jdoig 21 July 2010 в 07:03
поделиться

4 ответа

1) Если мой малыш на позиции x10, y100 перемещается вправо на 1 единицу, я просто повторно создать его, используя его старый значения с +1 к его позиции x (например, x11, y100)?

Ну, не обязательно. Вы можете создать экземпляр этого парня один раз и изменить его положение во время игры. Вы можете смоделировать это с помощью агентов. Парень - агент, ИИ - тоже, поток рендеринга - тоже пользователь.

Когда ИИ стреляет в парня, он отправляет ему сообщение, когда пользователь нажимает клавишу со стрелкой, отправляет другое сообщение и так далее.

 let guyAgent (guy, position, health) =
     let messages = receiveMessages()
     let (newPosition, newHealth) = process(messages)
     sendMessage(renderer, (guy, newPosition, newHealth))
     guyAgent (guy, newPosition, newHealth)

«Все» теперь неизменяемо (на самом деле, под капотом очереди дипатчей агента, вероятно, действительно есть какое-то изменяемое состояние).

4) Если неизменность - это что-то, я должен стремиться и даже прыгать хотя обручи создания новых версий объекты, которые изменились ... И если я создавай моего парня каждый раз, когда он двигается (только с другой позицией) не У меня точно такие же проблемы, как и у меня если бы он был изменчивым?

Ну да. Цикл с изменяемыми значениями и повторение с неизменяемыми эквивалентны.

Редактировать:

  1. Агентам всегда полезна вики .
  2. У Луки Болоньезе есть реализация на F # агентов.
  3. Эта книга (называемая некоторыми Книгой интеллектуальных агентов ), хотя нацелена на приложения ИИ (вместо того, чтобы иметь точку зрения инженерного ПО), превосходна.
2
ответ дан 6 December 2019 в 00:04
поделиться

Пара комментариев по вашим пунктам:

1) Да, возможно. Чтобы уменьшить накладные расходы, практический дизайн, вероятно, в конечном итоге приведет к разделению большого количества состояний между этими экземплярами. Например, возможно, у вашего малыша есть неизменяемая структура «Снаряжения». Новая копия и старая копия могут безопасно ссылаться на одну и ту же структуру «оборудования», поскольку она неизменяема; поэтому вам нужно скопировать только ссылку, а не все. Это обычное преимущество, которое вы получаете только благодаря неизменности - если «equipment» было изменяемым, вы не могли бы поделиться ссылкой, поскольку, если бы она изменилась, ваша «старая» версия тоже изменилась бы.

2) В игре наиболее практичным решением этой проблемы, вероятно, было бы наличие глобальных «часов» и выполнение такого рода обработки один раз, за ​​один такт часов. Обратите внимание, что ваш точный сценарий все равно будет проблемой, если вы не написали его в функциональном стиле: предположим, что H0 - это состояние здоровья во время T. Если вы передали H0 функции, которая приняла решение о состоянии во время T, вы приняли повреждения в момент времени T + 1, а затем функция вернулась в момент времени T + 5, возможно, она приняла неправильное решение, основанное на вашем текущем здоровье.

3) В языке, поддерживающем функциональное программирование, создание экземпляров объектов часто делается настолько дешевым, насколько это возможно. Я знаю, что на JVM создание небольших объектов в куче происходит настолько быстро, что это редко влияет на производительность в какой-либо практической ситуации, а в C # я никогда не сталкивался с ситуацией, когда это было бы проблемой.

3
ответ дан 6 December 2019 в 00:04
поделиться

Если все в глобальном состоянии системы, за пределами текущего кадра стека, является неизменным, если только другой поток не указывает ссылку на что-то в стеке ( ОЧЕНЬ ОПАСНО ), не будет никакого способа потоки делать что-либо, чтобы влиять друг на друга. Вы можете выстрелить и забыть или просто не беспокоиться о стрельбе, и эффект будет таким же.

Предполагая, что некоторые части глобального состояния являются изменяемыми, можно использовать один полезный шаблон:

Do
  Latch a mutable reference to an immutable object
  Generate a new object based upon the latched reference
Loop While CompareExchange fails.

Обмен сравнения должен обновить изменяемую ссылку на новую, если она все еще указывает на старую. Это позволяет избежать накладных расходов на блокировку, если нет одновременного доступа, но может работать хуже, чем блокировка, если многие потоки пытаются обновить один и тот же объект, а создание нового экземпляра из зафиксированного происходит медленно. Одним из преимуществ этого подхода является то, что нет опасности зайти в тупик, хотя в некоторых ситуациях может произойти liveLock.

0
ответ дан 6 December 2019 в 00:04
поделиться

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

Неизменяемость - это хорошо, но вам, возможно, следует переосмыслить свой подход, чтобы использовать больше параллельных решений, чем простое «неизменяемое» все. Подумайте об этом

Thread AI получает копию вашей позиции Вы перемещаетесь на три юнита влево. AI стреляет в вас, исходя из вашей старой позиции, и попаданий ... не должно быть!

Кроме того, большинство игр происходит в «игровых тиках» - многопоточности не так много!

-1
ответ дан 6 December 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: