Ищите хороший шаблон дизайна для этого набора объектов - PullRequest
2 голосов
/ 17 октября 2010

Первоначально я задавал этот вопрос на сайте programmers.stackexchange.com, потому что я полагал, что ответы будут слишком субъективны для stackoverflow.Тем не менее, в комментариях Muad'Dib указывалось на это:

это, вероятно, лучше подходит для StackOverflow ... Это прямой вопрос, связанный с проблемами программирования и обсуждающийпрограммные решения.Одно решение может быть равно другому, когда выбор между ними субъективен, но обсуждение самой проблемы не так, как некоторые решения явно не применимы.Таким образом, этот вопрос имеет один или несколько хороших ответов, тогда как такие вопросы, как «Какой текстовый редактор лучше?»не ...

Итак, немного подумав над ситуацией (и посмотрев на несколько моделей, которые, похоже, не подходят), вот моя дилемма:

The Set Up

Я разрабатываю простую стратегию игры с битвой.

  1. Два бойца атакуют друг друга в течение определенного времени.
  2. Победителем становитсятот, у которого больше всего здоровья после того, как время истекло.
  3. Прямое вмешательство игроков во время боя отсутствует.Игроки определяют некоторые стратегии для своего бойца перед боем, а «ИИ» (термин используется свободно) определяет, что будут делать бойцы.
  4. Бой состоит из произвольного таймера, который «тикает» секунд, и бойца.«Скорость атаки (среди прочего) определяет, как часто они что-то делают.
  5. Помимо объектов-бойцов, есть также« погодный »объект, который может оказывать случайное воздействие на окружающую среду способностей бойца.
  6. Вся эта вещь просто проходит каждую секунду, эффекты и атаки окружающей среды определяются и выполняются, все они записываются в журнал, и впоследствии журнал отображается для пользователя как игра за игрой.

Проблема

Я не уверен, какой шаблон проектирования лучше всего позволил бы мне выполнить вышеизложенное.Я ищу шаблон, который позволит мне увеличить сложность «борьбы» в будущем.Вероятно, добавив в бой больше объектов (больше комбатантов, возможно, новый объект среды и т. Д.)

Сначала я подумал, что шаблон Observer будет работать.У меня был бы объект боя, который представляет «наблюдаемый / субъект».Он отслеживает таймер и при увеличении таймера обновляет все объекты-участники-наблюдатели.Однако многие параметры бойцов-защитников могут влиять на действия атакующего, поэтому «наблюдатели» в этом сценарии должны знать друг друга, поэтому я не уверен, что это правильный подход.

Наконец, я не пытаюсь идеально придать дизайну рисунок.Может быть, нет «наилучшего соответствия».Я просто ищу прочную базу для дальнейшего развития.

Ответы [ 3 ]

2 голосов
/ 19 октября 2010

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

В частности, эта ситуация не совсем подходит для шаблонов проектирования - шаблоны проектирования в основном касаются статических отношений между классами и объектами, тогда как то, о чем вы здесь говорите, по своей природе является алгоритмическим.Шаблоны проектирования предоставляют способы реализации алгоритмов, но сами по себе они не являются алгоритмами.

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

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

1 голос
/ 19 октября 2010

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

Но это не шаблон для всей игры, это скорее решение для одного ее аспекта.

0 голосов
/ 31 июля 2014

Ну, все можно смоделировать с помощью объектов :)

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

Следующая.Пусть каждый бойец является объектом:

class Combatant {
  public $strategy;
  public takeDamage($damageType,$damageAmount){
     if($this->strategy->tryAvoidDamage($damageType,$damageAmount)) return;
     $newDamageAmount=$this->reduceDamageByArmor($damageType,$damageAmount);
     $newDamageAmount=$this->reduceDamageByAbilities($damageType,$newDamageAmount);
     // change your health below...
  }

  public dealDamage($weapoon, $enemy){
     $damageType = $weapoon->damageType;
     $damageAmount = $weapoon->damageAmount;
     $damageAmount = this->applySkills($weapoon, $damageType, $damageAmount);
     $enemy->takeDamage($damageType, $damageAmount);
  }

}  

Стратегия тоже объекты:

class Strategy{
   public $combatant;
   public tryAvoidDamage($damageType,$damageAmount){
     if($damageType=="melee" && $combatant->actionPoints>10){
       // try to block punch (roll dice for skills etc)
       return $combatant->tryBlockPunch();
     }
     return false; // can't avoid bullet
   }
   public DoAction($enviroment){
      if($combatant->hp<10){
         $combatant->tryCastHealing();
      } else {
        var $enemy = $enviroment->findEnemes()->whereDistanceLessThan(2)->mostWeak();
        if($enemy != null) {
           $combatant->dealDamage($combatant->hands, $enemy) 
        }
      }
   }   
}

Следующее, что вам нужно, это создать и инициализировать правильные объекты при запуске цикла

while($combatantA->isAlive() && $combatantB->isAlive()){
  $combatantA->strategy->DoAction(...)
  $combatantB->strategy->DoAction(...)
} 
...