#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "prologin.h"
#include "enumere.h"
#include "eval.h"
#include "utils.h"

/*
 *
 * Esteban CHRISTIANN - Prologin 2018
 *
 * Enumerer le plus de coups possibles puis choisir le "meilleur"
 *
 * Pour cela on fait pour chaque agent
 *
 * -  Calculer le score de tous les endroits possibles sur le plateu
 *
 *    - BFS qui part de tous les aliens (visibles ou non) et qui attribue un
 *      score maximal a chaque case en fonction de la valeur de l'alien, de la
 *      distance, de si l'adversaire a un agent dessus...
 *
 *    - Enumeration de tous les coups possible avec une fonction recursive
 *      (Backtract de profondeur 8 max) et qui se coupe automatiquement au bout
 *      de 1/6 de seconde de recherche pour eviter de faire un timeout et
 *      calcule et maintient les meilleures actions
 *
 *    - Application des actions
 *
 */

void partie_init(void)
{
}

void jouer_tour(void)
{
    clockd = clock();
    climite = clockd;

    for(agent_simul = 0; agent_simul < NB_AGENTS; agent_simul++)
    {
        currclock = clockd;
        skip = 0;
        climite += LIMITE_PAR_AGENT;

        calc_score_pos();

        position posagent = position_agent(moi(), agent_simul);
        if(alien_sur_case(posagent) && info_alien(posagent).points_capture > 0)
        {
            for(int i = 0; i < 4; i++)
            {
                struct position pdir;
                pdir.ligne   = posagent.ligne   + DEPLACEMENT[i].ligne;
                pdir.colonne = posagent.colonne + DEPLACEMENT[i].colonne;

                struct position pdir2;
                pdir2.ligne   = pdir.ligne   + DEPLACEMENT[i].ligne;
                pdir2.colonne = pdir.colonne + DEPLACEMENT[i].colonne;

                struct position pinv;
                pinv.ligne   = posagent.ligne   - DEPLACEMENT[i].ligne;
                pinv.colonne = posagent.colonne - DEPLACEMENT[i].colonne;

                if(agent_sur_case(pdir) == adversaire()
                && agent_sur_case(pinv) != adversaire()
                && type_case(pdir2) == LIBRE)
                    if(pousser(agent_simul, i) != OK)
                    {}
            }
        }
        else
        {
            act_prof = -1;
            best_score = -1e10;
            best_prof = -1;

            enumere_coups();

            for(int i = 0; i < best_prof; i++)
            {
                struct action_hist* iact = best_stack + i;

                switch(iact->atype)
                {
                    case ACTION_DEPLACER:
                        if(deplacer(iact->id_agent, iact->dir) != OK)
                        {
                        }
                        break;

                    case ACTION_GLISSER:
                        if(glisser(iact->id_agent, iact->dir) != OK)
                        {
                        }

                        break;
                    case ACTION_POUSSER:
                        if(pousser(iact->id_agent, iact->dir) != OK)
                        {
                        }

                        break;
                }
            }
        }
    }
}

void partie_fin(void)
{
}

