Rapport

Transcription

Rapport
WERNER Nicolas
M1 IFA
travail d’étude et de
recherche
Encadré par Simon E. B. Thierry
Table des matières
1 Introduction
3
2 Principe du jeu
2.1 Règles du jeu . . . . . . . .
2.2 Tactiques de base . . . . . .
2.2.1 Ile complète . . . . .
2.2.2 Iles voisines . . . . .
2.2.3 Unique possibilité de
2.2.4 Case inatteignable .
2.2.5 Coude noir . . . . .
2.2.6 Case condamnée . .
.
.
.
.
.
.
.
.
4
4
4
5
5
6
6
7
7
3 Formalisation
3.1 Le jeu formalisé . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Terminologie . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 NP-complétude . . . . . . . . . . . . . . . . . . . . . . . . . .
8
8
8
9
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
développement
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4 Solveur
4.1 Approches possibles . . . . . . . . . . . . . . . . . . . .
4.2 Approche personnelle . . . . . . . . . . . . . . . . . . . .
4.2.1 Case semi-déterminée adjacente . . . . . . . . . .
4.2.2 Case atteignable par une seule ı̂le . . . . . . . . .
4.2.3 Unique chemin possible d’une ı̂le . . . . . . . . .
4.2.4 Case encerclée . . . . . . . . . . . . . . . . . . .
4.2.5 Contradiction apparente . . . . . . . . . . . . . .
4.2.6 Espace nécessaire . . . . . . . . . . . . . . . . . .
4.2.7 Information selon les chemins possibles d’une ı̂le
5 Implémentation
5.1 Choix techniques . . .
5.1.1 La classe Grille
5.1.2 La classe Case
5.1.3 La classe Ile . .
5.1.4 La classe Mur .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10
10
10
11
11
12
12
13
13
14
.
.
.
.
.
15
15
15
15
16
16
5.2
5.1.5 La classe Bloc . . . . . . . . .
5.1.6 La classe CaseMouseListener
5.1.7 La classe Solveur . . . . . . .
5.1.8 La classe Nurikabe . . . . . .
Interface . . . . . . . . . . . . . . . .
6 Résultats
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
16
16
16
17
18
7 Perspectives
20
7.1 Générateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.2 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
8 Annexes
21
Bibliographie
22
2
Chapitre 1
Introduction
L’objectif du travail d’étude et de recherche est l’initiation à la recherche,
par la résolution de problèmes et le travail, à un niveau réduit, d’un chercheur.
Ce TER a pour but l’étude d’un problème et la recherche d’algorithme pour
le résoudre, plus précisément spécifier et implanter un solveur de grilles
Nurikabe. Le solveur doit être intégré dans une interface graphique, pas
nécessairement évoluée, permettant à un utilisateur de charger et sauvegarder des grilles, résoudre manuellement des grilles, et enfin demander la
résolution automatique de la grille.
Nurikabe vient du japonais « je peins les murs en noir ». Dans le folklore japonais, un « Nurikabe » est un mur invisible bloquant les routes et sur lequel
s’attarder est maudit. Le jeu a été inventé et baptisé par Nikoli, à qui l’on
doit entre autres Sudoku et Kakuro. Ce jeu, quelquefois appelé « ı̂les dans
le courant » ou que les Anglais connaissent sous le nom de Cell Structure,
est un puzzle à résolution binaire [4].
3
Chapitre 2
Principe du jeu
2.1
Règles du jeu
Le puzzle se joue sous forme d’une grille rectangulaire de taille variable.
Au départ, certaines cases de la grille contiennent un nombre entier, les
autres sont grises. Le but du jeu est de déterminer, pour chaque case grise,
si elle est blanche ou noire. Les cases noires forment « le Nurikabe » : elles
doivent toutes être orthogonalement jointes i.e. elles doivent former un polyomino unique, aucune d’entre elles ne doit contenir de numéro et il ne
peut y avoir de bloc 2x2 de cases noires. Les cases blanches forment les ı̂les :
chaque case contenant un nombre n doit faire partie d’un n-omino composé
uniquement de cases blanches. Une case blanche ne peut appartenir qu’à
une seule ı̂le et chaque ı̂le ne contient qu’une seule case numérotée.
2.2
Tactiques de base
Plusieurs tactiques de base sont facilement applicables pour résoudre une
grille.[1]
4
2.2.1
Ile complète
Une ı̂le est complète si elle contient autant de cases que le nombre qui lui
est affecté. Chaque ı̂le estampillée du chiffre ’1’ est trivialement complète.
Lorsqu’une ı̂le est complète, chaque cellule voisine doit être noire. L’image
suivante montre en rouge les cases à noircir étant donnée une ı̂le nécessitant
une seule case.
Fig. 2.1 – L’ı̂le unicellulaire est d’ores et déjà complète
2.2.2
Iles voisines
Puisque deux cases numérotées ne peuvent appartenir à la même ı̂le, toute
case ayant deux voisins numérotés doit être noire. Deux cas se présentent :
lorsque la case est entre deux cases numérotées ou quand deux cases
numérotées sont diagonalement adjacentes, comme le montre l’image 2.2.
Cette règle s’étend bien sûr pour deux cases blanches non nécessairement
numérotées mais dont on sait qu’elles n’appartiennent pas à la même ı̂le.
Fig. 2.2 – Chaque case rouge est voisine de deux ı̂les différentes
5
2.2.3
Unique possibilité de développement
Si une ı̂le, d’après sa taille requise, ne compte pas encore suffisament de cases,
et si elle n’a qu’une seule case voisine, alors cette dernière ne peut être noire,
elle doit appartenir à l’ı̂le. De la même façon, cette tactique s’applique pour
les cases noires. L’image suivante montre en vert le résultat pour deux ı̂les,
le noircissement de leurs cases voisines puisqu’elles deviennent complètes, et
en rouge le résultat pour des cases noires.
Fig. 2.3 – Développement selon les possibilités
2.2.4
Case inatteignable
Si aucune ı̂le ne peut s’étendre suffisamment loin pour atteindre une case,
alors cette case doit être noire. Sur l’image 2.4, les cases que chacune des ı̂les
peut atteindre sont colorées. Dans le cas présent, une seule case, indiquée
par la flèche, est toujours grise, donc inatteignable.
Fig. 2.4 – L’unique case grise n’est atteignable par aucune ı̂le
6
2.2.5
Coude noir
Si trois cases noires offrent une configuration en forme de ’L’, alors la case
à l’intérieur du coude doit être blanche pour éviter d’avoir un carré 2x2 de
cases noires. L’image ci-dessous présente un tel coude.
Fig. 2.5 – La case verte doit être blanchie pour éviter un bloc carré noir
2.2.6
Case condamnée
S’il ne manque plus qu’une seule case à une ı̂le pour être complète, et toutes
les cases pouvant appartenir à l’ı̂le ont la même case voisine, alors cette
case doit être noire. Ce cas de figure arrive typiquement lorsqu’une case
numérotée par ’2’ se trouve dans un coin de la grille ou si deux de ses
quatre voisins sont des cases noires diagonalement adjacentes. Sur l’image
ci-dessous, les remplissages possibles de deux ı̂les sont colorés en bleu-gris
et les cases condamnées le sont en rouge.
Fig. 2.6 – Les deux cases rouges sont forcément noires car un de leur voisins
doit devenir blanc
7
Chapitre 3
Formalisation
3.1
Le jeu formalisé
Pour formaliser le jeu, on abstrait les différents éléments sous forme
de graphe [6]. Ses sommets correspondent aux cases noires et blanches de la
grille et ses arcs définissent le lien de voisinage de deux cases. La composante
noire représente le mur. Chaque ı̂le est considérée comme une composante
blanche. Il est ainsi plus aisé de vérifier la connexité d’une composante. De
plus, la taille d’une ı̂le correspond dès lors à la cardinalité de la composante
blanche qui la caractérise.
On peut ainsi interpréter la notion d’atteignabilité d’une case par une ı̂le.
En effet, une ı̂le est un sous-graphe de la grille dont on connaı̂t la cardinalité.
Pour savoir si une case est atteignable par une ı̂le, il faut chercher si la taille
du chemin joignant l’ı̂le à la case est inférieure ou égale à la taille requise de
l’ı̂le moins sa taille courante.
La règle de l’unique possibilité de développement d’une ı̂le (cf. §2.3, page
6) peut être traduite en terme de graphe. Ce cas de figure intervient pour
une ı̂le non complète, lorsqu’un sommet n’a qu’un seul somment adjacent
qui n’est pas noir ; ou pour les sommets du sous-graphe représentant le mur,
lorsqu’un sommet n’a qu’un seul somment adjacent qui n’est pas blanc.
3.2
Terminologie
Afin d’utiliser un vocabulaire bien précis pour décrire les règles utilisées
sur les tables Nurikabe, une terminologie a été définie dans le cadre de ce
TER :
– Grille correcte : grille admettant une solution,
– Grille simple : grille admettant une unique solution,
– Graine : case blanche fournie au début de la grille contenant un entier,
– Mur : composante connexe noire,
– Ile : composante connexe blanche,
8
– Taille d’une ı̂le : cardinal de sa composante,
– Taille requise d’une ı̂le : nombre indiqué sur sa graine,
– Case non déterminée : case dont on ne sait pas à quel type de composante elle appartient,
– Case semi-déterminée : case dont on sait qu’elle appartient à une ı̂le,
mais pas encore à laquelle,
– Ile complète : ı̂le dont la taille est égale à la taille requise,
– Case atteignable : case jusqu’à laquelle au moins une ı̂le peut s’étendre,
– Cases voisines : cases ayant un côté en commun.
3.3
NP-complétude
La résolution d’une grille Nurikabe est un problème NP-complet. En
effet, tout problème NP-complet peut être réduit à un circuit booléen et le
problème d’un circuit booléen peut être réduit à celui du Nurikabe. [5]
9
Chapitre 4
Solveur
4.1
Approches possibles
Deux principales approches de résolution de grilles Nurikabe ressortent.
D’abord on peut résoudre une grille simple en appliquant les règles simples
ou tactiques de base (cf. §2.2, page 4).
Autrement, on peut utiliser la force brute en développant un arbre de possibilités, mais le nombre de possibilités calculées pour une grille contenant N
cases serait 2N . Même avec élagage, le nombre de branches de l’arbre rend
cette solution irréaliste.
Il aurait été possible d’adopter un système expert, la programmation par
contrainte ou encore les réseaux neuronaux, mais je n’ai pas évalué la faisabilité de ces approches.
4.2
Approche personnelle
En ce qui concerne le présent projet, la première approche a été
développée. En supplément des tactiques de base (cf. §2.2, page 4), de nombreuses règles élaborées ont été définies pour éviter le plus souvent d’émettre
des hypothèses. [7, 8]
10
4.2.1
Case semi-déterminée adjacente
Si une case semi-déterminée a un voisin blanc, alors elle appartient à la
même ı̂le que ce voisin. Sur l’image suivante, la case verte devient blanche
pour éviter qu’un bloc 2x2 noir se forme, et la case numérotées par ’3’ étant
blanche, la case verte appartient à son ı̂le.
Fig. 4.1 – La case verte est blanche pour éviter qu’un coude noir se forme
et appartient à l’ı̂le numérotée par ’3’
4.2.2
Case atteignable par une seule ı̂le
Si une case semi-déterminée n’est atteignable que par une seule ı̂le, alors
elle appartient à cette ı̂le. Sur l’image 4.2, les deux cases blanches en haut
à gauche de la grille ne sont atteignables que par l’ı̂le numérotées par ’6’.
Fig. 4.2 – Les deux cases blanches ne sont atteignable que par l’ı̂le ’6’, elle
lui appartiennent
11
4.2.3
Unique chemin possible d’une ı̂le
Si le nombre de cases non déterminées atteignables par une ı̂le est égal à la
différence entre la taille requise de cette ı̂le et sa taille, alors ces cases sont
blanches et appartiennent à l’ı̂le. Sur l’image suivante, l’ı̂le formée par la
case ’3’ en bas à gauche de la grille ne peut de développer que via les deux
cases vertes. Elles doivent donc être blanches et appartenir à l’ı̂le.
Fig. 4.3 – L’ı̂le ’3’ est désormais complète
4.2.4
Case encerclée
Si tous les voisins d’une case non déterminée sont de la même couleur, alors
cette case est aussi de cette couleur. L’image 4.4 montre la case rouge encerclée par quatre cases noires, elle doit donc être noire également.
Fig. 4.4 – La case rouge devient noire car elle est encerclée par quatre cases
noires
12
4.2.5
Contradiction apparente
Dans un graphe connexe, un sommet est dit point darticulation si le sousgraphe obtenu en le supprimant nest pas connexe. Par conséquent, il contient
plus dun sous-graphe.
Il arrive parfois qu’une case soit un point d’articulation du graphe de la grille.
Dans le cas décrit sur l’image 4.5, la case verte est un point d’articulation
de l’ı̂le ’5’. En effet, si on la coloriait en noir, l’ı̂le ne serait plus connexe.
Elle doit donc devenir blanche pour en éviter la déconnexion.
Fig. 4.5 – Pour pouvoir résoudre cette grille, la case verte doit être blanche
4.2.6
Espace nécessaire
Il arrive parfois qu’en tentant de développer une composante blanche ou
noire, il n’y ait pas suffisamment d’espace pour permettre à une composante
voisine de s’étendre. Il faut alors choisir une autre alternative. Sur l’image
ci-dessous, la composante noire doit se développer via la case rouge pour se
connecter aux autres cases noires. Ainsi la case verte doit être blanche pour
permettre à l’ı̂le numérotée par ’3’ de se développer.
Fig. 4.6 – La case verte doit être blanche et la case rouge doit devenir noire
13
4.2.7
Information selon les chemins possibles d’une ı̂le
Si tous les chemins joignant une ı̂le à une case atteignable par elle permettent
de déduire une même information à propos d’une tierce case, alors cette
information est vraie. Sur l’image ci-dessous, la case blanche en bas à droite
appartient à l’ı̂le ’7’. Selon les chemins possibles joignant l’ı̂le à cette case
blanche, les cases rouges se trouvent à coup sûr en bordures des chemins
potentiels alors que les cases vertes seront forcément propriétés de l’ı̂le.
Fig. 4.7 – Les cases vertes faisant partie de l’intersection des chemins possibles de l’ı̂le, elles sont blanches. Les cases rouges se trouvant alors en bordures deviennent noires
14
Chapitre 5
Implémentation
5.1
Choix techniques
Pour implémenter le jeu, le langage de programmation orientée objet
Java a été choisi.
Le solveur est par une classe à part entière. Chaque règle utilisée est
implémentée dans une méthode. Pour simuler la résolution d’une grille, on lui
applique ces règles les unes après les autres en la soumettant aux méthodes
correspondantes jusqu’à ce qu’elle soit résolue. Pour chaque situation décrite
par une règle bien précise, la grille est modifiée selon ces méthodes.
Plusieurs classes ont été créées pour matérialiser une grille Nurikabe.
5.1.1
La classe Grille
Elle hérite de la classe JPanel et comporte :
– un tableau de classes Case,
– un Vector de classes Ile, collectant les ı̂les de la grille,
– une instance de la classe Mur,
– un Vector de classes Bloc.
Une grille se construit selon une grammaire prédéfinie décrivant ses dimensions et l’état de chaque case.
5.1.2
La classe Case
Elle hérite également de la classe JPanel, permettant de dessiner chaque
case de la grille. Chaque instance de la classe est grise au départ et deviendra soit blanche et appartiendra à une ı̂le, soit noire et composera le mur.
Chacune comprend :
– un champ couleur, instance de la classe Color,
– un champ indice, instance de la classe String, représentant le numéro
que porte la case si tel est le cas, égal à null sinon,
15
– nord, sud, est, ouest, quatre instances de la classe Case, correspondant
aux quatre voisins de la case courante,
– un Vector de classes Ile enregistrant les ı̂les atteignant la case.
5.1.3
La classe Ile
Elle représente le graphe de cases blanches d’une même ı̂le. Elle est composée par :
– un entier tailleRequise correspondant à l’entier porté par une des cases
de l’ı̂le renseignant de la taille requise pour celle-ci,
– un Vector de classes Case contenant les cases appartenant à l’ı̂le,
– un Vector de classes Case regroupant les cases atteignables par l’ı̂le,
– un Vector de classes Case collectant les cases voisines de l’ı̂le.
5.1.4
La classe Mur
Elle permet de recenser les cases noires de la grille. Elle représente le
graphe de case noires. Elle comprend un Vector de classes Case contenant
toutes les cases noires.
5.1.5
La classe Bloc
Elle permet de regrouper tous les blocs 2x2 de cases de la grille. Cette
classe facilitera la détection de coude noir pour éviter un bloc 2x2 de cases
noires. Elle comporte quatre instances de la classe Case : un, deux, trois,
quatre, correspondant aux quatre cases formant un bloc 2x2 comme suit :
1 2
3 4
5.1.6
La classe CaseMouseListener
Elle permet à la classe Grille de se modifier selon les clics de la souris.
Lorsque l’on clique sur une case, sa couleur change selon le cycle suivant :
gris → noir → blanc → gris → etc..., si l’on a cliqué avec le bouton gauche
de la souris, ou gris → blanc → noir → gris → etc..., avec le bouton droit.
5.1.7
La classe Solveur
Elle permet de lancer les tactiques de base, les règles de résolution plus
élaborées et d’émettre des hypothèses si nécessaire, tant que la grille n’est
pas résolue.
5.1.8
La classe Nurikabe
Elle permet de construire l’interface graphique et de gérer tous les
évènements qui en découlent (cf. §5.2).
16
5.2
Interface
Tout d’abord, la fenêtre nécessaire à l’interface graphique est une
JFrame. On y ajoute une barre de menus proposant de sauvegarder l’état de
la grille sur laquelle on joue, de charger une grille depuis un fichier texte où
est écrit une grammaire ou de quitter le jeu. Ensuite on ajoute un premier
JPanel contenant quatre boutons : Vérifier, Solution, Zoom, Unzoom, dont
les actions sont respectivement : vérifier si la solution proposée par le
joueur est correcte, afficher la bonne solution de la grille courante, faire un
zoom en avant sur la grille et zoomer en arrière. Enfin un dernier JPanel
contiendra la grille une fois chargée.
Pour sauvegarder ou charger une grille, on utilise sa grammaire EBNF.
Celle-ci permet l’interopérabilité et la comparaison de différents solveurs.
Elle décrit la table Nuriabe selon le modèle suivant :
nurikabe = [comment], width, sep, height, sep, unsolved, {[sep, solution]} ;
comment = ’{’, {character - ’}’}, ’}’ ;
character = ? any character ? ;
width = num ;
height = num ;
sep = ”:” ;
unsolved = {seed | unknown | eor} ;
solution = {seed | unknown | wall | island | eor} ;
seed = num ;
unknown = ”.” ;
wall = ”]” ;
island = ” ” ;
eor = ”/” ;
num = {digit} ;
digit = ”0” | ”1” | ”2” | ”3” | ”4” | ”5” | ”6” | ”7” | ”8” | ”9” ;
17
Fig. 5.1 – Voici l’interface graphique du jeu Nurikabe
18
Chapitre 6
Résultats
Le solveur implémenté, des tests de performance s’imposent. Le temps de
résolution est pour cela mesuré pour chaque grille. Une moyenne est calculée
selon les dimensions du puzzle, puis reportée sur le graphique « Résultats »
(cf. §6.1, page 19). Celui-ci représente le temps de résolution du solveur en
millisecondes par rapport à la dimension de la grille, c’est-à-dire le nombre
de cases qu’elle contient. La courbe qui en résulte montre bien que le temps
de résolution n’est pas linéaire, mais plutôt exponentiel. Il est à noter que,
pour des grilles relativement simples, la résolution s’effectue en un temps très
court. Tandis que, pour des grilles nécessitant une résolution par hypothèses,
ce temps devient très grand, mais le programme reste toujours plus rapide
que l’humain.
19
Fig. 6.1 – Résultats
20
Chapitre 7
Perspectives
Pour aller plus loin dans le développement du Nurikabe, deux principales
idées peuvent être approfondies. On pourrait implémenter un générateur de
grilles aléatoires dans un premier temps, puis la conception en 3D apporterait une nouvelle approche du jeu.
7.1
Générateur
La première perspective serait d’intégrer un générateur de grilles. L’idée
se résumerait, à partir d’une grille composée uniquement de cases noires, à
colorer au hasard une case en blanc en vérifiant qu’aucune règle de base n’est
enfreinte. Une fois la grille finale obtenue et correcte, on décide au hasard
de désigner une case par ı̂le pour porter le numéro correspondant à la taille
requise de l’ı̂le. Et on grise alors toutes les cases vierges de numéro.
Le principal problème serait le temps de génération, qui pourrait croı̂tre de
manière trop importante en fonction de la dimension d’une grille.
7.2
3D
Une autre perspective consisterait à générer et résoudre des grilles en 3D,
présentées sous forme de parallélépipède rectangle. Les règles qu’on utilise
sont extensibles à la 3D. Dans ce cas figure, une case n’aurait plus quatre
voisins, mais six ; une ı̂le pourrait s’étendre sur plusieurs face du prisme
droit et à l’intérieur de ce dernier ; et de la même manière le mur devrait
être connexe dans tout le parallélépipède.
21
Chapitre 8
Annexes
22
Bibliographie
[1] Logic Games Online : http ://www.logicgamesonline.com/nurikabe/
[2] Nikoli : http ://www.nikoli.co.jp/en/puzzles/nurikabe/
[3] Puzzlinks : http ://puzzlinks.com/tag/nikoli
[4] Wikipedia :Nurikabe : http ://en.wikipedia.org/wiki/Nurikabe
[5] Poster sur la NP-complétude du Nurikabe : http ://www.reed.edu/ mcphailb/poster.pdf
[6] Graph Theory (Reinhard Diestel) : http ://www.math.unihamburg.de/home/diestel/books/graph.theory/index.html
[7] Introduction à l’algorithmique (Thomas H. Cormen et al.)
[8] Cours d’algorithmique de Julián Mestre de l’Université du Maryland :
http ://www.cs.umd.edu/class/summer2006/cmsc451/lectures.html
23

Documents pareils