vendredi 2 avril 2021

How to use strategy design pattern if a certain subclass cannot use some of the strategies?

My task was to implement a game. A part of my task was to implement the behavior of a monster. In the task it says a monster has different ways of attacking and each attack has a certain damage rate. Also I have to randomly generate an attack for each monster.

A Dragon can hit (damage: 5) and breath fire (damage: 20).
A Spider can hit (damage: 5) and bite (damage: 8).

My idea was to create a abstract Monster class and have class Spider and Dragon extend this class.
Then I would create an interface called Attack with a method attack and create subclasses Hit, Fire and Bite which implement this interface as strategies. I also created two generator methods one for the Dragon and one for the Spider but I think this is not good maybe someone knows a better way.

abstract class Monster {
  private health = 200;
  attack: Attack;

  constructor(attack: Attack) {
    this.attack = attack;
  }

  getAttackDamage() {
    return this.attack.attack();
  }

  getHealth() {
    return this.health;
  }

  damage(damage: number) {
    let isDefeated = false;
    this.health -= damage;

    if (this.health <= 0) {
      isDefeated = true;
    }

    return isDefeated;
  }
}

class Dragon extends Monster {
  constructor() {
    super(attackDragonGenerator());
  }

  setAttack() {
    this.attack = attackDragonGenerator();
  }
}

class Spider extends Monster {
  constructor() {
    super(attackSpiderGenerator());
  }

  setAttack() {
    this.attack = attackSpiderGenerator();
  }
}

interface Attack {
  attack: () => number;
  damage: number;
}

class Hit implements Attack {
  damage;

  constructor(damage: number) {
    this.damage = damage;
  }

  attack() {
    return this.damage;
  }
}

class Bite implements Attack {
  damage;

  constructor(damage: number) {
    this.damage = damage;
  }

  attack() {
    return this.damage;
  }
}

class Fire implements Attack {
  damage;

  constructor(damage: number) {
    this.damage = damage;
  }

  attack() {
    return this.damage;
  }
}

const attacksSpider: Attack[] = [new Hit(5), new Bite(8)];
const attacksDragon: Attack[] = [new Hit(5), new Fire(20)];

const attackSpiderGenerator = () => {
  const index = randomIntFromInterval(0, 1);
  return attacksSpider[index];
};

const attackDragonGenerator = () => {
  const index = randomIntFromInterval(0, 1);
  return attacksDragon[index];
};

Aucun commentaire:

Enregistrer un commentaire