import java.awt.Color;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList; 

// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
import java.util.Iterator;
// #[regen=yes,id=DCE.10E066DE-012A-25DC-3A9F-0C55197BB506]
import java.util.Random;
// </editor-fold> 
import java.util.Scanner;
import java.util.StringTokenizer;
public class Partida implements Serializable{

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.291F6FB3-F705-DF82-8D00-502E3DD0EBE6]
    // </editor-fold> 
    private ArrayList<Jugador> mJugador;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.839314DD-F39A-7312-62BE-556C3367D2F4]
    // </editor-fold> 
    private Tablero tablero;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.D4F79F6A-5E7C-D212-8B8F-F9DC2186DDBB]
    // </editor-fold> 
    private Turno mTurno;        
    
    /*Variables que hemos creado nosotros*/
    private String modalidadJuego;   
    private int numeroDeCambiosDeCartas;        
    
    /*Variables que controlan los posibles colores de los jugadores*/
    public ArrayList<Color> coloresJugadores;
    
    /*Jugador pivote de la aplicacion*/
    private Jugador jActivo = new Jugador();
    
    /*Variables para controlar las armadas que aparecen en las cartas*/
    /*Los tipos iran en este orden: Infanteria, Caballeria y Artilleria*/
    public String [] tiposDeArmada = {"Infanteria", "Caballeria", "Artilleria"};
    int [] numeroCartasPorTipo = new int[tiposDeArmada.length];    
    /*************************************/
    
    
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.6BFC800C-3DDA-C12A-4D8A-0775215238DB]
    // </editor-fold> 
    public Partida () 
    {
        /*Definimos la modalidad de juego*/
        //modalidadJuego = "CONQUISTA";
        modalidadJuego = "CAPITAL";
        //modalidadJuego = "MISION";
        
        
        /*Aunque no hace falta, definimos un tamaño maximo de capacidad*/
        mJugador = new ArrayList<Jugador>(6);         
        
        /*Creamos los jugadores*/
        Jugador j1 = new Jugador("Jugador 1"); mJugador.add(j1);       
        Jugador j2 = new Jugador("Jugador 2"); mJugador.add(j2);        
        Jugador j3 = new Jugador("Jugador 3"); mJugador.add(j3);
        
        /*En funcion del numero de jugadores asignamos ejercitos para que se puedan ubicar*/
        j1.setNumEjercitosParaUbicar(20);
        j2.setNumEjercitosParaUbicar(20);
        j3.setNumEjercitosParaUbicar(20);
        
        //setJugador(mJugador); 
        
        /*Asignamos colores a los jugadores*/
        asignarColorAlJugador();
        
        /*Inicializacion del mapa*/
        inicializarMapa(); 
        
        numeroDeCambiosDeCartas = 1;    /*Indica que se espera el primer cambio de la partida*/
    }        
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.5ADB86F9-744D-7AB7-999C-C74E02720B9A]
    // </editor-fold> 
    public ArrayList<Jugador> getJugador () {
        return mJugador;
    }
    
    public void setJugador (ArrayList<Jugador> val) 
    {
        this.mJugador = val;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.10D517E4-59B8-1C2D-C444-AB97566D6DB1]
    // </editor-fold> 
    public Tablero getTablero () {
        return tablero;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.F3EDD95A-A934-B013-AEE6-89772EBD8E53]
    // </editor-fold> 
    public void setTablero (Tablero val) {
        this.tablero = val;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.D310CE34-E98D-3DB6-206F-51F9AFC63F8E]
    // </editor-fold> 
    public Turno getTurno () {
        return mTurno;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.C4B6F8A8-A7AD-6595-E9D1-FDF6ACC6D21F]
    // </editor-fold> 
    public void setTurno (Turno val) {
        this.mTurno = val;
    }
    
    
    public Jugador getJActivo() {
        return jActivo;
    }

    public void setJActivo(Jugador jActivo) {
        this.jActivo = jActivo;
    }
    
    public void inicializarMapa()
    {                
        try
        {
            tablero = new Tablero();
                        
            /*Repartimos los Territorios entre los jugadores*/
            Iterator<Territorio> itTerritorios = tablero.getTerritorio().iterator();        
            Territorio tPivote = new Territorio();
                                     
            Random nAleatorio = new Random();
            int valorAleatorio;    
            
            /*Creamos un array tipo int de identificadores de territorio*/
            
            ArrayList idTerritorio= new ArrayList(); 
            
            for (int i=0; i<tablero.getTerritorio().size(); i++) /*inicializamos el array con los id*/
                idTerritorio.add (itTerritorios.next().getId());
          
           int territoriosARepartir = tablero.getTerritorio().size() /  mJugador.size();
           
            for (int j=0; j<mJugador.size(); j++)
            {
                for (int i=0; i<territoriosARepartir; i++)
                {            
                                   
                    valorAleatorio = nAleatorio.nextInt(idTerritorio.size())+1; //coge la posición de un id aleatoriamente                
                    Object id = idTerritorio.get(valorAleatorio-1);
                    
                    idTerritorio.remove(valorAleatorio-1);
                    tPivote = buscarTerritorioPorId(tablero.getTerritorio(), id); //Tenemos el territorio a asignar al jugador
                    
                    tPivote.setJugador(mJugador.get(j));
                    
                    mJugador.get(j).setTerritorio(tPivote);
                    System.out.println("  Territorio: " + tPivote.getNombre() + " de " + tPivote.getJugador().getNombre());            
                }
            }
           /*Si sobran territorios se les asignará aleatoriamente a los jugadores*/
          Iterator itId = idTerritorio.iterator(); //iterador para movernos por el arrayList de id que queadan por asignar
          
          while(itId.hasNext())
          {                                                         
              Object id = itId.next();              
               
              valorAleatorio = nAleatorio.nextInt(mJugador.size())+1; //generamosun numero aleatorio para coger un jugador
              tPivote = buscarTerritorioPorId(tablero.getTerritorio(), id); //devuelve el territorio que coincide con el id pasado
              tPivote.setJugador(mJugador.get(valorAleatorio-1));
              mJugador.get(valorAleatorio-1).setTerritorio(tPivote);
              System.out.println("  Territorio: " + tPivote.getNombre() + " de " + tPivote.getJugador().getNombre());                                                         
          } 
          
          
          
          /*En función de la modalidad de juego, creamos las cartas de mision o 
           asignamos una capital al jugador*/
          if (modalidadJuego.equals("CAPITAL"))
              asignarCapital();
          else if (modalidadJuego.equals("MISION"))
              asignarMision();                              
        }         
        catch(Exception error)
        {
            System.out.println(error.getMessage());
        }                
    }
    
    public void jugar ()
    {                                                                                                                       
        /*Con la lista llena de jugadores, inicializamos el iterador, ya que antes daria fallo*/
        Iterator <Jugador> it = mJugador.iterator();                                        
            
        
        setJActivo(it.next());
        while (!jActivo.getObjetivoCumplido())
        {                            
            /*Asiganamos ejércitos al jugador antes de que comienze su turno*/
            asignarEjercitos(getJActivo());
            
            /*El jugador puede comenzar su turno*/
            System.out.println("El jugador " + getJActivo().getNombre() + " tiene el turno");            
            mover(getJActivo());            
            
            /*Si el jugador se ha dado por vencido, lo eliminamos del array*/
            if (getJActivo().getAbandonaPartida())                            
                it.remove();                
            
            /*Al quedar solo un jugador, lo consideramos como ganador*/
            if (mJugador.size() == 1)                
                break;             
                        
            /*Asignamos una Carta de Terrotorio si ha conquistado algún territorio en el turno*/
            obtenerCarta(getJActivo());
            
            /*Por ultimo cambiar el turno*/            
            if (!it.hasNext())
                it = mJugador.iterator();   /*Pone el iterador de nuevo al principio*/               
            setJActivo(it.next());
        }
        
        System.out.println("\n!!!El jugador " + mJugador.get(0).getNombre() + " ha GANADO la partida!!!\n");
    }
    
    
    public void mover(Jugador jActivo) 
    {
        jActivo.setHaFinalizadoElTurno(false);

        while (!jActivo.getHaFinalizadoElTurno()) 
        {
            Scanner teclado = new Scanner(System.in);

            /*Mostramos un menu de opciones*/
            System.out.println("Indique la opcion a realizar:\n");
            /*System.out.println("Para atacar opcion 'a'");
            System.out.println("Para transferir opcion 't'");
            System.out.println("Para ubicar opcion 'u'");
            System.out.println("Para finalizar turno opcion 'f'");
            System.out.println("Para abandonar partida opcion 'A'\n");
            System.out.println("Opcion: ");*/


            switch (teclado.nextLine().charAt(0)) 
            {
                case 'a':
                    jActivo.atacar();
                    break;
                case 't':
                    jActivo.transferir();
                    break;
                case 'u':
                    jActivo.ubicar();
                    break;
                case 'A':
                    System.out.println("El " + jActivo.getNombre() + " Abandona la Partida");
                    jActivo.setAbandonaPartida(true);
                    return;
                case 'f':
                    jActivo.finalizarTurno();
                    break;
                case 'm':
                    System.out.println("Mision: "+jActivo.getCartaMision().getNombre());
                    System.out.println("Color: "+jActivo.getColor().toString());
                    break;
                case 'g':
                    System.out.println("Guardando Partida...");
                    guardarPartida();
                    break;
                case 'v':
                    for (int i = 0; i < jActivo.getTerritorios().size(); i++) 
                        System.out.println("Territorio: " + jActivo.getTerritorios().get(i).getNombre() + " - " + jActivo.getTerritorios().get(i).getNumEjercitos());                    
                    break;
            }
        }
    }
    
    /*Metodo que devuelve un territorio de un arraList pasado por parametro en 
    funcion del identificador de territorio que pasamos por parametro tambien*/
    public Territorio buscarTerritorioPorId(ArrayList<Territorio> arrayTerritorios, Object id) 
    {
        /*Recorremos el array buscando un territorio cuyo "identificador" sea el indicado*/
        for (int i = 0; i < arrayTerritorios.size(); i++) 
        {
            if (arrayTerritorios.get(i).getId() == id)
                return arrayTerritorios.get(i);           
        }
        return null;
    }

    
    /*Metodo que implementa el caso de uso Asignar Ejércitos al jugador*/
    public void asignarEjercitos(Jugador jActivo)
    {
        int numEjercitosParaAsignar = 0;
        /*Llamadas a los métodos que dan ejérictos al jugador*/
        
        numEjercitosParaAsignar += porTerritorioConquistado(jActivo);
        System.out.println("Numero de territorios por asignados " + numEjercitosParaAsignar);
        
        numEjercitosParaAsignar += porContinenteConquistado(jActivo);
        
        numEjercitosParaAsignar += porCambioDeCartas(jActivo);
             
        numEjercitosParaAsignar += porCartaTerritorioPoseido(jActivo);
        
        jActivo.setNumEjercitosParaUbicar(jActivo.getNumEjercitosParaUbicar() + numEjercitosParaAsignar);        
    }
    
    
    /*A continuación, la implementacion de todos los anteriores métodos*/
    public int porTerritorioConquistado(Jugador jugador)
    {
        if (jugador.getTerritorios().size() < 9)
            return 3;
        else        
            return jugador.getTerritorios().size()/3;                
    }
    
    public int porContinenteConquistado(Jugador jugador)
    {        
        int armadas = 0;
        
        for (int i = 0; i<tablero.getContinente().size(); i++)
        {
            if(continentePerteneceJugador (tablero.getContinente().get(i), jugador))            
                armadas += tablero.getContinente().get(i).getArmadasPorSerConquistado();            
        }
        
        return armadas;                
        
    }
    
    public int porCambioDeCartas(Jugador jugador)
    {
        /*****************************PROVISIONAL*********************************************/
        ArrayList<CartaDeTerritorio> cartas = new ArrayList<CartaDeTerritorio>();
        CartaDeTerritorio c1 = new CartaDeTerritorio(new Territorio("Terri1"), "Artilleria");
        CartaDeTerritorio c2 = new CartaDeTerritorio(new Territorio("Terri2"), "Infanteria");
        CartaDeTerritorio c3 = new CartaDeTerritorio(new Territorio("Terri3"), "Caballeria");
        CartaDeTerritorio c4 = new CartaDeTerritorio(new Territorio("Terri4"), "Artilleria");
        //CartaDeTerritorio c4 = new CartaDeTerritorio(new Territorio("T4"), "Caballeria");
        cartas.add(c1);cartas.add(c2);cartas.add(c3);cartas.add(c4);                        
        /**************************************************************************************/
                
        
        if (comprobarCombinaciones(cartas))
        {
            Scanner tecla = new Scanner(System.in);
            
            System.out.println("Hay cartas para cambiar");
            if (cartas.size() == 3 || cartas.size() == 4)
            {
                System.out.println("Puedes Cambiar cartas en este turno ¿Quieres?(y/n)\n");
                if (tecla.nextLine().charAt(0) == 'y')
                    return cambiarCartasPorEjercitos(cartas);
                else 
                    return 0;
            }
            else if (cartas.size() == 5 || cartas.size() == 6)
            {
                System.out.println("DEBES Cambiar cartas en este turno\n");                        
                return cambiarCartasPorEjercitos(cartas);
            }
        }
        else
        {
            System.out.print("No hay cartas para poder cambiar\n");
            return 0;
        }                                  
        return 0; /*Nunca saldrá por aqui pero si no, netbeans no nos deja ejecutar*/
    }
        
    
    public boolean comprobarCombinaciones(ArrayList<CartaDeTerritorio> cartas)
    {                        
        /*Inicializamos el araya que contndra en forma de enteros, 
         las combinacionesde cartas de cada jugador*/        
        for (int i=0; i<numeroCartasPorTipo.length; i++)
            numeroCartasPorTipo[i] = 0;
        
        /*Recorremos el array en busca de los grupos de cambio*/
        for (int i=0; i<tiposDeArmada.length; i++)
        {
            for (int j=0; j<cartas.size(); j++)
            {
                if (cartas.get(j).getArmada().equals(tiposDeArmada[i]))
                    numeroCartasPorTipo[i] ++;
            }
        }
                    
        System.out.println(numeroCartasPorTipo[0]+"-"+numeroCartasPorTipo[1]+"-"+numeroCartasPorTipo[2]);
        
        /*String combinacion = String.valueOf(numeroCartasPorTipo[0])+
                String.valueOf(numeroCartasPorTipo[1])+
                String.valueOf(numeroCartasPorTipo[2]);*/
        if (numeroCartasPorTipo[0] >= 3)
        {
            System.out.println("Puede cambiar las cartas de "+tiposDeArmada[0]
                    +" ya que tiene "+numeroCartasPorTipo[0]+" cartas");
            return true;
        }
        if (numeroCartasPorTipo[1] >= 3)
        {
            System.out.println("Puede cambiar las cartas de "+tiposDeArmada[1]
                    +" ya que tiene "+numeroCartasPorTipo[2]+" cartas");
            return true;
        }
        if (numeroCartasPorTipo[2] >= 3)
        {
            System.out.println("Puede cambiar las cartas de "+tiposDeArmada[2]
                    +" ya que tiene "+numeroCartasPorTipo[2]+" cartas");
            return true;
        }
        //Si tiene al menos tres cartas de diferentes tipos de armada
        if (numeroCartasPorTipo[0] >= 1 && numeroCartasPorTipo[1] >= 1 && numeroCartasPorTipo[2] >= 1)
        {
            System.out.println("Puede cambiar las cartas ya que posee al menos una carta de cada grupo");
            return true;
        }
                
        
        return false;
    }        
    
    /*Metodo que recogera el array de numeroDeCartasPorTipo y devolverá las 
     combinaciones que el jugador podrá cambiar por nuevas armadas*/
    public int cambiarCartasPorEjercitos(ArrayList<CartaDeTerritorio> cartas)
    {
        Scanner tecla = new Scanner(System.in);
                
        System.out.println("Combinaciones Posibles:\n");
        
        if (numeroCartasPorTipo[0] >= 3)        
            System.out.println(" - Combinación de "+tiposDeArmada[0]+" (Pulse 1)");        
        if (numeroCartasPorTipo[1] >= 3)        
            System.out.println(" - Combinación de "+tiposDeArmada[1]+" (Pulse 2)");
        if (numeroCartasPorTipo[2] >= 3)        
            System.out.println(" - Combinación de "+tiposDeArmada[2]+" (Pulse 3)");
        if (numeroCartasPorTipo[0] >= 1 && numeroCartasPorTipo[1] >= 1 && numeroCartasPorTipo[2] >= 1)
            System.out.println(" - Combinación de 1 diferente de cada Tipo  (Pulse 4)");
        
        switch (tecla.nextLine().charAt(0))
        {
            case '1':
                eliminarCartasDelJugador(cartas, 1);    /*con el 1 indicamos que hay que eliminar 
                                                        las cartas que se recogen con la opcion 1 
                                                        del menu anterior*/
                return devolverNumeroArmadas();
            case '2':
                eliminarCartasDelJugador(cartas, 2);
                return devolverNumeroArmadas();
            case '3':
                eliminarCartasDelJugador(cartas, 3);
                return devolverNumeroArmadas();
            case '4':
                eliminarCartasDelJugador(cartas, 4);
                return devolverNumeroArmadas();
        }
        
        //Por este return no se va a colar nunca, pero como hay que devolver algo le ponemos 0
        return 0;
    }
    
    public void eliminarCartasDelJugador(ArrayList<CartaDeTerritorio> cartas, int opcion)
    {
        int numCartasEliminadas = 0; /*Controla que sólo se eliminen 3 cartas como maximo del array*/
        boolean [] flagCartaEliminada = new boolean[tiposDeArmada.length];
                
        
        if (opcion == 1)
        {        
            for (int i=0; i<cartas.size(); i++)
            {            
                if (cartas.get(i).getArmada().equals(tiposDeArmada[0]))
                {
                    cartas.remove(i);
                    if (numCartasEliminadas != 3) numCartasEliminadas++; else break;
                }                    
            }
        }
        else if (opcion == 2)
        {        
            for (int i=0; i<cartas.size(); i++)
            {            
                if (cartas.get(i).getArmada().equals(tiposDeArmada[1]))
                {
                    cartas.remove(i);
                    if (numCartasEliminadas != 3) numCartasEliminadas++; else break;
                }                    
            }
        }
        else if (opcion == 3)
        {        
            for (int i=0; i<cartas.size(); i++)
            {            
                if (cartas.get(i).getArmada().equals(tiposDeArmada[2]))
                {
                    cartas.remove(i);
                    if (numCartasEliminadas != 3) numCartasEliminadas++; else break;
                }                    
            }
        }
        else if (opcion == 4)
        {
            for (int i=0; i<flagCartaEliminada.length; i++)
                flagCartaEliminada[i] = false;
            
            for (int i=0; i<cartas.size(); i++)
            {            
                if (cartas.get(i).getArmada().equals(tiposDeArmada[0]) && flagCartaEliminada[0] == false)
                {
                    cartas.remove(i);
                    flagCartaEliminada[0] = true;
                }
                else if (cartas.get(i).getArmada().equals(tiposDeArmada[1]) && flagCartaEliminada[1] == false)
                {
                    cartas.remove(i);
                    flagCartaEliminada[1] = true;
                }
                else if (cartas.get(i).getArmada().equals(tiposDeArmada[2]) && flagCartaEliminada[2] == false)
                {
                    cartas.remove(i);
                    flagCartaEliminada[2] = true;
                }
                
                if (numCartasEliminadas != 3) numCartasEliminadas++; else break;
            } 
        }   
    }
    
    /*Metodo que implementa la tabla de cambio de armadas en funcion de numero de cambio de 
     cartas que se hayan realizado hasta el momento*/
    public int devolverNumeroArmadas()
    {
        int armadas = 0;
        
        switch (numeroDeCambiosDeCartas)
        {
            case 1:
                armadas = 4;
                break;
            case 2:
                armadas = 6;
                break;
            case 3:
                armadas = 8;
                break;
            case 4:
                armadas = 10;
                break;
            case 5:
                armadas = 12;
                break;
            case 6:
                armadas = 15;
                break;
            default:
                //Es meramente una formula matemática que resulve la sucesión ES REBUSCADA PERO RULA
                armadas = numeroDeCambiosDeCartas + (9 + (4 * (numeroDeCambiosDeCartas - 6)));
                break;
        }
        System.out.println("Numero de Cambios de Cartas: "+numeroDeCambiosDeCartas+" \nLe correspnde "+armadas+" armadas\n");
        numeroDeCambiosDeCartas ++;                        
        
        return armadas;
    }
      
    
    public int porCartaTerritorioPoseido(Jugador jActivo/*, ArrayList<CartaDeTerritorio> cartas*/)    
    {
        /*****************************PROVISIONAL*********************************************/
        ArrayList<CartaDeTerritorio> cartas = new ArrayList<CartaDeTerritorio>();
        CartaDeTerritorio c1 = new CartaDeTerritorio(new Territorio("Terri1"), "Artilleria");
        CartaDeTerritorio c2 = new CartaDeTerritorio(new Territorio("Terri2"), "Infanteria");
        CartaDeTerritorio c3 = new CartaDeTerritorio(new Territorio("Terri3"), "Artilleria");
        CartaDeTerritorio c4 = new CartaDeTerritorio(new Territorio("Terri4"), "Artilleria");
        //CartaDeTerritorio c4 = new CartaDeTerritorio(new Territorio("T4"), "Caballeria");
        cartas.add(c1);cartas.add(c2);cartas.add(c3);cartas.add(c4);                
        jActivo.setCartaDeTerritorio(cartas);
        /**************************************************************************************/
        
        /*Recorremos los territorios buscando si hay alguna carta que coincida con él para 
         darle al jugador 2 armadas más*/
        
        for (int i=0; i<jActivo.getTerritorios().size(); i++)
        {
            for (int j=0; j<jActivo.getCartaDeTerritorio().size(); j++)
            {
                if (jActivo.getTerritorios().get(i).getNombre().equals(cartas.get(j).getTerritorioCarta().getNombre()))
                {
                    System.out.println("Tiene una carta con el territorio "+jActivo.getTerritorios().get(i).getNombre()+"\n");
                    System.out.println("Se le dan 2 armadas mas\n");
                    return 2;   /*Ya que dicen que se devuelven 2 armadas*/
                }                    
            }
        }
        return 0;
    }
    
    /*Método que asignará al jugador en turno una y sólo una Carta de Territorio si ha 
     conquistado al menos un territorio*/    
    public void obtenerCarta(Jugador jActivo)
    {
        if(jActivo.getHaConquistadoAlgunTerritorio())
        {
            CartaDeTerritorio carta = tablero.devolverCarta();
            if(carta != null)/*Null es el valor que devuelve en caso de no existir mas cartas que dar*/
            {
                System.out.println("Se le ha añadido al jugador "+ jActivo.getNombre() +" la carta de Territorio "+carta.getTerritorioCarta().getNombre()+".");
                jActivo.getCartaDeTerritorio().add(carta);
            }            
        }
    }    
    
    
    /*Metodo que coge un territorio del array de territorios (el primero que encuentre) 
     de un jugador y lo asigna como capital para ese jugador*/
    private void asignarCapital()
    {
        for (int i=0; i<mJugador.size(); i++) 
        {
            System.out.println("La capital del jugador "+mJugador.get(i).getNombre()+" es "+mJugador.get(i).getTerritorios().get(0).getNombre());            
            mJugador.get(i).setMiCapital(mJugador.get(i).getTerritorios().get(0));        
            mJugador.get(i).getTerritorios().get(0).setEsCapital(true);            
        }
    }
        
    /*Metodo que asigna a cada uno de los jugadores las cartas de mision*/
    private void asignarMision()
    {      
        Random nAleatorio = new Random();
        int valorAleatorio;
                
        /*Eliminamos las cartas de Destruir Jugador segun Color ya que 
         existen cartas de mision que hay que quitar del juego*/
        for (int i=0; i<6-mJugador.size(); i++)       
            tablero.getMCartasMision().remove(tablero.getMCartasMision().size()-1);        
                
        /*Repartimos el resto de cartas de mision*/
        for (int i=0; i<mJugador.size(); i++)
        {
            valorAleatorio = nAleatorio.nextInt(tablero.getMCartasMision().size());
            
            /*Habria que problarlo mas detenidamente*/
            if (tablero.getMCartasMision().get(valorAleatorio).getNombre().equals(mJugador.get(i).getColor()))
            {
                /*Por coincidir la mison con el color del jugador, se le asigna la mision de conquistar 24 Territorios*/
                mJugador.get(i).setCartaMision(new CartaMision("24Territorios", "Ocupar"));
                System.out.println("Se cambia de mision por coincidencia de color\n");
            }                
            else
                mJugador.get(i).setCartaMision(tablero.getMCartasMision().get(valorAleatorio));                        
            
            tablero.getMCartasMision().remove(valorAleatorio);            
        }
    }
    
    private void asignarColorAlJugador()
    {
        Random nAleatorio = new Random();
        int valorAleatorio;
        
        /*Creamos los colores*/
        coloresJugadores = new ArrayList<Color>();
        coloresJugadores.add (Color.RED);
        coloresJugadores.add (Color.BLUE);
        coloresJugadores.add (Color.GREEN);
        coloresJugadores.add (Color.ORANGE);
        coloresJugadores.add (Color.YELLOW);
        coloresJugadores.add (Color.PINK);
        
        /*Y los repartimos*/
        for (int i=0; i<mJugador.size(); i++)
        {
            valorAleatorio = nAleatorio.nextInt(coloresJugadores.size());
            mJugador.get(i).setColor(coloresJugadores.get(valorAleatorio));
            System.out.println("El jugador "+mJugador.get(i).getNombre()+" tiene el color "+coloresJugadores.get(valorAleatorio).toString());
            coloresJugadores.remove(valorAleatorio);
        }
    }
    
    
    /*Metodo que implementa la comprobación de objetivo dependiendo de la modalidad de juego
     que el jugador escoga al inicio de la partida*/
    public boolean comprobarObjetivoCumplido(Jugador j)
    {
        if (modalidadJuego.equals("CONQUISTA"))
            return comprobarObjetivoConquista(j);
        else if (modalidadJuego.equals("CAPITAL"))
            return comprobarObjetivoCapital(j);
        else if (modalidadJuego.equals("MISION"))
            return comprobarObjetivoMision(j);
        else /*Nunca debe entra por aqui, lo ponemos por si acaso*/        
        {
            System.out.println("¡¡¡ Error al validar la modalidad de Juego!!!\n");
            return false;
        }
    }
    
    /*Metodo que devolvera si el jugador en la modalidad de conquista ha cumplido el objetivo*/
    protected boolean comprobarObjetivoConquista(Jugador j)
    {
        if (j.getTerritorios().size()==tablero.getTerritorio().size())
            return true;
        
        return false;
    }
    
    /*Metodo que en la modalidad de Capitales devuelve si el jugador tiene 
     conquistadas las capitales necesarias para ganar el juego*/
    protected  boolean comprobarObjetivoCapital(Jugador j)
    {        
        /*Se debe comprobar que el jugador tenga todos los cuarteles de los otros jugadores
         Opcionalmente:
            - Si los jugadores son 4 basta con conquistar 2 capitales mas la suya propia
            - Si son 5 o 6 jugadores, 3 capitales mas la suya propia            
         */
        if (j.jugadorPoseeSuCapital())
        {
            if (mJugador.size() == 3 && numeroCapitalesPoseeJugador(j) == 2)
                return true;
            else if (mJugador.size() == 4 && numeroCapitalesPoseeJugador(j) == 2)
                return true;
            else if (mJugador.size() >=5 && numeroCapitalesPoseeJugador(j) == 3)
                return true;
        }        
        return false;
    }
    
    private int numeroCapitalesPoseeJugador(Jugador j)
    {
        int capitales = 0;
        
        for (int i=0; i<j.getTerritorios().size(); i++)
        {
            if (j.getTerritorios().get(i).getEsCapital() && j.getTerritorios().get(i) != j.getMiCapital())
                capitales ++;            
        }   
        
        return capitales;
    }
    
    /*Metodo que devuelve si el jugador ha cumplido con su mision en la modalidad 
     de mision secreta*/
    protected boolean comprobarObjetivoMision(Jugador j)
    {             
        if (j.getCartaMision().getNombre().equals("24Territorios"))
        {
            if (j.getTerritorios().size() == 24)
                return true;
            else
                return false;
        }
        else if (j.getCartaMision().getNombre().equals("18Territorios"))
        {
            boolean territorioConMenosDeDosEjercitos = false;
            if (j.getTerritorios().size() == 18)
            {
                for (int i=0; i<j.getTerritorios().size(); i++)
                {
                    if (j.getTerritorios().get(i).getNumEjercitos()<2)
                    {
                        territorioConMenosDeDosEjercitos = true;
                        break;
                    }
                }
                if (!territorioConMenosDeDosEjercitos)
                    return true;
            }                
        }
        else if (j.getCartaMision().getTipo().equals("ConquistarContinentes"))
        {
            StringTokenizer st = new StringTokenizer(j.getCartaMision().getNombre(), "-");
            
            while (st.hasMoreTokens())
            {                
                if (!continentePerteneceJugador(tablero.buscarContinente(st.nextToken()), j))
                    return false;
            }
            return true;            
        }/*
        else if (j.getCartaMision().getNombre().equals("AmericaNorte-Australasia"))
        {            
            Continente c = tablero.buscarContinente("AmericaNorte");
            if (continentePerteneceJugador(c, j))         
            {
                c = tablero.buscarContinente("Australasia");
                if (continentePerteneceJugador(c, j))
                    return true;
            }
        }*/        
        else if (j.getCartaMision().getTipo().equals("Destruir"))
        {
            if (buscarJugadorPorColor(j.getCartaMision().getNombre().toString()).
                    getTerritorios().size() == 0)
                return true;
        }
        
        
        return false;
    }   
    
    protected boolean continentePerteneceJugador (Continente c, Jugador j)
    {
        for (int i=0; i<c.getTerritorio().size(); i++)
        {
            if (c.getTerritorio().get(i).getJugador() != j)                            
                return false;            
        }
        
        return true;
    }
    
    protected Jugador buscarJugadorPorColor(String color)
    {
        for (int i=0; i<mJugador.size(); i++)
        {
            System.out.println("Color Jugador: "+mJugador.get(i).getColor().toString()+" Color Parametro: "+color);
            if (mJugador.get(i).getColor().toString().equals(color))
                return mJugador.get(i);
        }
        return null;        
    }
    
    
    public void guardarPartida()
    {
        try 
        {
            ObjectOutputStream streamGuardar = new ObjectOutputStream(
                                               new FileOutputStream("PartidaGuardada.rsk"));
            streamGuardar.writeObject(this);
        }
        catch (Exception e) 
        {
            System.out.println(e.getMessage());
        }
    }   
}

