import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Jugador {
    public static final int HUMANO = 1;
    public static final int ROBOT = 2;
    public static final String HUMANO_STRING = "Humano";
    public static final String ROBOT_STRING = "Robot";
    private final int tipo;
    private final Mesa mesa;
    private final List<Ficha> fichas;
    // Era un set pero no encontre una manera eficiente
    // de obtener un elemento al azar.
    public Jugador(int tipo, Mesa mesa) {
        this.tipo = tipo;
        this.mesa = mesa;
        fichas = new LinkedList<>();
    }
    public boolean isHuman() {
        return (tipo == HUMANO);
    }
    private String tipoToString() {
        if (tipo == HUMANO) {
            return HUMANO_STRING;
        } else {
            return ROBOT_STRING;
        }
    }
    private Tirada preguntarTiradaAHumano(ArrayList<Tirada> tiradas) {
        return tiradas.get(Pregunta.numEnRango("¿Que tirada juegas?",
                0, tiradas.size() - 1));
    }
    /*
    private Tirada preguntarTiradaARobot(ArrayList<Tirada> tiradas) {
        Duerme.duermeUnRatito();
        Tirada tiradaARealizar = tiradas.get(Azar.numeroAlAzar(tiradas.size()));
        System.out.print(Colores.color(Partida.COLOR_JUGADA));
        System.out.println("Tira: " + tiradaARealizar);
        return tiradaARealizar;
    }
     */
    private Tirada preguntarTiradaARobot(ArrayList<Tirada> tiradas) {
        Tirada tiradaARealizar = null;
        int max_heuristica = -1;
        Duerme.duermeUnRatito();
        // Tirada tiradaARealizar = tiradas.get(Azar.numeroAlAzar(tiradas.size()));
        for (Tirada t : tiradas) {
            int heuristica = 0;
            Ficha ficha = t.getFicha();
            if (ficha.esUnDoble()) {
                heuristica += 10;
            }
            heuristica += cuantasFichasVeoConNum(ficha.getA());
            heuristica += cuantasFichasVeoConNum(ficha.getB());
            System.out.print(" | h(" + t + ") = " + heuristica);
            if (heuristica > max_heuristica) {
                max_heuristica = heuristica;
                tiradaARealizar = t;
            }
        }
        System.out.println();
        System.out.print(Colores.color(Partida.COLOR_JUGADA));
        System.out.println("Tira: " + tiradaARealizar);
        return tiradaARealizar;
    }
    public Tirada preguntarTiradaAJugador(ArrayList<Tirada> tiradas) {
        switch (tipo) {
            case HUMANO:
                return preguntarTiradaAHumano(tiradas);
            case ROBOT:
            default:
                return preguntarTiradaARobot(tiradas);
        }
    }
    public Ficha getDobleMasAlto() {
        Ficha dobleMasAlto = null;
        for (Ficha f : fichas) {
            if (f.esUnDoble() && ((dobleMasAlto == null)
                    || (f.peso() > dobleMasAlto.peso()))) {
                dobleMasAlto = f;
            }
        }
        return dobleMasAlto;
    }
    public int getNumFichas() {
        return fichas.size();
    }
    public Ficha getFichaAlAzar() {
        // List en lugar de set para poder hacer get()
        return fichas.get(Azar.numeroAlAzar(fichas.size()));
    }
    public boolean tiraFicha(Ficha ficha) {
        return fichas.remove(ficha);
    }
    public void pillaFicha(Ficha ficha) {
        fichas.add(ficha);
    }
    public ArrayList<Tirada> posiblesTiradas() {
        ArrayList<Tirada> tiradas = new ArrayList<>();
        int izq = mesa.getExtremoIzquierdo();
        int der = mesa.getExtremoDerecho();
        for (Ficha f : fichas) {
            if ((f.getA() == izq) || (f.getB() == izq)) {
                tiradas.add(new Tirada(f, ExtremoMesa.IZQUIERDO));
            }
            if ((f.getA() == der) || (f.getB() == der)) {
                tiradas.add(new Tirada(f, ExtremoMesa.DERECHO));
            }
        }
        return tiradas;
    }
    public int cuantasFichasConNum(int n) {
        int cuantas = 0;
        for (Ficha f : fichas) {
            if ((f.getA() == n) || (f.getB() == n)) {
                cuantas++;
            }
        }
        return cuantas;
    }
    public int cuantasFichasVeoConNum(int n) {
        return (cuantasFichasConNum(n) + mesa.cuantasFichasConNum(n));
    }
    public int cuantasFichasVeoConNumDeExtremo() {
        return (cuantasFichasVeoConNum(mesa.getExtremoIzquierdo())
                + cuantasFichasVeoConNum(mesa.getExtremoDerecho()));
    }
    @Override
    public String toString() {
        String s = "";
        for (Ficha f : fichas) {
            s += f;
        }
        s += tipoToString();
        return s;
    }
}
