CSC_41011 · TD3
Pour commencer :
Ce sujet aborde la programmation du jeu de Hex.
Hex est un jeu pour deux joueurs, que l’on appelle Rouge et Bleu. Il se joue sur un plateau en losange pavé par des cases hexagonales, de taille libre, mais typiquement 11×11. Chaque joueur possède deux bords opposés du plateau. Rouge joue en premier. Les joueurs s’emparent tour à tour des cases vides du plateau en les marquant de leurs couleurs. Le premier joueur qui parvient à relier ses deux bords par une suite de cases adjacentes de sa couleur gagne la partie.
Si l’on joue sur un plateau n × n, on peut identifier les cases par des coordonnées (i, j) avec i et j des entiers entre 1 et n inclus. On convient que Rouge possède les bords haut et bas, tandis que Bleu possède les bords gauche et droit.
L’interface graphique (fournie) comporte :
Reset
(bouton) : réinitialise le plateau.Labels
, Coords
, Colors
(cases
à cocher) : affichages d’aide (identifiants, coordonnées, couleurs des
cases).Human
, Random
,
Heuristic
.Play
(bouton) : fait jouer automatiquement les joueurs
en mode IA ; en mode Human
, cliquez sur une case pour
jouer.HexGUI
s’appuie sur la classe Hex
pour
l’état et les règles du jeu. Lancez Hex
pour afficher le
plateau. Au fil des questions, complétez la classe Hex
(champs, méthodes, constructeur Hex(int n)
).
Au lancement, certaines commandes ne fonctionnent pas tant que vous
n’avez pas codé la logique dans Hex
:
click(i, j)
et
currentPlayer()
.Labels
nécessite une implémentation utile de
label(i, j)
.Colors
suppose un plateau correctement initialisé dans
le constructeur et lu par get(i, j)
.Play
et les menus IA (Random
,
Heuristic
) nécessitent randomMove()
,
heuristicMove()
et un winner()
opérationnel.Implémentez la méthode Player get(int i, int j)
qui
renvoie le joueur possédant la case (i, j)
(Player.RED
ou Player.BLUE
), ou
Player.NOONE
si cette case n’a pas encore été jouée. Pour
représenter les bords, on permettra à i et j de prendre les valeurs 0 ou n + 1.
Vous pouvez introduire un champ Player[][] grid
correctement initialisé.
Déposez Hex.java
.
Exécutez Hex
et utilisez la case Colors
pour vérifier l’initialisation du plateau.
Un plateau correctement initialisé.
Implémentez la méthode boolean click(int i, int j)
dont
l’appel signale que le joueur dont c’est le tour joue la case (i, j). Si c’est un coup
légal, la méthode met à jour l’état du plateau et renvoie
true
. Sinon elle ne fait rien et renvoie
false
.
Implémentez la méthode Player currentPlayer()
qui
renvoie le joueur dont c’est le tour.
Déposez Hex.java
.
Vous devriez pouvoir jouer à Hex en exécutant Hex
. Le
bouton Reset
permet de réinitialiser l’état du plateau.
On souhaite maintenant que l’interface signale quand l’un des joueurs remporte la partie.
Implémentez la méthode Player winner()
qui renvoie le
joueur dont la position est gagnante, ou Player.NOONE
si
aucun des deux n’a encore gagné. Vous pouvez utiliser une structure de
données union-find et associer l’entier i + (n + 2)j à la
case (i, j).
Modifiez la méthode currentPlayer()
pour qu’elle renvoie
Player.NOONE
lorsque l’un des joueurs a gagné la
partie.
Déposez Hex.java
.
Pour faciliter le débogage, vous pouvez modifier la méthode
int label(int i, int j)
pour, par exemple, qu’elle renvoie
l’identifiant de composante connexe de la case (i, j). Ces identifiants
peuvent être affichés dans l’interface graphique en cochant la case
Labels
.
Exemple (stratégiquement peu inspiré) d’un plateau avec l’affichage des identifiants des composantes connexes.
Implémentez la méthode boolean randomMove()
dans
Hex
. Cette méthode joue un coup aléatoire pour le joueur
dont c’est le tour, met à jour l’état du jeu comme si
click(i, j)
avait été appelé sur la case choisie, et
renvoie true
si un coup a été effectivement joué,
false
sinon (partie terminée).
Peut-on l’implémenter en complexité O(1) en moyenne sur une suite de n2 appels ?
Déposez Hex.java
.
Implémentez la méthode boolean heuristicMove()
dans
Hex
, avec la même spécification que
randomMove()
, mais en essayant de mieux jouer.
Stratégie possible : à partir de l’état actuel, simuler une partie avec des coups alternés jusqu’à la victoire de l’un des joueurs. Le dernier coup simulé, celui qui mène à la victoire, est sûrement un coup valable.
Déposez Hex.java
.
Défiez vos camarades.