Использование наследования и полиморфизма для решения общей игровой проблемы - PullRequest
22 голосов
/ 05 мая 2010

У меня есть два класса; давайте назовем их Огром и Волшебником. (Все поля являются общедоступными, чтобы упростить ввод примера).

public class Ogre
{
  int weight;
  int height;
  int axeLength;
}

public class Wizard
{
  int age;
  int IQ;
  int height;
}

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

public Ogre battle(Ogre o)
{
  if (this.height > o.height) return this;
  else if (this.height < o.height) return o;
  else if (this.axeLength > o.axeLength) return this;
  else if (this.axeLength < o.axeLength) return o;
  else return this;    // default case
}

Мы можем сделать аналогичный метод для Wizards.

Но что, если Волшебник встречает Огра? Конечно, мы могли бы сделать метод для этого, сравнив, скажем, только высоту.

public Wizard battle(Ogre o)
{
  if (this.height > o.height) return this;
  else if (this.height < o.height) return o;
  else return this;
}

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

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

public class Character
{
  int height;

  public Character battle(Character c)
  {
    if (this.height > c.height) return this;
    else if (this.height < c.height) return c;
    else return this;
  }
}

Есть ли лучший способ организовать занятия? Я посмотрел на шаблон стратегии и шаблон посредника, но я не уверен, как кто-то из них (если есть) мог бы помочь здесь. Моя цель состоит в том, чтобы достичь какого-то общего метода битвы, чтобы, если Огр встречает Огра, он использует битву Огр-против-Огре, но если Огр встречает Волшебника, он использует более общий метод. Кроме того, что если встречающиеся персонажи не имеют общих черт? Как мы можем решить, кто выиграет битву?

Редактировать: много отличных ответов! Мне нужно переварить их и выяснить, какой из них лучше всего подходит для моей ситуации.

Ответы [ 13 ]

0 голосов
/ 05 мая 2010

попробуйте тройную отправку дяди Боба. см. мой ответ на: Управление межобъектными отношениями

0 голосов
/ 05 мая 2010

Как то так?

class Trait
{
    enum Type
    {
        HEIGHT,
        WEIGHT,
        IQ
    }
    protected Type type;
    protected int value;

    public Trait(int value, Type type)
    {
        this.type = type;
        this.value = value;
    }

    public boolean compareTo(Trait trait)
    {
        if(trait.type != this.type)
            throw new IllegalArgumentException(trait.type+" and "+this.type+" are not comparable traits");
        else
            return this.value - trait.value;
    }
}

class Character
{
    protected Trait[] traits;

    protected Character(Trait[] traits)
    {
        this.traits = traits;
    }

    public Trait getTrait(Trait.Type type)
    {
        for(Trait t : traits)
            if(t.type == type) return t;
        return null;
    }

    public Character doBattleWith(Character that)
    {
        for(Trait thisTrait : traits)
        {
            otherTrait = that.getTrait(thisTrait.type);
            if(otherTrait != null)
            {
                int comp = thisTrait.compareTo(otherTrait);

                if(comp > 0)
                    return this;
                else if (comp < 0)
                    return that;
            }
        }
        return null;
    }
}

class Ogre extends Character
{
    public Ogre(int height, int weight)
    {
        super(new Trait[]{
            new Trait(Type.HEIGHT,height),
            new Trait(Type.WEIGHT,height)});
    }
}
0 голосов
/ 05 мая 2010

Хм, во-первых, ваш первый дизайн не очень хорош, потому что вы позволяете бойцам решать, кто победит. Если вы используете Mediator, например, Что-то вроде предложенного класса битвы, вы сможете централизовать боевую логику и легко изменить любое правило боя в одном месте. Представьте, что у вас много существ ... как только вы захотите изменить способ сражаться вместе, куда вы пойдете искать метод битвы? В первом или во втором классе? Какой-то суперкласс? Так что Посредник - хорошая идея. Еще одна проблема - решить, какое правило использовать. Вы можете легко добраться до проблемы множественной отправки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...