/*
  Si consideri il seguente gioco.
  Ci sono alcune creature fantastiche: streghe, giganti e supereroi.
  La strega ha un punteggio intero 0-10 assegnato a caso per la magia.
  Il gigante ha un punteggio intero 0-10 assegnato a caso per la forza.
  Il supereroe ha un punteggio intero 0-10 assegnato a caso per la magia e un
  punteggio intero 0-10 assegnato a caso per la forza.
  Il gioco consiste nel fare scontrare il supereroe con le altre creature.
  Se lo scontro è con una strega l'eroe vince se ha magia strettamente maggiore della strega.
  Se lo scontro è con un gigante l'eroe vince se ha forza strettamente maggiore del gigante.
  Il gioco consiste nel creare a caso un supereroe e farlo scontrare con streghe e giganti
  creati a caso fino a che l'eroe resti sconfitto. In tal caso si deisderano le statistiche sul
  numero di streghe e giganti uccisi.


  *****************************************
  *********Le interfacce*******************
  ***************************************** */
interface magia {
  //le classi ke implementano qst interfaccia DEVONO ridefinire il metodo getMagia
  public int getMagia();
}

interface forza {
  //le classi ke implementano qst interfaccia DEVONO ridefinire il metodo getForza
  public int getForza();
}

/*
  *****************************************
  *********La classe astratta**************
  *****************************************
*/
abstract class Creatura {
  //le sottoclassi di Creatura erediteranno i membri privati: magia e forza
  protected int magia, forza;
}


/*
  *****************************************
  *******Le sottoclassi di Creatura********
  *****************************************
*/

class Strega extends Creatura implements magia {
  //costruttore: crea Strega con magia casuale
  public Strega() {
    magia = (int) (Math.random()*11);
  }
  //Metodi pubblici (ridefinisco interfaccia magia)
  public int getMagia() {return magia;}
  public String toString() {return "Strega con magia="+magia;}
}

class Gigante extends Creatura implements forza {
  //costruttore: crea Gigante con magia casuale
  public Gigante() {
    forza = (int) (Math.random()*11);
  }
  //Metodi pubblici (ridefinisco interfaccia forza )
  public int getForza() {return forza;}
  public String toString() {return "Gigante con forza="+forza;}
}


/*
  *****************************************
  *******LUI E' IL SUPEREROE!!!!!!!********
  *****************************************
*/

class Supereroe extends Creatura implements magia, forza {
  //membri di istanza privati
  private int winStr, winGig; //numero di Streghe e Giganti sconfitti
  //costruttore
  public Supereroe() {
    magia = (int) (Math.random()*11);
    forza = (int) (Math.random()*11);
  }
  //Metodi pubblici (ridefinisco quelli delle interfacce)
  public int getMagia() {return magia;}
  public int getForza() {return forza;}
  //Metodi pubblici per il punteggio
  public int getWinStreghe() {return winStr;}
  public int getWinGiganti() {return winGig;}
  //Overriding del nome della classe
  public String toString() {return "Eroe con forza="+forza+" e magia="+magia;}

/*
  Metodo per lo scontro tra l'Eroe e un'altra creatura
  Questo è il "cuore" del programma; Qui il nostro Supereroe si imbatte in una
  qualunque "Creatura" (vedi parametro) e in base al tipo (Gigante o Strega) effettua
  il confronto con la forza o la magia. Se l'eroe vince incrementa i suoi "personali"
  contatori di vittoria (infatti un altro eroe avrebbe i suoi, quindi.. "private");
  se l'eroe esce sconfitto, perde un punto di forza o di magia. L'eroe muore quando
  perde entrambi (ho deciso così dato che nel testo non è specificato diversamente)!!
*/
 public void combact(Creatura x) {
  System.out.print("Combatto con la creatura " + x + " e ");
  if (x instanceof Strega) {
    //Scontro con Strega
    Strega tempStr = (Strega) x; //downcasting, in questo caso SICURAMENTE possibile
    if (magia > tempStr.getMagia()) {
      winStr++; //vince Eroe
      System.out.println("Vinco!!");
    }
    else {
      if (magia > 0) --magia; //vince Strega, indebolisce Eroe
      System.out.println("Perdo!!");
    }
  }
  else if (x instanceof Gigante) {
    //Scontro Gigante
    Gigante tempGig = (Gigante) x; //downcasting, in questo caso SICURAMENTE possibile
    if (forza > tempGig.getForza()) {
      winGig++; //vince Eroe
      System.out.println("Vinco!!");
    }
    else {
      if (forza > 0) --forza; //vince Gigante, indebolisce Eroe
      System.out.println("Perdo!!");
    }
  }
 }

  //Restituisce TRUE se l'eroe è stato definitivamente sconfitto (magia==0 && forza==0)
  public boolean isDead() {
    return (magia == 0 && forza == 0);
  }

}


/*
************************************************************
*********Classe principale col metodo main******************
************************************************************
*/

public class Ex_tipo3 {
  public static void main(String[] args) {

    //Creo il mio Supereroe di nome "ercole"
    Supereroe ercole = new Supereroe();
    System.out.println("Ciao Sono Ercole.\nSituazione iniziale di Ercole:\n"+ercole+"\n");

    System.out.println("SI VA A COMBATTERE!!!!!\n");

    //Creo il riferimento a una creatura
    Creatura unaCreatura;


    double cas; //numero casuale

    do {
    
      cas = Math.random();
    
      if (cas >0.5) unaCreatura = new Strega();
      else unaCreatura = new Gigante();
      
      ercole.combact(unaCreatura); //ercole combatte con una creatura
      System.out.println(ercole+"\n"); //situazione di ercole
      
    } while (!ercole.isDead()); //continua finchè sei ancora vivo
    
    //Risultati finali
    System.out.println("\n\nSi, è vero mi hanno sconfitto, ma prima di farmi fuori io ho ucciso:");
    System.out.println(ercole.getWinStreghe() + " Streghe");
    System.out.println(ercole.getWinGiganti() + " Giganti");
  }

}