module Sig_interface: sig
.. end
Projet Puzzle
Author(s): Lilian Besson <lilian.besson[AT]ens-cachan.fr>
val init_fenetre : x:int -> y:int -> unit -> unit
Pour ouvrir une fenêtre, qui utilise le module Graphics, de taille "x" x "y".
Réalise l'inverse de la fonction 'rgb', récupère le code R,G,B depuis une "Graphics.color", représentation interne du module Graphics pour les couleurs.
val from_rgb : Graphics.color -> int * int * int
val draw_rect : int -> int -> int -> int -> unit
Dessine un rectangle en renseignant les coordonnées du point inférieur gauche et supérieur droit.
val draw_int : x:int -> y:int -> i:int -> unit
Ecrit la valeur de l'entier "i" en position "x" x "y".
val couleur_fond : Graphics.color
La couleur qui est utilisé en fond de tous les dessins fait dans cette interface graphique. Par défaut, c'est blanc.
val couleur_lignes : Graphics.color
La couleur qui est utilisé en fond de tous les dessins fait dans cette interface graphique. Par défaut, c'est noir.
val genere_echelle_couleur : cmin:Graphics.color -> cmax:Graphics.color -> nb:int -> Graphics.color array
Pour générer un tableau de couleurs par interpolation affine, selon deux couleurs "cmin" et "cmax", pour un nombre "nb" de couleurs différentes.
exception Error_Annule of int
On utilise beaucoup l'outil "Zenity", par l'appel en exécutant des lignes de commandes, via le module "Sys" et sa précieuse fonction "Sys.command". Ces commandes renvoient des codes d'erreurs, qui sont propagés au niveau supérieur via cette exception.
val faire : string -> unit
Exécute la commande présente dans la chaine argument, en renvoyant les erreurs au niveau supérieur.
val zenity_info : string -> unit
Une macro pour afficher une fenêtre d'information via Zenity, contenant le message argument. Impose un titre 'Projet Puzzle : information', et va chercher une icone ".monicone.ico" pour la fenêtre dans le répertoire 'Projet_Programmation_2_Lilian_BESSON'.
val ask_couleur : unit -> Graphics.color
Utilise Zenity pour demander à l'utilisateur de choisir une couleur dans une roue des couleurs RGB, et la renvoie. Utilise un fichier caché temporaire ".color_choose_zenity.color".
val ask_int : unit -> int
Idem, pour demander la valeur d'un entier. Par défaut, ces valeurs sont restreintes entre 1 et 16. Utilise un fichier caché temporaire ".int_choose_zenity.int".
val ask_int_msg : string -> unit -> int
La même, mais en spécifiant un message supplémentaire. Par exemple : "choissiez le nombre de couleurs".
val ask_echelle_couleur : int -> unit -> Graphics.color array
Demande deux fois une couleurs, et renvoie une tableau de couleurs, formant un dégradé depuis la première jusqu'a la seconde. Le rendu est un peu aléatoire. En cas de doute, choisir blanc et noir donne un rendu acceptable.
val fill_custom : Resolution.couleur -> (int * int) array -> unit -> unit
Pour remplir un polygone donné par le tableau de ses sommets d'une couleur d'indice donné. Utilise une échelle de couleur globale définie dans le fichier.
val line_custom : Resolution.couleur -> int -> int -> int -> int -> unit -> unit
La meme chose, pour dessinée une ligne colorée. Les deux premières valeurs sont pour le premier point, et les deux autres pour le second point.
val echelle_globale_fichier_initialisee_une_fois : Graphics.color array Pervasives.ref
Voila l'échelle globale annoncée plus haut.
val afficher_piece : ?x:int -> ?y:int -> p:Resolution.piece -> ?s:int -> c:int -> unit
Pour afficher une pièce "p" en position "x" et "y", avec une taille "s" (par défaut 30 pixel), et avec un nombre de couleur "c". Utilise l'échelle de couleur globale.
val afficher_piece_option : ?x:int -> ?y:int -> p:Resolution.piece option -> ?s:int -> c:int -> unit
La même chose, mais en laissant un espace blanc en cas de 'None' pour la piece option. Permet de dessiner ensuite un plateau courant qui n'est pas encore entierèment complété.
exception Fin
Si l'utilisateur choisi de fermer l'interface graphique, c'est cette exception qui est propageé.
val squel : f_init:(unit -> 'a) ->
f_end:(unit -> unit) ->
f_key:(char -> unit) ->
f_mouse:(int -> int -> unit) -> f_except:(exn -> unit) -> unit
Ce générateur de boucle intéractive est librement inspiré du livre 'Developpement d'applications en Ocaml'. Cette fonction génère une interface graphique, qui exécute "f_init" pour se démarrer, "f_end" pour se fermer, "f_key" pour réagir à l'appuis sur une touche, "f_mouse" pour réagir au clic de la souris, et "f_except" pour gérer les éventuelles exceptions lancée par les 4 autres fonctions.
val trait_char : int -> char -> unit
Un exemple de "f_key" réagissant à l'appuis sur une touche du clavier.
val exemples_piece_aleatoire : int -> unit
Utilise 'trait_char' précédent pour réaliser une petite interface graphique, la première du fichier, qui dessine une nouvelle pièce a chaque clic de la souris.
exception Erreur_trop_grand_h
L'écran d'un ordinateur étant limité en taille, on interdit de dessiner des plateaux trop grand. Si on essaie de dessiner un plateau trop grand horizontalement, cette exception est déclenchée.
exception Erreur_trop_grand_v
De même si trop grand verticalement.
val resolution_x : int
La taille maximum de la fenêtre selon x. Par défaut, vaut 1000 pixels, afin d'être compatible avec la plupart des ordinateurs du marché.
val resolution_y : int
Idem, mais selon les ordonnées y. Par défaut, 700 pixels.
val taille_piece : int
La taille d'une MOITIEE de pièce, en pixel. Par défaut, 30.
val afficher_plateau : Resolution.plateau -> unit
Pour afficher un plateau dans la fenêtre courante. Comme toutes les autres fonctions d'affichage suivantes, suppose qu'une fenêtre soit déjà ouverte, sinon ça crache salement.
val test_random : m:int -> n:int -> c:int -> nb:int -> unit
Pour réaliser un test de cette fonction. "nb" correspond juste au nombre de tests voulus. Ne fonctionne qu'en mode console.
val actualise_taille : s:int -> n:int -> m:int -> unit -> unit
Actualise la taille réelle de la fenêtre courante selon le nombre de pièces "n" et "m", en la calculant selon la taille des pièces "s". Demande une confirmation supplémentaire (un "()" en plus).
val lit_et_affiche_plateau : file:string -> unit
Tout est dans le nom.
val afficher_instance : Resolution.instance -> unit
Pour afficher une instance dans la fenêtre courante.
val lit_et_affiche_instance : file:string -> unit
Idem.
val creer_instance_random_et_affiche : m:int -> n:int -> c:int -> Resolution.instance
Encore une fois, le nom et les paramètres sont ... explicites !
val aff_random : m:int -> n:int -> c:int -> Resolution.instance
Un simple alias de la précédente.
val printP : Resolution.plateau -> unit
La méthode graphique de gestion du plateau courant, pour aller avec la fonction Resolution.resoud_naivement.
val resoud_naivement_graphique : Resolution.instance -> Resolution.plateau
Résoud l'instance argument, ou en tout cas essaie, de manière naïve. Affiche progressivement les plateaux courants.
Plus précisément, chaque appel récursif commence par afficher son plateau
val aide_interface : string
Chaine contenant l'aide de l'interface utilisateur.
val aide_ic : unit -> unit
Pour afficher une fenêtre Zenity contenant l'aide nommée ci dessus.
val new_n_ic : unit -> int
Pour demander une nouvelle valeur au nombre local de lignes.
val new_m_ic : unit -> int
Idem nombre de colonnes.
val new_c_ic : unit -> int
Idem nombre de couleurs.
val ask_fichier : unit -> string
Pour demander un nom de fichier à l'utilisateur. Utilise Zenity, et affiche des messages informatifs assez clairs.
val browse_instance : unit -> Resolution.instance
Combine 'ask_fichier' avec 'lecture_instance'.
val ask_value : string -> unit -> string
Idem, mais en demandant à l'utilisateur de renseigner lui même le nom de fichier, par exemple pour la capture d'écran (enregistrement au format jpg).
val demande_confirmation_graphique : string -> unit
Si le fichier destination choisi avec ask_value existe déja, une confirmation est demandée avant de l'écraser.
val capture_ecran : unit -> unit
Pour faire une capture d'écran de la fenêtre courante. Un détail : avec le module Graphics il n'est pas possible de récupérer (simplement) le titre de la fenêtre, donc cette fonction réinitialise le titre à "Projet Puzzle".
val titre_ic : c:int -> n:int -> m:int -> unit
Pour actualiser le titre de la fenêtre en fonction des trois paramètres courants "c", "n", "m".
val fail_recherche : Resolution.instance -> unit -> unit
Si la recherche exhaustive a échouée, un message informatif est affiché par cette fonction, qui deplus redessine l'instance qu'on tentait de résoudre dès que l'utilisateur a confirmé avoir lu le message informatif.
val ask_piece : c:int -> unit -> Resolution.piece
Lance une demande intéractive de pièce : l'utilisateur doit choisir les 4 couleurs (haut, gauche, bas, droite), entre 1 et "c".
val ask_position : n:int -> m:int -> s:int -> unit -> int * int
Attends que l'utilisateur clique sur une des cases de la fenêtre.
val interface_complete : unit -> unit
L'interface finale. Utilise tout ce qui précède. Après avoir chosis les paramètres, tapez "h" pour une liste complète des options disponibles.
Aide de l'interface graphique
Ce programme est écrit en Ocaml, et utilise le module graphique de la distribution standard Graphics pour l'affichage, et l'outil Zenity, disponible gratuitement sous Linux (''$ sudo apt-get install zenity'' pour le récupérer).
Durant la boucle intéractive, les touches suivantes déclenchent les actions suivantes :
h : affiche ce message d'aide,
'enter' : efface la fenêtre,
'e' fait la meme chose (le code de la touche 'enter' varie selon le mode d'exécution).
u : change le nombre de couleurs utilisées,
c : change l'échelle de couleur utilisée,
m : change le nombre de colonnes des instances générées,
n : change le nombre de lignes des instances générées,
'Escape': quitte proprement et enregistre l'instance / le plateau courant dans un fichier de sauvegarde caché,
i : sauvegarde l'image de la fenêtre dans une image JPEG externe, en demandant un nom de fichier (demande confirmation avant écrasement). Utilise l'outil 'import', disponible gratuitement sous Linux (''$ sudo apt-get install imagemagick'' pour le récupérer),
s : sauvegarde l'instance / le plateau courant affiché à l'ecran dans un fichier texte externe, en demandant un nom de fichier (demande confirmation avant écrasement).
b : ouvre une instance déjà sauvegardée, en utilisant le navigateur de document de Zenity.
'space' : génére une nouvelle instance aléatoire avec les paramètres courant, et l'affiche,
w : génére une nouvelle instance aléatoire, ayant une solution, avec les paramètres courant, et l'affiche,
y : génére une solution aleatoire, avec les paramètres courant, et l'affiche,
p : demande de choisir une pièce, puis une position pour cette pièce, et enfin confirmation pour la placer dans l'instance courante. Redessine celle ci ensuite. Un clic de la souris sur une position de pièce fait la même chose.
v : pour vérifier la validité du plateau dessiné à l'écran, et afficher le résultat (valide, ou une preuve de non validité) dans une fenêtre informative.
r : résoud l'instance courante affichée à l'écran,
Appuyez sur Echap pour fermer cette fenêtre d'aide et retourner au programme. Evitez de quitter brutalement, la gestion souple d'une 'fatal error' n'est pas encore au point (ceci est valable pour tout le programme).