206 lines
8.3 KiB
TeX
206 lines
8.3 KiB
TeX
%%%%%%%%%%
|
|
% Macros %
|
|
%%%%%%%%%%
|
|
|
|
% Associe les couleurs en fonction de l'état d'une cellule
|
|
\newcommand{\cellcolor}[1]{%
|
|
\ifnum\pdfstrcmp{#1}{alive}=0 matblue\fi%
|
|
\ifnum\pdfstrcmp{#1}{dying}=0 matred\fi%
|
|
\ifnum\pdfstrcmp{#1}{nascent}=0 matgreen\fi}
|
|
|
|
% Dessine une cellule en X, Y dans l'état donné (doit être
|
|
% utilisé dans un environnement TikZ)
|
|
\newcommand{\fillcell}[3]{
|
|
\ifnum\pdfstrcmp{#3}{stillborn}=0
|
|
\draw [fill=\cellcolor{dying}] (#1,#2) -- (#1+1,#2) -- (#1+1,#2+1) -- (#1,#2);
|
|
\draw [fill=\cellcolor{nascent}] (#1,#2) -- (#1,#2+1) -- (#1+1,#2+1) -- (#1,#2);
|
|
\else
|
|
\draw [fill=\cellcolor{#3}] (#1,#2) rectangle (#1+1,#2+1);
|
|
\fi
|
|
}
|
|
|
|
%%%%%%%%%%
|
|
% Source %
|
|
%%%%%%%%%%
|
|
|
|
\chapter{Jeu de la vie}
|
|
|
|
Le jeu de la vie, inventé par John Conway en 1970, est l'exemple le plus
|
|
populaire d'automate cellulaire.
|
|
\cite{gof-wikipedia}
|
|
Un automate cellulaire est un ensemble
|
|
de cellules pouvant être dans plusieurs états différents et dont l'état
|
|
suivant est entièrement déterminé à partir de l'état actuel.
|
|
\cite{gof-automata}
|
|
|
|
Il présente un intérêt théorique car il a été démontré que le jeu de la vie
|
|
est Turing-complet, c'est-à-dire que n'importe quel algorithme peut
|
|
y être implémenté.
|
|
|
|
\section{Principes}\label{sec:principes}
|
|
|
|
Le jeu de la vie est composé d'une grille infinie de cellules pouvant
|
|
être soit mortes soit vivantes. Le jeu est constitué d'états : un état du jeu
|
|
est l'ensemble des états (vivante ou morte) de chacune de ses cellules à
|
|
un moment précis. Seul l'état initial est fourni, les états suivants sont calculés
|
|
de proche en proche selon les règles suivantes~:
|
|
|
|
\begin{enumerate}
|
|
\item si une cellule a trois voisines à l'état $n$, elle est vivante à l'état $n+1$ ;
|
|
\item si une cellule a deux voisines à l'état $n$, elle persévère dans son état ;
|
|
\item si une cellule a moins de deux ou plus de trois voisines à l'état $n$, elle est morte à l'état $n+1$.
|
|
\cite{gof-conwaylife}
|
|
\end{enumerate}
|
|
|
|
Les figures~\ref{fig:life-ex-1}, \ref{fig:life-ex-2} et \ref{fig:life-ex-3} montrent
|
|
trois situations typiques du jeu de la vie sur des portions de grilles.
|
|
Dans ces figures, une case \tikz[scale=.2]{\fillcell{0}{0}{nascent}} représente
|
|
une cellule qui vient de naître, une case \tikz[scale=.2]{\fillcell{0}{0}{dying}}
|
|
représente une cellule qui va mourir à l'état suivant et une case
|
|
\tikz[scale=.2]{\fillcell{0}{0}{alive}} représente une cellule vivante.
|
|
|
|
\begin{figure}[p!]
|
|
\centering
|
|
\input{./figures/life-ex-1}
|
|
\caption{Mort par sous-population}
|
|
\label{fig:life-ex-1}
|
|
\end{figure}
|
|
|
|
\begin{figure}[p!]
|
|
\centering
|
|
\input{./figures/life-ex-2}
|
|
\caption{Un oscillateur, une configuration qui se répète indéfiniment}
|
|
\label{fig:life-ex-2}
|
|
\end{figure}
|
|
|
|
\begin{figure}[p!]
|
|
\centering
|
|
\input{./figures/life-ex-3}
|
|
\caption{Stabilisation de la configuration en quatre états}
|
|
\label{fig:life-ex-3}
|
|
\end{figure}
|
|
|
|
\section{Modélisation}
|
|
|
|
Les cellules peuvent prendre uniquement deux états, vivante ou
|
|
morte. Pour cette raison, il est naturel de représenter une
|
|
cellule par un booléen, \texttt{true} pour une cellule
|
|
vivante et \texttt{false} pour une cellule morte.
|
|
Pour la représentation d'une grille de cellules, on utilisera donc
|
|
un tableau de tableaux de booléens.
|
|
|
|
Les tableaux seront de taille suffisamment grande pour éviter qu'une
|
|
structure n'arrive à la bordure. En effet, le comportement à la bordure
|
|
d'une grille n'est pas défini dans les règles du jeu de la vie puisqu'il
|
|
est censé se dérouler sur une grille infinie.
|
|
|
|
\section{Algorithmes}
|
|
|
|
Quatre algorithmes doivent être définis pour gérer la grille.
|
|
|
|
\begin{description}
|
|
\item[Initialisation de la grille] Allocation d'une grille de taille
|
|
donnée et initialisation de tous les booléens à \texttt{false}.
|
|
\item[Détermination du nombre de voisins vivants] Reçoit une grille $G$
|
|
et une position de cellule $(x, y)$.
|
|
\begin{enumerate}
|
|
\item Soit $total := 0$.
|
|
\item Pour $i$ allant de $x - 1$ à $x + 1$~:
|
|
\begin{enumerate}
|
|
\item pour $j$ allant de $y - 1$ à $y + 1$, si
|
|
$(i, j)$ est une position valide et
|
|
$(i, j)$ est une cellule vivante de $G$ et
|
|
$(i, j) \neq (x, y)$, alors $total := total + 1$.
|
|
\end{enumerate}
|
|
\item Renvoyer $total$.
|
|
\end{enumerate}
|
|
\item[Calcul de l'état suivant] Reçoit une grille $G$ et calcule
|
|
la grille représentant l'état suivant du jeu.
|
|
\begin{enumerate}
|
|
\item Soit $G^\prime$ une grille de même taille que $G$.
|
|
\item Pour $i$ allant de $0$ à la taille horizontale de $G$~:
|
|
\begin{enumerate}
|
|
\item pour $j$ allant de $0$ à la taille verticale de $G$~:
|
|
\begin{enumerate}
|
|
\item appeler l'algorithme \textbf{Détermination du nombre de voisins vivants}
|
|
sur la grille $G$ et la case $(i, j)$ et stocker le résultat dans $voisins$~;
|
|
\item si $voisins = 3$, $G^\prime(i, j) := \mathtt{true}$~;
|
|
\item sinon, si $voisins = 2$, $G^\prime(i, j) := G(i, j)$~;
|
|
\item sinon, $G^\prime(i, j) := \mathtt{false}$.
|
|
\end{enumerate}
|
|
\end{enumerate}
|
|
\item Renvoyer $G^\prime$.
|
|
\end{enumerate}
|
|
\item[Affichage de la grille] Doit parcourir chaque cellule
|
|
d'une grille donnée pour afficher à l'écran l'état de celle-ci. L'algorithme
|
|
dépendra principalement du type d'affichage choisi (terminal, fenêtré).
|
|
\end{description}
|
|
|
|
Le programme principal se charge d'appeler l'algorithme 1, puis
|
|
d'appeler de manière répétée les algorithmes 3 et 4 pour afficher
|
|
les états suivants.
|
|
|
|
\section{Spécifications}
|
|
|
|
\subsection{Version initiale}
|
|
|
|
On choisira le langage C++, qui possède les structures requises dans
|
|
la section précédente, et est enseigné dans le cursus. Il n'y a pas de difficulté
|
|
algorithmique particulière qui justifie le choix d'un langage différent,
|
|
sachant que le choix d'un tel langage pourrait ralentir le développement.
|
|
|
|
L'affichage de la grille se fera dans le terminal. Un algorithme
|
|
naïf sera choisi pour le calcul de l'état suivant, se contenant de parcourir
|
|
chaque cellule et de calculer son état, sans recherche d'optimisation.
|
|
|
|
L'état initial sera choisi par l'utilisateur parmi une série de
|
|
préconfigurations codées \emph{en dur} dans le programme.
|
|
|
|
Le type \texttt{std::vector<std::vector<bool>\null>} de la librairie
|
|
standard C++ sera utilisé pour représenter les grilles car il permet
|
|
une allocation dynamique automatiquement gérée.
|
|
|
|
\subsection{Améliorations possibles}
|
|
|
|
L'affichage peut s'effectuer en fenêtré. Les bibliothèques
|
|
SDL~(en C) ou SFML~(en C++, orienté objet) peuvent être choisies
|
|
et seront utilisées dans l'algorithme d'affichage pour le dessin
|
|
des cellules, et dans le programme principal pour initialiser la fenêtre.
|
|
|
|
On peut laisser l'utilisateur choisir l'état initial en cliquant
|
|
sur les cellules. L'utilisateur pourra contrôler la génération grâce
|
|
à un bouton marche/arrêt, pas à pas, ou remise à zéro. On peut
|
|
également fournir une série de préconfigurations parmi lesquelles choisir
|
|
dans l'interface.
|
|
|
|
Enfin, un algorithme plus performant peut être utilisé, réduisant
|
|
les calculs inutiles. Par exemple, l'algorithme \emph{Hashlife,}
|
|
\cite{gof-hashlife}
|
|
utilisant des \emph{quadtrees} et une table de hachage peut améliorer
|
|
considérablement les performances (mais peut être difficile à implémenter).
|
|
|
|
\section{Organisation}
|
|
|
|
Pour la version initiale du programme, il y a quatre algorithmes à
|
|
mettre en place. Ces algorithmes reprennent des concepts
|
|
vus en cours. On pourra y consacrer 10 heures.
|
|
|
|
Pour l'affichage fenêtré, il faudra se renseigner sur l'A.P.I. des
|
|
bibliothèques utilisées, concevoir une interface (placement des boutons,
|
|
de la grille) et l'implémenter. On pourra prévoir 10 heures.
|
|
|
|
L'implémentation de l'algorithme \emph{Hashlife} requièrera des renseignements
|
|
sur l'utilisation des \emph{quadtrees} et des tables de hachages ainsi
|
|
que sur l'algorithme en lui-même. Prévoir 20 heures.
|
|
|
|
La rédaction du rapport s'effectuera en continu pendant la création du jeu.
|
|
La figure~\ref{fig:life-gantt} présente un diagramme de Gantt résumant
|
|
la répartition du travail.
|
|
|
|
\begin{figure}[h!]
|
|
\centering
|
|
\input{./figures/life-gantt}
|
|
\caption{Développement du jeu de la vie sur 40 heures}
|
|
\label{fig:life-gantt}
|
|
\end{figure}
|