C, PHP, VB, .NET

Дневникът на Филип Петров


* Контролна работа 23.11.2013

Публикувано на 23 ноември 2013 в раздел ПИК3 Java.

В електронна игра има три вида герои – войни (warriors), стрелци (archers) и варвари (barbarians). Всеки от тях разполага с две основни сили: атака (attack) и защита (defence) – и двете цели числа (тип byte) – както и определено количество живот (health), отново цяло число (тип byte), което първоначално винаги заема максималната си стойност 127.

Освен двете основни сили, всеки вид герой има специална сила (special), отново тип byte:

  • Войните имат armor, който им помага в битките с варварите като увеличава тяхната защита;
  • Стрелците имат специални стрели (flameArrows), които увеличават тяхната атака при битка с войни;
  • Варварите имат кръвожадност (bloodlust), който увеличава тяхната атака при битка със стрелци.

При провеждане на битка специалната и съответната ѝ основна сили се сумират (при нужда), но сумата им не може да надвишава числото 127 (което е и границата на типа). В самата битка се нанасят последователности от удари (походово). Всеки удар намалява точките живот на противника:

Живот на ударения = Живот на ударения – att2(Атака на противника – Защита на ударения)

От формулата функцията att2 се грижи атаката да не стане отрицателно число или 0.
Ако Атака на противника – Защита на ударения е по-малка от 1, трябва да се приравни на 1.

Както беше споменато, ударите се нанасят последователно, като първо атакува нападателя. Ако той убие противника си (health на противника стане 0 или по-малък от 0), битката приключва. Ако не го убие, ролите се сменят и нападнатия противник нанася своя удар. Битката продължава в същия дух до смъртта на един от двата противници.

Битките се провеждат контролирано (потребителя сам насочва свой герой да нападне даден противник) или автоматично (два героя от противникови лагери се сбиват без намеса на играча). За провеждане на контролирана битка трябва да се използва следния метод на използвания герой:

public boolean attack(Opponent p){ … } // връща true ако победим или false ако загубим

а при автоматична битка трябва да реализирате статичен метод:

public static boolean autoAttack(Attacker a, Defender d){ … } // true/false ако Attacker победи/загуби

Естествено Opponent, Attacker и Defender се заменят със съответните типове войни.

Направете клас с main метод, в който инициализирайте две армии (по ваш избор два списъка или масива), всяка от която притежава различни видове войни. Демонстрирайте поне една контролирана и една автоматична битка.

Решение: За удобство в решението е използвана рекурсия (не е задължително). Също така са поставени незадължителни отпечатвания в конзолата, с които се следи хода на всяка една битка.

Hero.java:

package game;

public abstract class Hero{
  private byte attack;
  private byte defence;
  private byte special;
  byte health;
  public Hero(byte attack, byte defence, byte special) throws Exception{
    if(attack<1 || defence<0 || special <0) throw new Exception("Невалидни данни");
    this.attack = attack;
    this.defence = defence;
    this.special = special;
    this.health = 127;
  }
  public byte getAttack(){ return this.attack; }
  public byte getDefence(){ return this.defence; }
  public byte getSpecial(){ return this.special; }
  public abstract boolean attack(Hero opponent);
  public static boolean autoAttack(Hero attacker, Hero defender){
    return attacker.attack(defender);
  }
}

Warrior.java:

package game;

public class Warrior extends Hero{
  public Warrior(byte attack, byte defence, byte armor) throws Exception{
    super(attack, defence, armor);
  }
  public boolean attack(Hero opponent){
    if(this.health<=0){
      return false;
    }
    if(opponent.health<=0){
      return true;
    }
    System.out.print(this.getClass()+" hits");
    int attackPower = super.getAttack();
    int opponentDefence = opponent.getDefence();
    int hit = attackPower-opponentDefence>0?attackPower-opponentDefence:1;
    opponent.health -= hit;
    System.out.println(". Damage done: "+hit);
    return !opponent.attack(this);
  }
}

Archer.java:

package game;

public class Archer extends Hero{
  public Archer(byte attack, byte defence, byte flameArrows) throws Exception{
    super(attack, defence, flameArrows);
  }
  public boolean attack(Hero opponent){
    if(this.health<=0){
      return false;
    }
    if(opponent.health<=0){
      return true;
    }
    System.out.print(this.getClass()+" hits");
    int attackPower = super.getAttack();
    byte opponentDefence = opponent.getDefence();
    if(opponent instanceof Warrior) attackPower += super.getSpecial();
    if(attackPower>127) attackPower=127;
    int hit = attackPower-opponentDefence>0?attackPower-opponentDefence:1;
    opponent.health -= hit;
    System.out.println(". Damage done: "+hit);
    return !opponent.attack(this);
  }
}

Barbarian.java:

package game;

public class Barbarian extends Hero{
  public Barbarian(byte attack, byte defence, byte bloodlust) throws Exception{
    super(attack, defence, bloodlust);
  }
  public boolean attack(Hero opponent){
    if(this.health<=0){
      return false;
    }
    if(opponent.health<=0){
      return true;
    }
    System.out.print(this.getClass()+" hits");
    int attackPower = super.getAttack();
    int opponentDefence = opponent.getDefence();
    if(opponent instanceof Warrior) opponentDefence += opponent.getSpecial();
    else{
      if(opponent instanceof Archer) attackPower += super.getSpecial();
      if(attackPower>127) attackPower = 127;
    }
    int hit = attackPower-opponentDefence>0?attackPower-opponentDefence:1;
    opponent.health -= hit;
    System.out.println(". Damage done: "+hit);
    return !opponent.attack(this);
  }
}

Game.java:

package game;
import java.util.ArrayList;
import java.util.LinkedList;

public class Game{
  public static void main(String[] args){
    ArrayList<Hero> army1 = new ArrayList<Hero>(3);
    try{
      army1.add(new Warrior((byte)50, (byte)15, (byte)20));
      army1.add(new Archer((byte)30, (byte)25, (byte)20));
      army1.add(new Barbarian((byte)50, (byte)15, (byte)0));
    }
    catch(Exception e){ System.out.println(e.getMessage()); };

    LinkedList<Hero> army2 = new LinkedList<Hero>();
    try{
      army2.add(new Archer((byte)30, (byte)25, (byte)10));
      army2.add(new Warrior((byte)10, (byte)35, (byte)10));
      army2.add(new Barbarian((byte)25, (byte)25, (byte)10));
      army2.add(new Archer((byte)70, (byte)10, (byte)5));
    }
    catch(Exception e){ System.out.println(e.getMessage()); };

    if(army1.get(0).attack(army2.get(0))){
      System.out.println("Army 1 won a battle");
      army2.remove(0);
    }
    else{
      System.out.println("Army 2 won a battle");
      army1.remove(0);
    }
    System.out.println();

    if(Hero.autoAttack(army1.get(0), army2.get(2))){
      System.out.println("Army 1 won a battle");
      army2.remove(2);
    }
    else{
      System.out.println("Army 2 won a battle");
      army1.remove(0);
    }
    System.out.println();    
  }
}

Ако имате въпроси, може да ги зададете в коментари под статията или по e-mail. Може и да изтеглите файловете със сорс кода.

 



Един коментар


  1. Валери каза:

    if(opponent instanceof Warrior) attackPower += super.getSpecial(); според мен тук има грешка, и тук би трябвало да бъде: if(opponent instanceof Warrior) opponentDefence+=opponent.getSpecial();

Добави коментар

Адресът на електронната поща няма да се публикува


*