/*
 *
 *  Prologin 2017 - Lundi 1er mai 2017
 *
 *
 *  Champion final
 *    Tacos XXVII v2 - Esteban CHRISTIAN (21.11.2001)
 *
 *
 *  Ce fichier contient les fonctions qui seront utilisees par le fichier prologin.cc
 *
 */

#include "prologin.hh"
#include "fonctions.h"
#include <vector>
#include <iostream>

using namespace std;

/*
 * Cherche la plus grosse region
 *
 * Si chercheOr est a true les regions sont triees par gain d'or
 * Sinon par gain de catalyseurs
 */
position grosseRegion(bool chercheOr)
{
    position max;
    max.ligne = INFINI;
    int maxi = -INFINI;
    for(int i = 0; i < TAILLE_ETABLI; i++)
    {
        for(int j = 0; j < TAILLE_ETABLI; j++)
        {
            position iPos = makepos(i, j);
            int iTaille = taille_region(iPos, monId);

            int iVal;
            if(chercheOr)
                iVal = quantite_transmutation_or(iTaille);
            else
                iVal = quantite_transmutation_catalyseur(iTaille);

            if(maxi < iVal && iVal >= 3)
            {
                maxi = iVal;
                max = iPos;
            }
        }
    }

    return max;
}

/*
 * Compte le nombre de case du type 'type' dans le plateau du joueur 'id'
 */
int nbCases(case_type type, int id)
{
    int nb = 0;

    for(int i = 0; i < TAILLE_ETABLI; i++)
    {
        for(int j = 0; j < TAILLE_ETABLI; j++)
        {
            if(type_case(makepos(i, j), autreId) == type)
            {
                nb++;
            }
        }
    }

    return nb;
}

/*
 * Donne un echantillon a l'adversaire
 */
void donnerMerde()
{
    case_type min;
    int mini = INFINI;

    for(int type = PLOMB; type < MERCURE; type++)
    {
        int cpt = nbCases((case_type) type, autreId);
        if(cpt < mini && cpt > 0)
        {
            mini = cpt;
            min = (case_type) type;
        }
    }

    echantillon t = echantillon_tour();
    if(nbCases(t.element1, autreId) > nbCases(t.element2, autreId))
    {
        t.element1 = min;
    }
    else
    {
        t.element2 = min;
    }

    donner_echantillon(t);
}

/*
 * Pose l'echantillon du tour son son plateau
 */
void poserEchantillon()
{
    if(tour_actuel() <= 2) // Poser au centre au premier coup
    {
        placer_echantillon(makepos(3, 3), makepos(4, 3));
    }

    while(!a_pose_echantillon())
    {
        vector<position_echantillon> positionsPossibles = placements_possible_echantillon(echantillon_tour(), monId);

        position_echantillon maxPosEch;
        int maxi = -INFINI;
        for(int i = 0; i < positionsPossibles.size(); i++) // Cherche un endroit pour pose directe
        {
            position_echantillon iPosEch = positionsPossibles[i];
            if(placer_echantillon(iPosEch.pos1, iPosEch.pos2) == OK)
            {
                int iVal = quantite_transmutation_or(taille_region(iPosEch.pos1, monId))
                    + quantite_transmutation_or(taille_region(iPosEch.pos2, monId));

                if(maxi < iVal)
                {
                    maxPosEch = iPosEch;
                    maxi = iVal;
                }

                annuler();
            }
        }

        if(maxi != -INFINI)
        {
            placer_echantillon(maxPosEch.pos1, maxPosEch.pos2); // Echantillon pose
            return;
        }

        position maxPos;
        maxi = -INFINI;

        for(int i = 0; i < TAILLE_ETABLI; i++) // Cherche la plus grande region pour coller l'echantillon
        {
            for(int j = 0; j < TAILLE_ETABLI; j++)
            {
                position iPos = makepos(i, j);
                int iVal = taille_region(iPos, monId);

                if((type_case(iPos, monId) == echantillon_tour().element1
                || type_case(iPos, monId) == echantillon_tour().element2)
                && maxi < iVal)
                {
                    maxPos = iPos;
                    maxi = iVal;
                }
            }
        }

        vector<position> posReg = positions_region(maxPos, monId);

        if(maxi == -INFINI) // On peut poser l'echantillon n'importe ou
        {
            posReg.clear();
            for(int i = 0; i < TAILLE_ETABLI; i++)
            {
                for(int j = 0; j < TAILLE_ETABLI; j++)
                {
                    posReg.push_back(makepos(i, j));
                }
            }
        }

        position minPos;
        int mini = INFINI;
        for(int limite = 3; limite >= 1 && mini == INFINI; limite--) // Chercher la region qui empeche la pose
        {
            for(int i = 0; i < posReg.size(); i++)
            {
                for(int j = 0; j < 5; j++)
                {
                    position iPos = makepos(posReg[i].ligne + DEPS[j][0], posReg[i].colonne + DEPS[j][1]);

                    int iVal = taille_region(iPos, monId);
                    if(iVal < mini && iVal > 0 && iVal >= limite)
                    {
                        minPos = iPos;
                        mini = iVal;
                    }
                }
            }

            if(mini != INFINI)
            {
                transmuter(minPos); // LA transmuter
            }
        }
    }
}

/*
 * Utilise les catalyseurs de maniere intelligeante
 */
void utiliserCatalyseurs()
{
    int nbCata = nombre_catalyseurs();
    for(int iCata = 0; iCata < nbCata; iCata++)
    {
        position maxPos;
        case_type maxType;
        int maxId;
        int maxi = -INFINI;

        int iId = autreId;
        for(int __i = 0; __i < 2; __i++) // Poser sur son plateau ou celui de l'adversaire
        {
            for(int i = 0; i < TAILLE_ETABLI; i++)
            {
                for(int j = 0; j < TAILLE_ETABLI; j++)
                {
                    for(int k = PLOMB; k < MERCURE; k++) // Tester toutes les catalysers possibles
                    {
                        position p = makepos(i, j);
                        case_type c = (case_type) k;

                        int avant = -INFINI;
                        if(iId == monId)
                        {
                            for(int dep = 0; dep < 4; dep++)
                            {
                                position posDep = makepos(p.ligne + DEPS[dep][0], p.colonne + DEPS[dep][1]);
                                if(type_case(posDep, iId) == c)
                                    avant = max(avant, quantite_transmutation_or(taille_region(posDep, iId)));
                            }
                        }
                        else
                            avant = quantite_transmutation_or(taille_region(p, iId));

                        case_type caseAvant = type_case(p, iId);

                        if(catalyser(p, iId, c) == OK)
                        {
                            int apres = -INFINI;
                            if(iId != monId)
                            {
                                for(int dep = 0; dep < 4; dep++)
                                {
                                    position posDep = makepos(p.ligne + DEPS[dep][0], p.colonne + DEPS[dep][1]);
                                    if(type_case(posDep, iId) == caseAvant)
                                        apres = max(apres, quantite_transmutation_or(taille_region(posDep, iId)));
                                }
                            }
                            else
                                apres = quantite_transmutation_or(taille_region(p, iId));

                            annuler();

                            int iScore = -INFINI; // Comparer avant et apres la catalyse
                            if(iId == monId && avant != -INFINI && apres != -INFINI)
                                iScore = apres - avant;
                            else if(avant != -INFINI && apres != -INFINI)
                                iScore = avant - apres;

                            if(maxi < iScore)
                            {
                                maxPos = p;
                                maxType = c;
                                maxId = iId;
                                maxi = iScore;
                            }
                        }
                    }
                }
            }
            iId = monId;
        }

        catalyser(maxPos, maxId, maxType); // Faire la meilleure catalyse
    }
}
