1 Le jeu «Puissance 4»



Documents pareils
Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Premiers Pas en Programmation Objet : les Classes et les Objets

TD3: tableaux avancées, première classe et chaînes

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Programmer en JAVA. par Tama

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Utilisation d objets : String et ArrayList

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Corrigés des premiers exercices sur les classes

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Plan du cours. Historique du langage Nouveautés de Java 7

Un ordonnanceur stupide

Solutions du chapitre 4

Programmation avec des objets : Cours 7. Menu du jour

Chapitre 10. Les interfaces Comparable et Comparator 1

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Tp 1 correction. Structures de données (IF2)

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Java Licence Professionnelle CISII,

Projet de programmation (IK3) : TP n 1 Correction

Cours d initiation à la programmation en C++ Johann Cuenin

TP, première séquence d exercices.

LES TYPES DE DONNÉES DU LANGAGE PASCAL

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Corrigé des exercices sur les références

TD/TP PAC - Programmation n 3

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Objets et Programmation. origine des langages orientés-objet

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

TP1 : Initiation à Java et Eclipse

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

TP : Gestion d une image au format PGM

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

TD/TP PAC - Programmation n 3

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

as Architecture des Systèmes d Information

Programmation en Java IUT GEII (MC-II1) 1

Présentation du langage et premières fonctions

ACTIVITÉ DE PROGRAMMATION

OpenPaaS Le réseau social d'entreprise

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Poker. A rendre pour le 25 avril

Introduction à MATLAB R

Les structures. Chapitre 3

Chapitre 2. Classes et objets

IMAGES NUMÉRIQUES MATRICIELLES EN SCILAB

Anne Tasso. Java. Le livre de. premier langage. 10 e édition. Avec 109 exercices corrigés. Groupe Eyrolles, , ISBN :

Généralités sur le Langage Java et éléments syntaxiques.

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Programme Compte bancaire (code)

Programmation par les Objets en Java

2. Comprendre les définitions de classes

Auto-évaluation Programmation en Java

Langage Java. Classe de première SI

ALGORITHMIQUE ET PROGRAMMATION ORIENTEE OBJET

Cours 1: Java et les objets

Chap III : Les tableaux

1 CRÉER UN TABLEAU. IADE Outils et Méthodes de gestion de l information

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Conventions d écriture et outils de mise au point

TP1. Outils Java Eléments de correction

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Gestion distribuée (par sockets) de banque en Java


Algorithme. Table des matières

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Programmation Par Objets

Langage et Concepts de Programmation Objet. 1 Attributs et Méthodes d instance ou de classe. Travaux Dirigés no2

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

EXCEL TUTORIEL 2012/2013

Cours 1 : Qu est-ce que la programmation?

Package Java.util Classe générique

Le langage C. Séance n 4

Programmation Objet I

Introduction à la programmation concurrente

Apprendre Java en 154 minutes

Prendre le marteau, le tableau, le mètre, le crayon, la ficelle, le clou, la pointe ;

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

IV- Comment fonctionne un ordinateur?

Introduction au langage C

Débuter avec EXPRESS. Alain Plantec. 1 Schema 2

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Programmation Orientée Objet

STAGE IREM 0- Premiers pas en Python

Bases Java - Eclipse / Netbeans

TP 1. Prise en main du langage Python

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Exercices sur les interfaces

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

PROGRAMMATION PAR OBJETS

Chapitre VI- La validation de la composition.

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Projet Matlab : un logiciel de cryptage

Programmation Objet Java Correction

Transcription:

Université de Nice-Sophia Antipolis Deug MIAS-MI 1 Algorithmique & Programmation 2002 2003 TP N 3 Procédures et fonctions Buts : Manipuler des objets complexes Tableaux à deux dimensions Usage des sentinelles Utilisation des constantes Apprendre à modifier un programme 1 Le jeu «Puissance 4» Ce jeu se joue à deux joueurs sur une grille rectangulaire supposée verticale. Chacun à leur tour les joueurs posent un pion en haut d une colonne non pleine : ce pion glisse vers le bas jusqu à être arrêté par un autre pion ou par le bas de la grille. Le gagnant est le premier qui aligne 4 de ses pions, horizontalement, verticalement ou en diagonale. Voici un exemple de partie en cours : 1 2 3 4 5 6 7....................... o x o... o x o x.. x x x o o.. C est à X de jouer. Il peut gagner en jouant en colonne 5 mais, s il ne le voit pas et commet l erreur de jouer en colonne 2, c est O qui pourra gagner en jouant lui aussi en colonne 2! Nous avons programmé pour vous un gestionnaire de partie pour ce jeu : un programme qui demande alternativement à deux joueurs humains 1 quel coup ils jouent, affiche l état de la partie et détermine qui gagne. Ce programme, trop long et trop complexe pour que vous l écriviez vousmême, vous est fourni dans les Documents de cours et il est reproduit à la fin de cette feuille de TP. Votre premier travail sera de le comprendre, le second sera d y faire quelques modifications pour en améliorer la programmation ou la qualité. 2 Comprendre un programme 2.1 Objets complexes Les objets définis par la classe instanciable Power4Game sont, comme leur nom l indique, des parties en cours de «Puissance 4». Le constructeur sera chargé de créer la partie dans son état initial (personne n a encore joué) et la classe exportera une seule méthode d instance, l ordre de «jouer la partie»! Regardez la classe Power4 pour voir comment la classe Power4Game est utilisée et vérifiez que toutes les autres méthodes de Power4Game sont déclarées private. 1. Programmer un jeu «humain contre ordinateur» n est pas encore de votre niveau : attendez la fin du semestre!

Les attributs d une partie en cours seront, très naturellement, l état de la grille de jeu (les coups déjà joués), les noms des joueurs (pour l affichage des dialogues), celui dont c est le tour de jouer et le résultat provisoire (la partie est-elle finie? y a-t-il un gagnant?). 2.2 Codage des joueurs Comme beaucoup de langages, Java ne dispose pas de type énuméré et, pour traduire une déclaration comme : type joueur = (joueur1, joueur2, personne) il faudra donner explicitement un codage par l ordinal de chacune des trois constantes (ici, 0, 1 et 2) et considérer ce type joueur comme un type entier. 2.3 Tableaux à deux dimensions La grille de jeu est une matrice rectangulaire qui contient des entiers (ces entiers codent l état de chaque case). Représenter une telle matrice ne pose aucun problème, il suffit de la considérer ligne par ligne : chaque case étant de type int, chaque ligne sera représentée par un tableau de type int[] et, comme on peut définir des tableaux de n importe quoi, on dira que la matrice est un tableau de lignes, donc de type int[][]. La ligne d indice line sera donc grid[][line] et sa valeur dans la colonne d indice column sera simplement grid[column][line]. Les informaticiens n utilisent pas le terme «matrice» pour désigner une telle structure, ils parlent plutôt de tableaux à deux dimensions 2. 2.4 Usage des sentinelles Pour savoir si le coup d un joueur le fait gagner, il va être nécessaire de se déplacer dans la grille de jeu et de tester la valeur de chaque case. Ce problème s apparente à celui de la recherche séquentielle (chercher une valeur dans une liste ou un tableau) et, comme lui, est compliqué par le fait qu il ne faut pas dépasser les bornes. La façon la plus simple de s en sortir est de placer des sentinelles, valeurs fictives, juste hors des bornes, pour lesquelles le résultat de la recherche est connu d avance et qui permettront de s arrêter sans avoir à tester qu on reste dans les bornes. Ici, on va entourer la grille de jeu de deux lignes et de deux colonnes supplémentaires dans lesquelles, bien sûr, il sera toujours interdit de jouer! Ainsi, quand on cherchera des alignements, la présence de ces cases vides arrêtera la recherche sans que d autres tests soit nécessaires. Et, évidemment, on n affichera pas ces cases fictives quand on affichera la grille de jeu. 2.5 Utilisation des constantes Java ne connaissant ni les types énumérés ni les intervalles, un très grand nombre des valeurs manipulées par un programme seront des entiers, soit comme valeur effective, soit comme codage, et il serait très facile de s y perdre : Qu est-ce que «2» dans un programme? Le nombre entier par lequel on multiplie une valeur pour la doubler? un indice dans un tableau? la troisième constante d un type énuméré? Et supposons que ce soit le dernier cas et que, mettant le programme au point, on s aperçoive qu il faut modifier le type énuméré et que cette constante devienne la cinquième : comment savoir quels sont, dans le programme, les «2» qu il faut remplacer par des «4»? 2. Beaucoup de langages de programmation (et notre langage algorithmique) permettent d utiliser l écriture équivalente grid[column,line] ; ce n est pas le cas de Java.

Toutes ces difficultés sont résolues par l usage systématique de constantes nommées. Le programme donné ne lésine pas là-dessus et c est ainsi qu il faut procéder 3. Examinons en détail ces déclarations : les lignes 7 à 9 codent le type énuméré «joueur» mais aussi les indices du tableau de la ligne 10 qui dit quel caractère doit être affiché selon l état de la case ; comme les lignes 12 et 13 déclarent une trop grande grille (à cause des sentinelles), les lignes 14 et 17 donnent des noms explicites aux indices où commence et finit le plateau de jeu réel ; les lignes 19 et 20 précisent que, quand un tableau de deux éléments représente un vecteur, son premier indice correspond à l horizontale, son second à la verticale (ces constantes seront utilisées entre les lignes 74 et 83) ; les lignes 21 à 24 ne servent qu à indiquer la signification de la ligne 25, les constantes qu elles définissent ne seront plus jamais utilisées ensuite! enfin, cette ligne 25 précise les directions dans lesquelles on cherchera des alignements de quatre pions. Dans un premier temps, les meilleurs d entre vous penseront sans doute que ce travail de déclaration est fastidieux, qu ils ne sont pas des imbéciles et qu ils n ont pas de temps à perdre avec ça. Ce n est pas grave, ils changeront d avis quand ils s apercevront qu ils ne sont plus les meilleurs. 2.6 Variables d instance La variable impactline déclarée en ligne 34 joue un rôle un peu particulier : elle ne sert qu à mémoriser la ligne d arrivée d un pion, déterminée par la procédure play, le temps qu elle soit utilisée comme argument de iswinning en ligne 127. Une programmation peu soigneuse pourrait la mettre avec les attributs (elle se déclare exactement de la même façon) et, bien sûr, ça marcherait. Cependant, il est difficile de la considérer comme un attribut au sens «objet» du terme, elle n est qu un intermédiaire, non une caractéristique de la partie en cours et, d ailleurs, on serait bien en peine de la faire initialiser par le constructeur! Le mieux est de la considérer comme une sorte de variable locale, tout comme les indices de boucles ou celles qui servent à échanger deux valeurs. Si l on tient à la terminologie objet, on pourra éventuellement parler de variable d instance. 3 Modifier un programme À présent que vous avez à peu près compris comment marche ce programme, nous allons voir si vous êtes capables de lui faire subir quelques améliorations ou modifications mineures. Les exercices proposés sont tous indépendants et ils doivent être réalisés sans bouleverser le programme de façon importante. a. Modifiez le programme pour que, quand il affiche l état de la partie, il dise aussi à qui c est le tour de jouer. b. La convention qui a été choisie est de numéroter les lignes de bas en haut. Ce n est pas la convention usuelle en informatique. Modifiez le programme pour qu elles soient numérotées de haut en bas. c. Les lignes 98 et 99 sont un peu violentes car elles peuvent interrompre la partie pour une simple faute de frappe. Modifiez le programme pour que, si un joueur joue dans une colonne pleine, on lui signale son erreur et on lui demande un autre choix. d. La méthode playable est un peu lourde puisqu elle réexamine toutes les têtes de colonne à chaque coup alors qu elles ne changent pas souvent. Modifiez le programme pour que la fin de partie par impossibilité de jouer (partie nulle) soit décelée plus économiquement. e. (difficile) On change les règles en déclarant qu un alignement de quatre pions est aussi gagnant s il est réalisé selon la marche du cavalier aux échecs (c est-à-dire selon une pente 2, 2, 1/2 ou 1/2). Modifiez le programme pour tenir compte de cette nouvelle règle. Faites-le de telle sorte qu on puisse revenir très facilement aux anciennes règles. 3. Il aurait même été encore plus propre de les déclarer private.

f. (difficile) Il n est pas facile de repérer les alignements. Modifiez le programme de telle sorte que, quand un joueur gagne, l alignement qu il vient de compléter soit mis en majuscules. g. (programme d imitation, facultatif) Le jeu japonais appelé gomoku se joue avec les règles de notre «morpion» (un joueur a les X, l autre les O, ils jouent chacun leur tour en posant leur pion sur une intersection d un quadrillage, le premier qui aligne cinq a gagné) à la seule différence que la zone de jeu est un carré. Dans la variante la plus jouée, appelée gomoku ninuki, une règle de prise est ajoutée : quand un joueur, au moment où il joue, prend deux pions adverses en tenaille avec un autre de ses pions, ils sont considérés comme prisonniers et retirés du jeu (par exemple, si X joue sur le point dans la position X O O., la situation devient X.. X ; en revanche, O peut sans danger jouer sur le point dans une position X O. X ). La prise peut être multiple et, comme l alignement, elle se fait dans n importe quelle direction. Le gagnant est le premier qui a aligné cinq ou fait dix prisonniers. Programmez le jeu de base ou la variante. La classe instanciable Power4Game 1 import unsa.console ; 2 3 public class Power4Game { 4 5 // CONSTANTES 6 // joueurs 7 final static int PLAYER_1 = 0 ; 8 final static int PLAYER_2 = 1 ; 9 final static int EMPTY = 2 ; 10 final static char[] SYMBOL = new char[] { x, o,. } ; 11 // coordonnées 12 final static int GRID_WIDTH = 9 ; // 7 + sentinelles 13 final static int GRID_HEIGHT = 8 ; // 6 + sentinelles 14 final static int FIRST_COL = 1 ; 15 final static int LAST_COL = GRID_WIDTH - 2 ; 16 final static int TOP_LINE = GRID_HEIGHT - 2 ; 17 final static int BOTTOM_LINE = 1 ; 18 // directions 19 final static int H = 0 ; // horizontalement 20 final static int V = 1 ; // verticalement 21 final static int[] HOR = new int[] {1, 0} ; // horizontale 22 final static int[] VER = new int[] {0, 1} ; // verticale 23 final static int[] UP = new int[] {1, 1} ; // diagonale montante 24 final static int[] DOWN = new int[] {1, -1} ; // diagonale descendante 25 final static int[][] DIRECTION = new int[][] {HOR, VER, UP, DOWN} ; 26 27 // Attributs 28 private int[][] grid ; // grille de jeu 29 private String[] name ; // noms des joueurs 30 private int player ; // qui doit jouer 31 private int result ; // vainqueur ou partie nulle (si EMPTY) 32 33 // Variable d instance 34 private int impactline ; // ligne atteinte par le dernier pion joué 35

37 public Power4Game (String[] name) { // noms des joueurs 38 // tout mettre à vide, y compris les sentinelles! 39 grid = new int[grid_width][grid_height] ; 40 for (int i = 0 ; i < GRID_WIDTH ; i++) { 41 for (int k = 0 ; k < GRID_HEIGHT ; k++) 42 grid[i][k] = EMPTY ; 43 } 44 this.name = name ; 45 player = PLAYER_1 ; 46 result = EMPTY ; 47 } 48 49 // Fonctions 50 private boolean isfree (int column) { 51 return grid[column][top_line] == EMPTY ; 52 } 53 private boolean playable () { 54 // cherche s il existe une colonne libre 55 int column = FIRST_COL ; 56 while (column <= LAST_COL) { 57 if (isfree(column)) 58 return true ; 59 column++ ; 60 } 61 return false ; 62 } 63 private boolean iswinning (int column, int line) { 64 // cherche s il existe une direction alignant 4 65 int i = 0 ; 66 while (i < DIRECTION.length) { 67 if (iswinning(column, line, DIRECTION[i])) 68 return true ; 69 i++ ; 70 } 71 return false ; 72 } 73 private boolean iswinning (int column, int line, int[] dir) { 74 int nextcolumn = column + dir[h] ; int nextline = line + dir[v] ; 75 int forward = 0 ; // nombre de cases du joueur vers l avant 76 while (grid[nextcolumn][nextline] == player) { 77 nextcolumn += dir[h] ; nextline += dir[v] ; forward++ ; 78 } 79 // reculer 80 nextcolumn = column - dir[h] ; nextline = line - dir[v] ; 81 int backward = 0 ; // nombre de cases du joueur vers l arrière 82 while (grid[nextcolumn][nextline] == player) { 83 nextcolumn -= dir[h] ; nextline -= dir[v] ; backward++ ; 84 } 85 return backward + 1 + forward >= 4 ; 86 } 87 88 // Procédures 89 private void nextplayer () { 90 // préférer un test clair à une astuce fondée sur les valeurs 91 // arbitraires des constantes comme player = 1 - player 92 if (player == PLAYER_1) 93 player = PLAYER_2 ; 94 else 95 player = PLAYER_1 ; 96 }

97 private void play (int column) { 98 if (!isfree(column)) 99 throw new RuntimeException(" colonne p l e i n e ") ; 100 impactline = TOP_LINE ; // on sait qu elle est libre 101 while (impactline > BOTTOM_LINE && grid[column][impactline - 1] == EMPTY) 102 impactline-- ; 103 // on est en bas ou au-dessus d un pion 104 grid[column][impactline] = player ; 105 } 106 107 // Affichage 108 private void printboard () { 109 // numéros des colonnes 110 for (int column = FIRST_COL ; column <= LAST_COL ; column++) 111 System.out.print(" " + column + " ") ; 112 System.out.println() ; 113 // état de la partie 114 for (int line = TOP_LINE ; line >= BOTTOM_LINE ; line--) { 115 for (int column = FIRST_COL ; column <= LAST_COL ; column++) 116 System.out.print(" " + SYMBOL[grid[column][line]] + " ") ; 117 System.out.println() ; 118 } 119 } 120 121 // Jeu d une partie 122 public void playgame () { 123 while (result == EMPTY && playable()) { 124 printboard() ; 125 int column = Console.readInt(name[player] + " joue en colonne?") ; 126 play(column) ; // la variable impactline a reçu une valeur 127 if (iswinning(column, impactline)) 128 result = player ; 129 else 130 nextplayer() ; 131 } 132 printboard() ; 133 if (result == EMPTY) 134 System.out.println(" p a r t i e n u l l e ") ; 135 else 136 System.out.println(name[result] + " gagne") ; 137 } 138 } La classe exécutable Power4 1 public class Power4 { 2 3 public static void main (String[ ] args) { 4 // les noms des joueurs sont donnés en arguments d exécution 5 Power4Game game = new Power4Game(args) ; 6 game.playgame() ; 7 } 8 }