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

(*
** Taille de l’établi de travail (longueur et largeur)
*)
let taille_etabli = 6

(*
** Nombre de tours à jouer avant la fin de l’affrontement
*)
let nb_tours = 150

(*
** Taille de l’énumération ``case_type``
*)
let nb_type_cases = 6

(*
** Types de cases
*)
type case_type =
| Vide (* <- Case vide *)
| Plomb (* <- Plomb ; transmutable en or *)
| Fer (* <- Fer ; transmutable en or *)
| Cuivre (* <- Cuivre ; transmutable en or *)
| Soufre (* <- Soufre ; transmutable en catalyseur *)
| Mercure (* <- Mercure ; transmutable en catalyseur *)


(*
** Types de propriétés des éléments
*)
type element_propriete =
| Aucune (* <- Les cases vides ne contiennent pas d’élément, et n’ont donc aucune propriété *)
| Transmutable_or (* <- Élement transmutable en or *)
| Transmutable_catalyseur (* <- Élément transmutable en catalyseur *)


(*
** Erreurs possibles
*)
type erreur =
| Ok (* <- L’action a été exécutée avec succès *)
| Position_invalide (* <- La position spécifiée n’est pas sur l’établi *)
| Placement_invalide (* <- Les deux positions ne correspondent pas à des cases adjacentes *)
| Placement_impossible (* <- Les cases ciblées ne sont pas vides *)
| Placement_incorrect (* <- Un des deux éléments de l'échantillon doit être placé adjacent à un élément du même type déjà présent sur l'établi *)
| Case_vide (* <- La case ciblée est vide *)
| Echantillon_incomplet (* <- L’échantillon doit contenir deux éléments. *)
| Echantillon_invalide (* <- L’échantillon doit contenir au moins un des éléments de l’échantillon reçu auparavant *)
| Aucun_catalyseur (* <- Aucun catalyseur disponible *)
| Catalyse_invalide (* <- L'élément de destination ne peut pas être vide. *)
| Deja_pose (* <- L’échantillon a déjà été posé ce tour-ci *)
| Deja_donne (* <- L’échantillon a déjà été donné ce tour-ci *)


(*
** Types d’actions
*)
type action_type =
| Action_placer (* <- Action ``placer_echantillon`` *)
| Action_transmuter (* <- Action ``transmuter`` *)
| Action_catalyser (* <- Action ``catalyser`` *)
| Action_donner_echantillon (* <- Action ``donner_echantillon`` *)


(*
** Position sur la carte, donnée par deux coordonnées
*)
type position = (int * int)

(*
** Échantillon, défini par deux types d’éléments
*)
type echantillon = (case_type * case_type)

(*
** Position d’un échantillon, donnée par deux positions adjacentes
*)
type position_echantillon = (position * position)

(*
** Action représentée dans l’historique. L’action ``placer_echantillon`` utilise ``pos1`` et ``pos2``. L’action ``transmuter`` utilise ``pos1``. L’action ``catalyser`` utilise ``pos1``, ``id_apprenti`` et ``nouvelle_case``. L’action ``donner_echantillon`` n’est pas représentée dans l’historique, car ``echantillon_tour`` donne l’information.
*)
type action_hist = {
  atype : action_type ; (* <- Type de l’action *)
  pos1 : position ; (* <- Position, pour les actions placer (1er élément), transmuter et catalyser *)
  pos2 : position ; (* <- Position, pour l’action placer (2e élément) *)
  id_apprenti : int ; (* <- ID de l’apprenti, pour l’action catalyser *)
  nouvelle_case : case_type ; (* <- Élément pour l’action catalyser *)
}

(*
** Place l’échantillon du tour sur l’établi, avec les coordonnées de deux cases adjacentes.
*)
external placer_echantillon : position -> position -> erreur = "ml_placer_echantillon"
(*
** Provoque la transformation chimique de l’élément à la case ciblée, ainsi que tous les éléments adjacents du même type, ceux du même type adjacents à ces derniers, etc. Ils disparaissent alors tous dans leur transmutation en or ou en catalyseur.
*)
external transmuter : position -> erreur = "ml_transmuter"
(*
** Utilise un catalyseur sur la case ciblée de l'apprenti indiqué. Transforme l’ancien élément en l’élément indiqué.
*)
external catalyser : position -> int -> case_type -> erreur = "ml_catalyser"
(*
** Définit l’échantillon que l’adversaire recevra à son prochain tour.
*)
external donner_echantillon : echantillon -> erreur = "ml_donner_echantillon"
(*
** Renvoie le type d’une case donnée, ou 0 si la case est invaide.
*)
external type_case : position -> int -> case_type = "ml_type_case"
(*
** Indique si une case donnée est vide ou contient un élément. Renvoie faux en cas d'erreur.
*)
external est_vide : position -> int -> bool = "ml_est_vide"
(*
** Renvoie la propriété de l’élément sur une case donnée. Un élément invalide n'a pas de propriété.
*)
external propriete_case : position -> int -> element_propriete = "ml_propriete_case"
(*
** Renvoie la propriété d’un type de case donné.
*)
external propriete_case_type : case_type -> element_propriete = "ml_propriete_case_type"
(*
** Renvoie la taille de la région à laquelle appartient un élément. Renvoie -1 si la position est invalide.
*)
external taille_region : position -> int -> int = "ml_taille_region"
(*
** Renvoie la liste des positions des cases composant la région à laquelle appartient un élément donné. Renvoie une liste vide en cas d'erreur.
*)
external positions_region : position -> int -> position array = "ml_positions_region"
(*
** Détermine si le placement d’un échantillon est valide.
*)
external placement_possible_echantillon : echantillon -> position -> position -> int -> bool = "ml_placement_possible_echantillon"
(*
** Renvoie la liste des placements possibles pour un échantillon donné sur l’établi d’un apprenti donné. Renvoie une liste vide en cas d'erreur.
*)
external placements_possible_echantillon : echantillon -> int -> position_echantillon array = "ml_placements_possible_echantillon"
(*
** Renvoie la liste des actions jouées par l’adversaire pendant son tour, dans l’ordre chronologique.
*)
external historique : unit -> action_hist array = "ml_historique"
(*
** Renvoie votre numéro d’apprenti.
*)
external moi : unit -> int = "ml_moi"
(*
** Renvoie le numéro d’apprenti de votre adversaire.
*)
external adversaire : unit -> int = "ml_adversaire"
(*
** Renvoie la quantité d’or amassée par l’apprenti désigné par le numéro ``id_apprenti``. Renvoie 0 si ``id_apprenti`` est invalide (attention, le score d’un apprenti valide peut aussi être 0).
*)
external score : int -> int = "ml_score"
(*
** Renvoie le numéro du tour actuel.
*)
external tour_actuel : unit -> int = "ml_tour_actuel"
(*
** Annule la dernière action. Renvoie ``false`` quand il n’y a pas d’action à annuler ce tour-ci.
*)
external annuler : unit -> bool = "ml_annuler"
(*
** Indique le nombre de catalyseurs en votre possession.
*)
external nombre_catalyseurs : unit -> int = "ml_nombre_catalyseurs"
(*
** Indique l’échantillon reçu pour ce tour.
*)
external echantillon_tour : unit -> echantillon = "ml_echantillon_tour"
(*
** Indique si l’échantillon reçu pour ce tour a déjà été posé.
*)
external a_pose_echantillon : unit -> bool = "ml_a_pose_echantillon"
(*
** Indique si un échantillon a déjà été donné ce tour.
*)
external a_donne_echantillon : unit -> bool = "ml_a_donne_echantillon"
(*
** Renvoie la quantité d’or (et donc le score) obtenue par la transmutation de ``taille_region`` éléments transmutables en or.
*)
external quantite_transmutation_or : int -> int = "ml_quantite_transmutation_or"
(*
** Renvoie la quantité de catalyseurs obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
*)
external quantite_transmutation_catalyseur : int -> int = "ml_quantite_transmutation_catalyseur"
(*
** Renvoie la quantité d’or obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
*)
external quantite_transmutation_catalyseur_or : int -> int = "ml_quantite_transmutation_catalyseur_or"
(*
** Indique l’échantillon par défaut lors du premier tour
*)
external echantillon_defaut_premier_tour : unit -> echantillon = "ml_echantillon_defaut_premier_tour"
(*
** Affiche l'état actuel des deux établis dans la console.
*)
external afficher_etablis : unit -> unit = "ml_afficher_etablis"
(*
** Affiche le contenu d'une valeur de type case_type
*)
external afficher_case_type : case_type -> unit = "ml_afficher_case_type"
(*
** Affiche le contenu d'une valeur de type element_propriete
*)
external afficher_element_propriete : element_propriete -> unit = "ml_afficher_element_propriete"
(*
** Affiche le contenu d'une valeur de type erreur
*)
external afficher_erreur : erreur -> unit = "ml_afficher_erreur"
(*
** Affiche le contenu d'une valeur de type action_type
*)
external afficher_action_type : action_type -> unit = "ml_afficher_action_type"
(*
** Affiche le contenu d'une valeur de type position
*)
external afficher_position : position -> unit = "ml_afficher_position"
(*
** Affiche le contenu d'une valeur de type echantillon
*)
external afficher_echantillon : echantillon -> unit = "ml_afficher_echantillon"
(*
** Affiche le contenu d'une valeur de type position_echantillon
*)
external afficher_position_echantillon : position_echantillon -> unit = "ml_afficher_position_echantillon"
(*
** Affiche le contenu d'une valeur de type action_hist
*)
external afficher_action_hist : action_hist -> unit = "ml_afficher_action_hist"
