#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
#include "api.hh"
#include "alea.hh"
#include "misc.hh"

using namespace std;


vector<Position> objectifs;

void Debut()
{
    srand(time(0) ^ SEED);
    
    // Déterminer les cases objectif de la partie
    for (int x = 0; x < TAILLE_TERRAIN; x++)
    {
        for (int y = 0; y < TAILLE_TERRAIN; y++)
        {
            if (Case(x, y) == CASE_FONTAINE
            ||  Case(x, y) == CASE_ARTEFACT
            ||  (Case(x, y) == CASE_BASE && (Position) {x, y} != Base(ID)))
                objectifs.push_back((Position) {x, y});
        }
    }
    sort(objectifs.begin(), objectifs.end());
}


void Construction()
{
    vector<Tourelle> tourelles = Liste_Tourelles(ID);
    bool adjacent[TAILLE_TERRAIN][TAILLE_TERRAIN] = {false};

    // Déterminer les cases adjacentes à une tourelle
    for (int index = 0; index < tourelles.size(); index++)
    {
        vector<Position> voisins = Zone(tourelles[index].pos, );
        
        for (int voisin = 0; voisin < voisins.size(); voisin++)
            adjacent[voisins[voisin].x][voisins[voisin].y] = true;
    }

    if (tourelles.empty())
    {
        vector<Position> alentours = Alentours(Base(ID), PORTEE_CONSTRUCTION);
        vector<Position> eligible;
        
        // Déterminer la liste des cases libres aux alentours de la base
        for (int index = 0; index < alentours.size(); index++)
            if (Constructible(alentours[index]))
                eligible.push_back(alentours[index]);
        if (eligible.empty())
            Creer_Sorciers(MAGIE / COUT_SORCIER);
        else
            Creer_Tourelle(eligible[Aleatoire(0, eligible.size())], PORTEE_TOURELLE);
    }
    else
    {
        vector<Evenement> candidats;
        double total = 0;

        // Calculer la probabilité de choisir une tourelle
        for (int index = 0; index < tourelles.size(); index++)
        {
            if (Bernouilli(3. / 5, 2. / 5))
                candidats.push_back(Evenement(index,
                    100. / Distance_Carre(tourelles[index].pos,
                           Plus_Proche(objectifs, tourelles[index].pos))
                    // Votre formule de calcul ici
                ));
            else
                candidats.push_back(Evenement(index,
                    100. / Distance_Carre(tourelles[index].pos, Base(ID))
                    // Votre formule de calcul ici
                ));
            total += candidats.back().probabilite;
        }
        for (int index = 0; index < tourelles.size(); index++)
            candidats[index].probabilite /= total;

        while (MAGIE >= COUT_TOURELLE)
        {
            int choix = Choisir(candidats);
            vector<Position> alentours = Alentours(tourelles[choix].pos, 
                                                   PORTEE_CONSTRUCTION);
            vector<Position> eligible;

            // Déterminer la liste des cases libres aux alentours de la tourelle
            for (int index = 0; index < alentours.size(); index++)
                if (!adjacent[alentours[index].x][alentours[index].y]
                &&  Constructible(alentours[index]))
                    eligible.push_back(alentours[index]);
            if (eligible.empty())
                Creer_Sorciers(MAGIE / COUT_SORCIER);
            else
            {
                Position position = eligible[Aleatoire(0, eligible.size() - 1)];
                int portee;
                
                // Choisir une case pas trop proche de la base
                for (int index = 0; index < eligible.size(); index++)
                    if (Distance_Carre(eligible[index], Base(ID))
                     >  Distance_Carre(position, Base(ID))
                    &&  Bernouilli(1. / 3, 2. / 3))
                        position = eligible[index];
                
                for (portee = 5; COUT_AMELIORATION(portee) > MAGIE
                              && portee > PORTEE_TOURELLE; portee--);
                Creer_Tourelle(position, portee);
            }
        }
        Creer_Sorciers(MAGIE / COUT_SORCIER);
    }
}

void Deplacement()
{
}

void Tirs()
{
}

void Siege()
{
}

void Fin()
{
}

