diff --git a/rendu/rendu.pdf b/rendu/rendu.pdf index fd08e3c..6292fd6 100644 Binary files a/rendu/rendu.pdf and b/rendu/rendu.pdf differ diff --git a/rendu/rendu.tex b/rendu/rendu.tex index bed9584..a44faaf 100644 --- a/rendu/rendu.tex +++ b/rendu/rendu.tex @@ -5,8 +5,14 @@ \usepackage[T1]{fontenc} % encodage T1 police \usepackage[hidelinks]{hyperref} % lien dans table des matières \usepackage{listings} % intégration code -\usepackage[dvipsnames]{xcolor} % couleur +\usepackage{xcolor} % couleur +\usepackage{enumitem} % listes personalisées +\usepackage{graphicx} % intégration images +% liste avec flèches +\newlist{listeFleche}{itemize}{4} +\setlist[listeFleche]{label=$\rightarrow$} +% couleurs \definecolor{defaultPredicat}{RGB}{121, 94, 38} \definecolor{definitionChar}{RGB}{175, 0, 219} \definecolor{argsAndPredicat}{RGB}{0, 96, 181} @@ -16,6 +22,8 @@ frame=single, % encadré breaklines=true, % lignes dans le cadre columns=fullflexible, % contenu bien présenté dans le cadre + language=Prolog, % language + tabsize=4, % nb d'espace par tabulation % chiffres numbers=left, numberstyle=\tiny, @@ -43,8 +51,10 @@ {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1 {€}{{\euro}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1 {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1 {¡}{{!`}}1, - showstringspaces=false, % espaces normaux - language=Prolog % language + % espaces normaux sans underscore + showspaces=false, + showstringspaces=false, + showtabs=false } \author{Kévin Martins Da Veiga [20009472] et Anri Kennel [20010664]} \title{Projet Heyawake en Prolog} @@ -58,28 +68,109 @@ \section{Présentation du Projet} \subsection{Introduction et règles du jeu} - \noindent L'Heyawake est un puzzle joué dans une grille rectangulaire séparés en plusieurs aires dont le but - est de colorés des cellules en noir et blanc en accord avec les règles : - \\\indent -> Certaines aires contiennent un chiffre qui montre combien il y a de cellules noires dans l'aire - \\\indent\indent -> Région avec un 0 ne doivent pas avoir de cellules noires - \\\indent\indent -> Région avec un 1 contient une cellule noire - \\\indent -> Toutes les cellules blanches doivent être connectés en un seul groupe, pas de groupe isolés, elles doivent toutes être reliés - \\\indent -> Deux cellules noires de peuvent être l'un à côté de l'autre horizontalement et verticalement (en diagonale, c'est possible) - \\\indent\indent -> Ca veut dire que les cellules noires doivent être que entourés de cellules blanches - \\\indent -> Une rangée de cellule blanche ne peuvent pas être alignée au-delà de 2 aires + L'Heyawake est un puzzle joué dans une grille rectangulaire séparés en plusieurs aires dont le but + est de colorés des cases en noir et blanc en accord avec les règles : + + \begin{listeFleche} + \item Certaines aires contiennent un chiffre qui montre combien il y a de cases noires dans l'aire + \begin{listeFleche} + \item Région avec un 0 ne doivent pas avoir de cases noires + \item Région avec un 1 contient une case noire + \end{listeFleche} + \item Toutes les cases blanches doivent être connectés en un seul groupe, pas de groupe isolés, elles doivent toutes être reliés + \item Deux cases noires de peuvent être l'un à côté de l'autre horizontalement et verticalement (en diagonale, c'est possible) + \begin{listeFleche} + \item Ca veut dire que les cases noires doivent être que entourés de cases blanches + \end{listeFleche} + \item Une rangée de case blanche ne peuvent pas être alignée au-delà de 2 aires + \end{listeFleche} + \subsection{Réalisation} + \begin{listeFleche} + \item Mettre toutes les aires avec un 0 en blanc + \item Mettre des cases noires là où une rangée de cases blanches dans plus de 2 aires peut se faire + \item Toujours mettre du blanc autour des celulles noires + \begin{listeFleche} + \item En suivant cette étape, quand on met une case noire dans une aire avec un chiffre 1, colore tout le reste de l'aire en blanc + \end{listeFleche} + \item Toujours verifié que les cases blanches ne sont pas piégés entre des cases noires + \begin{listeFleche} + \item Ca implique que dans ce schéma suivant avec B une case blanche, N une case noire et X une case vide : + \begin{listeFleche} + \item B X B $\rightarrow$ B B B + \item N B N $\rightarrow$ N B N + \item B N B $\rightarrow$ B N B + \item Le X doit obligatoirement devenir blanc pour laisser une sortie à la case blanc qui se trouve entre les cases noires + \end{listeFleche} + \end{listeFleche} + \end{listeFleche} + + Le programme se lance en appelant le prédicat \emph{run} avec comme argument une liste de listes des aires. + + \begin{lstlisting} +run([[0,0,1,1,2], [2,0,2,2,-1], [3,0,5,1,-1], + [0,2,0,4,-1], [1,2,1,3,0], [3,2,5,2,0], + [1,4,1,4,1], [2,3,5,5,4], [0,5,1,5,-1]]). +% [X1, Y1, X2, Y2, N] avec N le nombre de case noire dans l'aire + \end{lstlisting} + + Cet appel correspond au puzzle ci-dessous + \begin{figure}[ht] + \centering + \includegraphics[width=5cm, height=5cm]{default} + \caption{Puzzle de difficulté facile d'Heyawake} + \label{fig:fig1} + \end{figure} + \section{Résolution d'une grille avec des aires} - \subsection{On a essayé\dots} + \subsection{Ce que l'on a essayé\dots} + \begin{listeFleche} + \item On vérifie les aires avec un 2 et de 4 cases puis on colorie la case 2 en noire et ses diagonales + \begin{listeFleche} + \item On colore les cases adjacentes au noire en blanc, on le fais autant de fois que nécessaire + \end{listeFleche} + \item On regarde quelles cases doivent être colorés en noire pour éviter de faire des lignes de 4 cases blanches + \item On connecte les cases blanches entre elle sans faire de lignes de plus de 3 cases dans des zones différentes + + \item Maintenant on essaie de rajouter des cases noires : + \begin{listeFleche} + \item On met une case noire pour éviter des groupes de 3 cases blanches + \item On colorie les cases adjacentes à la nouvelle case noire en blanc + \end{listeFleche} + \item On fait en sorte que toutes les cases blanches soient connectés en rajoutant des cases blanches si possible + \item On remplie les cases noires là où on peut les mettre + \item Etc\dots + \end{listeFleche} \section{Le programme} - \subsection{La fonction principal en détail} - \subsection{Listing des prédicats utilisés} - \subsection{On a pas réussi\dots} + \subsection{Le prédicat \emph{\texttt{aire}} en détail} + Le prédicat \emph{\texttt{aire}} fonctionne comme l'image ci-contre. Il regarde chaque case de l'aire. + Une fois arrivé à l'extremité d'une aire, il descend d'une case si il y une ligne en dessous puis il parcours + le chemin inverse avec le prédicat \emph{\texttt{airereverse}}. - \newpage - \section{Annexe : les codes} - \subsection{Programme qui ne fonctionne pas} + Par exemple, sur la figure \ref{fig:fig1}, prenons l'aire en bas à droite : + \begin{figure}[ht] + \centering + \includegraphics[width=5cm, height=5cm]{aireExplication} + \caption{Explication fonctionnement \emph{\texttt{aire}}} + \end{figure} + + \subsection{Listing des prédicats utilisés} + \begin{listeFleche} + \item \textbf{\texttt{aire(X1, Y1, X2, Y2, E, T)}} : + Ce prédicat fait scanne l'aire renseignée et assigne une couleur via le prédicat \emph{\texttt{case}}. + \item \textbf{\texttt{airereverse(X1, Y1, X2, Y2, 0, T)}} : + Ce prédicat est appellée par le prédicat \emph{\texttt{aire}} et permet de vérifier tout les éléments + d'une aire. + \item \textbf{\texttt{case(X, Y, C)}} : + Ce prédicat renvoie la couleur d'une case du puzzle. + \item \textbf{\texttt{run([[X1, Y1, X2, Y2, E] | Q])}} : + Ce prédicat lance la résolution du puzzle. + \end{listeFleche} + + + \section{Annexe : le code} \lstinputlisting{../resolveur.pl} \end{document} diff --git a/resolveur.pl b/resolveur.pl index 51cc8a4..fdebfb7 100644 --- a/resolveur.pl +++ b/resolveur.pl @@ -4,15 +4,14 @@ aire(X, Y, X, Y, 1) :- case(X, Y, 1). % zone blanche aire(X1, Y1, X2, Y2, 0, T) :- X1 \= X2, case(X1, Y1, 0), NX is X1 + 1, aire(NX, Y1, X2, Y2, 0, T). aire(X, Y1, X, Y2, 0, T) :- Y1 \= Y2, case(X, Y1, 0), NY is Y1 + 1, airereverse(X, NY, X, Y2, 0, T). -% zone : E = Etat, T = Taille -aire(X1, Y1, X2, Y2, E, T) :- E \= 0, write("\n"), write(X1), - write(" "), write(Y1), - write(" "), write(X2), - write(" "), write(Y2), - write(" "), write(E), - write(" "), write(T). -airereverse(X1, Y1, X2, Y2, 0, T) :- case(X1, Y1, 0), NX is X1 - 1, NX \= T, airereverse(NX, Y1, X2, Y2, 0, T); +% zone : E = Etat, T = Taille +aire(X1, Y1, X2, Y2, E, T) :- E \= 0, write("\n"), write(X1), write(" "), write(Y1), + write(" "), write(X2), write(" "), write(Y2), + write(" "), write(E), write(" "), write(T). + +airereverse(X1, Y1, X2, Y2, 0, T) :- case(X1, Y1, 0), NX is X1 - 1, NX \= T, + airereverse(NX, Y1, X2, Y2, 0, T); NX = T, aire(NX, Y1, X2, Y2, 0, T). % cellule