#ifndef MESS_INCLUDED
#define MESS_INCLUDED

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "prologin.h"


/* ///////////////////////////////////////////////////////////////////////// */

#define $P(x,y)                     ((P){.ligne=(x),.colonne=(y)})
typedef position                    P;

#define $E(a,b)                     ((E){.element1=(a),.element2=(b)})
typedef echantillon                 E;

#define $PE(u,v)                    ((PE){.pos1=(u),.pos2=(v)})
typedef position_echantillon        PE;
typedef position_echantillon_array  PE_A;

/* Humble correcteur, passe ton chemin. Ici s'arrête l'innocence ... */

#define POUR_CHAQUE_PLACEMENT(p,x,s)                                                                    \
    for(PE_A $##p=placements_possible_echantillon((x),(s));$##p.length;free($##p.datas),$##p.length=0)  \
        for(PE p;$##p.length>0&&((p=$##p.datas[$##p.length---1]),1);)

#define POUR_CHAQUE_POSITION(p)                                                                         \
    for(P p=$P(0,0);p.ligne<6;p.ligne+=!!(p.colonne==5),p.colonne=(p.colonne+1)%6)

#define POUR_CHAQUE_VOISIN(v, p)                                                                        \
    for(int $##v=0,$x##v=0,$y##v=1;$##v<4;$##v++,($x##v^=$y##v),($y##v=-($x##v^$y##v)),($x##v^=-$y##v)) \
        for(P v=$P(p.ligne+(($##v+=4),$x##v),p.colonne+$y##v);$##v>=4;$##v-=4)

/* ///////////////////////////////////////////////////////////////////////// */

typedef struct {
    PE  s;
    P   p, q;    

#define GAINS   3
    int gain[GAINS], element;
} Situation;

static bool
meilleure(Situation a, Situation b)
{
    for (int i = 0; i < GAINS; i++) {
        if (a.gain[i] > b.gain[i])
            return true;
        else if (a.gain[i] < b.gain[i])
            return false;
    }
    return true;
}

static int
min(int a, int b)
{
    return a < b ? a : b;
}

static int
max(int a, int b)
{
    return a > b ? a : b;
}

static int
valeur(P p, int s)
{
    switch (propriete_case_type(type_case(p,s))) {
        case TRANSMUTABLE_OR:
            return quantite_transmutation_or(taille_region(p, s));
        case TRANSMUTABLE_CATALYSEUR:
            return quantite_transmutation_catalyseur_or(taille_region(p, s));
        default:
            return 0;
    }
}

#define potentiel(p,s)  (max(valeur((p),(s)),0))


static bool
grille_vide(void)
{
    POUR_CHAQUE_POSITION(p)
        if (!est_vide(p, moi()))
            return false;
    return true;
}

/* ///////////////////////////////////////////////////////////////////////// */


#define THE_GAME    void jouer_tour     ()
                    void partie_init    (void)  {}
                    void partie_fin     (void)  {}

#endif /* MESS_INCLUDED */
