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

using namespace std;


void Debut()
{
    srand(time(0) ^ SEED);
}


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

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

    // Si aucune tourelle n'est construite
    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_CONSTRUCTION);
    }
    else
    {
        if (Bernouilli(3./ 5, 2. / 5))
            Creer_Sorciers(MAGIE / COUT_SORCIER);
        else
        {
            vector<Evenement> candidats;
            double total = 0;

            // Calculer la probabilité de choisir une tourelle
            for (int index = 0; index < tourelles.size(); index++)
            {
                candidats.push_back(Evenement(index,
                    (double) Distance_Carre(tourelles[index].pos, Base(ID))
                ));
                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 (Constructible(alentours[index]) && 
                       !adjacent[alentours[index].x][alentours[index].y])
                        eligible.push_back(alentours[index]);
                if (eligible.empty())
                    Creer_Sorciers(MAGIE / COUT_SORCIER);
                else
                {
                    Position position = eligible[Aleatoire(0, eligible.size() - 1)];
                    int portee;
                    
                    for (portee = 4; COUT_AMELIORATION(portee) > MAGIE
                                  && portee > PORTEE_TOURELLE; portee--);
                    Creer_Tourelle(position, portee);
                }
            }
            Creer_Sorciers(MAGIE / COUT_SORCIER);
        }
    }
}
