import java.util.*;

class Spillekort{

  // Farve konstanter:
  public final static int RUDER = 0;
  public final static int HJERTER = 1;  
  public final static int KLØR = 2;  
  public final static int SPAR = 3;  

  // Værdi konstanter: 
  public final static int KNÆGT = 11;  
  public final static int DRONNING = 12;  
  public final static int KONGE = 13;
  public final static int ES = 1;  

  private int farve;
  private int værdi;

  Spillekort(int farve, int værdi){
    this.farve = farve;
    this.værdi = værdi;
  }

  private String værdiPræsentation(){
    if (this.værdi == ES)            return ("Es");
    else if (this.værdi == KNÆGT)    return ("Knægt");
    else if (this.værdi == DRONNING) return ("Dronning");
    else if (this.værdi == KONGE)    return ("Konge");
    else return (Integer.toString(værdi));
  }

  private String farvePræsentation(){
    switch (this.farve) {
      case RUDER:    return("Ruder"); 
      case HJERTER:  return ("Hjerter");
      case KLØR:     return("Klør");
      case SPAR:     return("Spar");
      default: return("???");
    }
  }

  public String toString(){
    return(farvePræsentation() + " " + værdiPræsentation());
  }

  public boolean ligMed(Spillekort andetKort){
    return(this.farve == andetKort.farve && this.værdi == andetKort.værdi);
  }

  /** Sammenligning udelukkende på værdi */
  public boolean mindreEnd(Spillekort andetKort){
    int thisReelVærdi  = (this.værdi == 1) ? KONGE+1 : this.værdi;
    int andetKortReelVærdi = (andetKort.værdi == 1) ? KONGE+1 : andetKort.værdi;
    return(thisReelVærdi < andetKortReelVærdi);
  }

  /** Total sammenligning, hvor ruder < hjerter < klør < spar */
  public boolean totalMindreEnd(Spillekort andetKort){
    return (this.farve < andetKort.farve) || 
           (this.farve == andetKort.farve && this.mindreEnd(andetKort));
  }

  public boolean størreEnd(Spillekort andetKort){
    return !(this.ligMed(andetKort) || this.mindreEnd(andetKort));
  }
}

class Kortbunke {
  private List bunke; 

  /** Lav en tom kortbunke */
  public Kortbunke (){
    bunke = new ArrayList();
  }

  /** Lav en kortbunk med bestemte kort, repræsenteret som en liste */
  public Kortbunke (List listeAfKort){
    // Her burde vi nok checke typen af kort
    bunke = (ArrayList)((ArrayList)listeAfKort).clone();
  }

  /** En konstant der symboliserer et fuldt spil kort */
  public static final boolean HELT_KORTSPIL = true;

  /** Lav et komplet spil kort hvis parameteren er den boolske værdi true. Hvis false, lav et tomt spil */
  public Kortbunke (boolean kompletKortSpil){
    bunke = new ArrayList();
    if (kompletKortSpil){
     for(int v = 1; v <= Spillekort.KONGE; v++)
       for (int f = Spillekort.RUDER; f <= Spillekort.SPAR; f++){
         Spillekort kort = new Spillekort(f,v);
         bunke.add(kort);
       }}
  }

  /** Fjern og returner øverste kort. Prebetingelse: bunken er ikke tom */
  public Spillekort tagØverste(){
    return (Spillekort)bunke.remove(0);
  }

  /** Læg kortet kort øverst i denne bunke */
  public void lægØverst (Spillekort kort){
    bunke.add(0,kort);
  }

  /** Læg alle kort i andenBunke øverst i denne bunke */
  public void lægØverst(Kortbunke andenBunke){
    for(Iterator kortIterator = andenBunke.bunkeIterator(); kortIterator.hasNext();){
      this.lægØverst((Spillekort)kortIterator.next());
    }
  }

  /** Læg kort nederst i denne bunke */
  public void lægNederst (Spillekort kort){
    bunke.add(kort);
  }

  /** Læg alle kort i andenBunke nederst i denne bunke */
  public void lægNederst(Kortbunke andenBunke){
    for(Iterator kortIterator = andenBunke.bunkeIterator(); kortIterator.hasNext();){
      this.lægNederst((Spillekort)kortIterator.next());
    }
  }

  /** Returner om denne bunke er tom */
  public boolean erTom(){
    return bunke.isEmpty();
  }

  /** Bland denne bunke tilfældigt */
  public void bland(){
    Collections.shuffle(bunke);
  }

  /* En klasse der indkapsler en compare funktion på to kort */
  private static class KortSortering implements Comparator{
    public int compare(Object o1, Object o2){
      Spillekort kort1 = (Spillekort) o1;
      Spillekort kort2 = (Spillekort) o2;
      if (kort1.ligMed(kort2))
        return 0;
      else if (kort1.totalMindreEnd(kort2))
        return -1;
      else
        return 1;
    }
  }

  /** Sorter denne bunke ved brug af KortSortering's compare operation */
  public void sorter(){
    Collections.sort(bunke,new KortSortering());
  }

  /** Returner en iterator, som tillader et gennemløb af bunken */
  public Iterator bunkeIterator(){
    return bunke.listIterator();
  }

  /** Returner en streng præsentation af denne kortbunke */
  public String toString(){
    return bunke.toString();
  }

  /** Tøm denne bunke */
  public void tøm(){
    bunke.clear();
  }

  /** Returner antallet af kort i denne bunke */
  public int antalKort(){
   return bunke.size();
  }
}

public class Krig {

  /* Et program som adminstrerer et spil kort og to spillere med hver sine kort.
     Programmet gennemfører et simpelt spil, som mange børn kalder 'Krig'.
     Denne version af programmet er basert på klassen Kortbunke
  */

  // Stakkene af kort repræsenteres som Kortbunkt objekter
  static Kortbunke kortSpil = new Kortbunke(Kortbunke.HELT_KORTSPIL);  // et fuld spil kort
  static Kortbunke spillerEt = new Kortbunke();
  static Kortbunke spillerTo = new Kortbunke();

  // En stak af kort der bruges når der opstår en krigssituation.
  static Kortbunke krigsPulje = new Kortbunke();
 
  // En variabel der peger på næste spillers Kortbunke.
  // Dette for at holde styr på, hvem der skal have næste kort når kortene deles ud mv.
  static Kortbunke næsteSpiller; 

  // Skift fra en spiller til den anden
  private static void skift(){
    if (næsteSpiller == spillerEt)
       næsteSpiller = spillerTo;
    else næsteSpiller = spillerEt;
  }

  // Udskriv situtationen for spillerne i termer af øverste kort og antal kort
  private static void situation(Spillekort k1, int n1, Spillekort k2, int n2){
    System.out.print("Spiller 1: " + k1 + "(" + n1 + ")" +  "   " + "Spiller 2: " + k2 + "(" + n2 + ")" + "     ");
  }
  
  public static void main (String[] args){

    // Bland kortene i hele spillet...
    kortSpil.bland();

    næsteSpiller = spillerEt;
    
    // Skriv dem lige ud så vi kan se dem...
    System.out.println("Kortbunken:"); 
    System.out.println(kortSpil);

    // Del kortene ud til spiller et og to:
    for (int i = 1; i <= 52; i++){
      Spillekort etKort = kortSpil.tagØverste();
      næsteSpiller.lægØverst(etKort);
      skift();
    }

    System.out.println("Spiller et's kort:");
    System.out.println(spillerEt);

    System.out.println("Spiller to's kort:");
    System.out.println(spillerTo);

    // Skriv dem lige ud så vi kan se at bunken nu er tom...
    System.out.println("Kortbunken:");
    System.out.println(kortSpil);


    // Og nu igang med spillet:
    while (!spillerEt.erTom() && !spillerTo.erTom()){
      Spillekort spillerEtsKort = spillerEt.tagØverste();
      Spillekort spillerTosKort = spillerTo.tagØverste();

      situation(spillerEtsKort, spillerEt.antalKort()+1, spillerTosKort, spillerTo.antalKort()+1); 

      if (spillerEtsKort.mindreEnd(spillerTosKort)){
         // Spiller to vinder de to kort. Læg de to kort nederst i bunken.
         spillerTo.lægNederst(spillerEtsKort);  spillerTo.lægNederst(spillerTosKort);
         System.out.println("Spiller to vinder");}
      else if (spillerTosKort.mindreEnd(spillerEtsKort)){
         // Spiller et vinder de to kort. Læg de to kort nederst i bunken.
         spillerEt.lægNederst(spillerTosKort);  spillerEt.lægNederst(spillerEtsKort);
         System.out.println("Spiller et vinder");}
      else {
         // Krig:
         System.out.println("KRIG KRIG KRIG KRIG KRIG KRIG KRIG");
 
         // Læg de to kort i krigsPuljen
         krigsPulje.lægØverst(spillerEtsKort);  krigsPulje.lægØverst(spillerTosKort); 
          
         // Hver spiller putter to kort mere i krigsPuljen (hvis de har to kort, vel at mærke)...
         if (!spillerEt.erTom()) krigsPulje.lægØverst(spillerEt.tagØverste());
         if (!spillerEt.erTom()) krigsPulje.lægØverst(spillerEt.tagØverste());
         if (!spillerTo.erTom()) krigsPulje.lægØverst(spillerTo.tagØverste());
         if (!spillerTo.erTom()) krigsPulje.lægØverst(spillerTo.tagØverste());


         // Afgør krigen ved at trække et kort mere og sammenlign:
         if (!spillerEt.erTom() && !spillerTo.erTom()){
            Spillekort spillerEtsAfgørendeKort = spillerEt.tagØverste();
            Spillekort spillerTosAfgørendeKort = spillerTo.tagØverste();
            
            if (spillerEtsAfgørendeKort.mindreEnd(spillerTosAfgørendeKort)){
               // Spiller to får krigsPuljen og de afgørende kort
               krigsPulje.lægØverst(spillerEtsAfgørendeKort); krigsPulje.lægØverst(spillerTosAfgørendeKort); 
               krigsPulje.bland();
               spillerTo.lægNederst(krigsPulje);
               krigsPulje.tøm();
               System.out.println("Spiller to vinder krigen");}
            else if (spillerTosAfgørendeKort.mindreEnd(spillerEtsAfgørendeKort)){
               // Spiller et får krigsPuljen og de afgørende kort
               krigsPulje.lægØverst(spillerEtsAfgørendeKort); krigsPulje.lægØverst(spillerTosAfgørendeKort); 
               krigsPulje.bland();
               spillerEt.lægNederst(krigsPulje);
               krigsPulje.tøm();
               System.out.println("Spiller et vinder krigen");}
            else {
               System.out.print("GENTAGEN KRIG: "); 
               System.out.println(spillerEtsAfgørendeKort + " vs " + spillerTosAfgørendeKort);

               // Vi laver en iterativ løsning på dobbeltkrigsproblemet.
               // De to afgørende kort lægges tilbage til spiller et og to.
               // Når spillet kører næste runde vil der umiddelbar opstå krig igen
               // Bemærk at puljen kun nulstilles når en af spillerne har vundet krigen.

               spillerEt.lægØverst(spillerEtsAfgørendeKort);
               spillerTo.lægØverst(spillerTosAfgørendeKort);
            }
         }

      }

   }

   if (spillerEt.erTom()) System.out.println("SPILLER TO ER VINDER");
   else System.out.println("SPILLER ET ER VINDER");
         
  }
}
