///
// This file has been generated, if you wish to
// modify it in a permanent way, please refer
// to the script file : gen/generator_c.rb
//

#include "interface.hh"
#include <cstdlib>

template<typename Lang, typename Cxx>
Cxx lang2cxx(Lang in)
{
  return in;
}

template<>
std::string lang2cxx<char*, std::string>(char* in)
{
  return in;
}

template<typename Lang, typename Lang_array, typename Cxx>
std::vector<Cxx> lang2cxx_array(Lang_array in)
{
  std::vector<Cxx> out(in.length);
  for (size_t i = 0; i < in.length; ++i)
    out[i] = lang2cxx<Lang, Cxx>(in.datas[i]);
  return out;
}

template<typename Lang, typename Cxx>
Lang cxx2lang(Cxx in)
{
  return in;
}

template<>
char* cxx2lang<char*, std::string>(std::string in)
{
  size_t l = in.length();
  char* out = (char *) malloc(l + 1);
  for (int i = 0; i < l; i++) out[i] = in[i];
  out[l] = 0;
  return out;
}

template<typename Lang, typename Lang_array, typename Cxx>
Lang_array cxx2lang_array(const std::vector<Cxx>& in)
{
  Lang_array out = { NULL, in.size() };
  out.datas = (Lang *)malloc((out.length) * sizeof(Lang));
  for (int i = 0; i < out.length; ++i)
    out.datas[i] = cxx2lang<Lang, Cxx>(in[i]);
  return out;
}
///
// Position sur la carte, donnée par deux coordonnées.
//
template<>
__internal__cxx__position lang2cxx<position, __internal__cxx__position>(position in)
{
  __internal__cxx__position out;
  out.x = lang2cxx<int, int >(in.x);
  out.y = lang2cxx<int, int >(in.y);
  return out;
}

template<>
position cxx2lang<position, __internal__cxx__position>(__internal__cxx__position in)
{
  position out;
  out.x = cxx2lang<int, int >(in.x);
  out.y = cxx2lang<int, int >(in.y);
  return out;
}


///
// Représente un lien existant.
//
template<>
__internal__cxx__lien lang2cxx<lien, __internal__cxx__lien>(lien in)
{
  __internal__cxx__lien out;
  out.extr1 = lang2cxx<position, __internal__cxx__position >(in.extr1);
  out.extr2 = lang2cxx<position, __internal__cxx__position >(in.extr2);
  out.joueur_l = lang2cxx<int, int >(in.joueur_l);
  return out;
}

template<>
lien cxx2lang<lien, __internal__cxx__lien>(__internal__cxx__lien in)
{
  lien out;
  out.extr1 = cxx2lang<position, __internal__cxx__position >(in.extr1);
  out.extr2 = cxx2lang<position, __internal__cxx__position >(in.extr2);
  out.joueur_l = cxx2lang<int, int >(in.joueur_l);
  return out;
}


///
// Représente un champ de contrôle existant.
//
template<>
__internal__cxx__champ lang2cxx<champ, __internal__cxx__champ>(champ in)
{
  __internal__cxx__champ out;
  out.som1 = lang2cxx<position, __internal__cxx__position >(in.som1);
  out.som2 = lang2cxx<position, __internal__cxx__position >(in.som2);
  out.som3 = lang2cxx<position, __internal__cxx__position >(in.som3);
  out.joueur_c = lang2cxx<int, int >(in.joueur_c);
  return out;
}

template<>
champ cxx2lang<champ, __internal__cxx__champ>(__internal__cxx__champ in)
{
  champ out;
  out.som1 = cxx2lang<position, __internal__cxx__position >(in.som1);
  out.som2 = cxx2lang<position, __internal__cxx__position >(in.som2);
  out.som3 = cxx2lang<position, __internal__cxx__position >(in.som3);
  out.joueur_c = cxx2lang<int, int >(in.joueur_c);
  return out;
}


extern "C" {
///
// Déplace votre agent sur la case passée en argument.
//
erreur deplacer(position dest)
{
  return cxx2lang<erreur, erreur >(api_deplacer(lang2cxx<position, __internal__cxx__position >(dest)));
}


///
// Utilise un turbo.
//
erreur utiliser_turbo(void)
{
  return cxx2lang<erreur, erreur >(api_utiliser_turbo());
}


///
// Capture le portail où est positionné votre agent.
//
erreur capturer(void)
{
  return cxx2lang<erreur, erreur >(api_capturer());
}


///
// Crée un lien entre le portail où se trouve votre agent et le portail de destination donné en argument.
//
erreur lier(position portail)
{
  return cxx2lang<erreur, erreur >(api_lier(lang2cxx<position, __internal__cxx__position >(portail)));
}


///
// Neutralise le portail où se trouve votre agent.
//
erreur neutraliser(void)
{
  return cxx2lang<erreur, erreur >(api_neutraliser());
}


///
// Ajoute un bouclier au portail sur lequel se trouve votre agent.
//
erreur ajouter_bouclier(void)
{
  return cxx2lang<erreur, erreur >(api_ajouter_bouclier());
}


///
// Renvoie la liste de tous les liens présents.
//
lien_array liste_liens(void)
{
  return cxx2lang_array<lien, lien_array, __internal__cxx__lien >(api_liste_liens());
}


///
// Renvoie la liste de tous les champs de contrôle.
//
champ_array liste_champs(void)
{
  return cxx2lang_array<champ, champ_array, __internal__cxx__champ >(api_liste_champs());
}


///
// Renvoie la liste de tous les portails de la carte.
//
position_array liste_portails(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_liste_portails());
}


///
// Renvoie la liste de tous les liens existants qui croisent un segment, entravant la création d'un lien.
//
lien_array liens_bloquants(position ext1, position ext2)
{
  return cxx2lang_array<lien, lien_array, __internal__cxx__lien >(api_liens_bloquants(lang2cxx<position, __internal__cxx__position >(ext1), lang2cxx<position, __internal__cxx__position >(ext2)));
}


///
// Prend les positions de deux portails, et renvoie un booléen indiquant s'ils sont reliés. Le résultat est `false` lorsque l'une des deux positions ne repère pas un portail.
//
bool lien_existe(position ext1, position ext2)
{
  return cxx2lang<bool, bool >(api_lien_existe(lang2cxx<position, __internal__cxx__position >(ext1), lang2cxx<position, __internal__cxx__position >(ext2)));
}


///
// Renvoie un booléen indiquant si les 3 positions repèrent bien 3 portails tous reliés entre eux.
//
bool champ_existe(position som1, position som2, position som3)
{
  return cxx2lang<bool, bool >(api_champ_existe(lang2cxx<position, __internal__cxx__position >(som1), lang2cxx<position, __internal__cxx__position >(som2), lang2cxx<position, __internal__cxx__position >(som3)));
}


///
// Renvoie un booléen indiquant si la case ``pos`` se trouve dans un champ.
//
bool case_dans_champ(position pos)
{
  return cxx2lang<bool, bool >(api_case_dans_champ(lang2cxx<position, __internal__cxx__position >(pos)));
}


///
// Renvoie la liste des champs à l'intérieur desquels ``pos`` se trouve. Si la case est un portail, le résultat de ``case_champs`` sera disjoint de celui de ``champs_incidents_portail``.
//
champ_array case_champs(position pos)
{
  return cxx2lang_array<champ, champ_array, __internal__cxx__champ >(api_case_champs(lang2cxx<position, __internal__cxx__position >(pos)));
}


///
// Renvoie le numéro du joueur correspondant au portail donné, -1 si le portail est neutre, -2 si la case n'est pas un portail. Vous pouvez utiliser cette fonction pour vérifier qu'une case donnée est bien un portail.
//
int portail_joueur(position portail)
{
  return cxx2lang<int, int >(api_portail_joueur(lang2cxx<position, __internal__cxx__position >(portail)));
}


///
// Renvoie le nombre de boucliers présents sur un portail (-2 si la case n'est pas un portail).
//
int portail_boucliers(position portail)
{
  return cxx2lang<int, int >(api_portail_boucliers(lang2cxx<position, __internal__cxx__position >(portail)));
}


///
// Renvoie la liste de tous les liens dont le portail donné est une extrémité.
//
lien_array liens_incidents_portail(position portail)
{
  return cxx2lang_array<lien, lien_array, __internal__cxx__lien >(api_liens_incidents_portail(lang2cxx<position, __internal__cxx__position >(portail)));
}


///
// Renvoie la liste de tous les champs dont le portail donné est un sommet.
//
champ_array champs_incidents_portail(position portail)
{
  return cxx2lang_array<champ, champ_array, __internal__cxx__champ >(api_champs_incidents_portail(lang2cxx<position, __internal__cxx__position >(portail)));
}


///
// Renvoie la liste de tous les champs dont le lien donné est un côté. Si le segment n'est pas un lien présent, renvoie la liste de tous les champs que la création du lien ferait apparaître.
//
champ_array champs_incidents_segment(position ext1, position ext2)
{
  return cxx2lang_array<champ, champ_array, __internal__cxx__champ >(api_champs_incidents_segment(lang2cxx<position, __internal__cxx__position >(ext1), lang2cxx<position, __internal__cxx__position >(ext2)));
}


///
// Renvoie la liste des portails capturés par votre adversaire au dernier tour.
//
position_array hist_portails_captures(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_portails_captures());
}


///
// Renvoie la liste des portails neutralisés par votre adversaire au dernier tour.
//
position_array hist_portails_neutralises(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_portails_neutralises());
}


///
// Renvoie la liste des liens créés par votre adversaire au dernier tour.
//
lien_array hist_liens_crees(void)
{
  return cxx2lang_array<lien, lien_array, __internal__cxx__lien >(api_hist_liens_crees());
}


///
// Renvoie la liste des champs créés par votre adversaire au dernier tour.
//
champ_array hist_champs_crees(void)
{
  return cxx2lang_array<champ, champ_array, __internal__cxx__champ >(api_hist_champs_crees());
}


///
// Renvoie la liste des positions où votre adversaire a ajouté des boucliers au dernier tour.
//
position_array hist_boucliers_ajoutes(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_boucliers_ajoutes());
}


///
// Renvoie la distance de Manhattan entre deux positions.
//
int distance(position pos1, position pos2)
{
  return cxx2lang<int, int >(api_distance(lang2cxx<position, __internal__cxx__position >(pos1), lang2cxx<position, __internal__cxx__position >(pos2)));
}


///
// Renvoie le nombre de points que rapporte(rait) chaque tour un champ existant ou hypothétique.
//
int score_triangle(position som1, position som2, position som3)
{
  return cxx2lang<int, int >(api_score_triangle(lang2cxx<position, __internal__cxx__position >(som1), lang2cxx<position, __internal__cxx__position >(som2), lang2cxx<position, __internal__cxx__position >(som3)));
}


///
// Indique si deux segments se croisent. Cette fonction correspond exactement à la condition d'interférence entre liens, c'est-à-dire qu'elle renvoie ``false`` si l'intersection est une extrémité des deux segments.
//
bool intersection_segments(position a1, position a2, position b1, position b2)
{
  return cxx2lang<bool, bool >(api_intersection_segments(lang2cxx<position, __internal__cxx__position >(a1), lang2cxx<position, __internal__cxx__position >(a2), lang2cxx<position, __internal__cxx__position >(b1), lang2cxx<position, __internal__cxx__position >(b2)));
}


///
// Indique si un point se trouve à l'intérieur d'un triangle. Le critère coïncide avec celui de ``case_champs``.
//
bool point_dans_triangle(position p, position som1, position som2, position som3)
{
  return cxx2lang<bool, bool >(api_point_dans_triangle(lang2cxx<position, __internal__cxx__position >(p), lang2cxx<position, __internal__cxx__position >(som1), lang2cxx<position, __internal__cxx__position >(som2), lang2cxx<position, __internal__cxx__position >(som3)));
}


///
// Renvoie votre numéro de joueur.
//
int moi(void)
{
  return cxx2lang<int, int >(api_moi());
}


///
// Renvoie le numéro de votre adversaire.
//
int adversaire(void)
{
  return cxx2lang<int, int >(api_adversaire());
}


///
// Indique la position de l'agent du joueur désigné par le numéro ``id_joueur``.
//
position position_agent(int id_joueur)
{
  return cxx2lang<position, __internal__cxx__position >(api_position_agent(lang2cxx<int, int >(id_joueur)));
}


///
// Indique votre nombre de points d'actions restants pour ce tour-ci.
//
int points_action(void)
{
  return cxx2lang<int, int >(api_points_action());
}


///
// Indique votre nombre de points de déplacement restants pour ce tour-ci.
//
int points_deplacement(void)
{
  return cxx2lang<int, int >(api_points_deplacement());
}


///
// Renvoie le score du joueur désigné par le numéro ``id_joueur``.
//
int score(int id_joueur)
{
  return cxx2lang<int, int >(api_score(lang2cxx<int, int >(id_joueur)));
}


///
// Renvoie le numéro du tour actuel.
//
int tour_actuel(void)
{
  return cxx2lang<int, int >(api_tour_actuel());
}


///
// Annule la dernière action. Renvoie ``false`` quand il n'y a pas d'action à annuler ce tour-ci.
//
bool annuler(void)
{
  return cxx2lang<bool, bool >(api_annuler());
}


///
// Affiche le contenu d'une valeur de type erreur
//
void afficher_erreur(erreur v)
{
  api_afficher_erreur(lang2cxx<erreur, erreur >(v));
}


///
// Affiche le contenu d'une valeur de type position
//
void afficher_position(position v)
{
  api_afficher_position(lang2cxx<position, __internal__cxx__position >(v));
}


///
// Affiche le contenu d'une valeur de type lien
//
void afficher_lien(lien v)
{
  api_afficher_lien(lang2cxx<lien, __internal__cxx__lien >(v));
}


///
// Affiche le contenu d'une valeur de type champ
//
void afficher_champ(champ v)
{
  api_afficher_champ(lang2cxx<champ, __internal__cxx__champ >(v));
}


}
