• Aucun résultat trouvé

Examen de Java

N/A
N/A
Protected

Academic year: 2022

Partager "Examen de Java"

Copied!
13
0
0

Texte intégral

(1)

Examen de Java

Institut d’´Electronique Fondamentale Universit´e de Paris Sud

Modalit´es - Dur´ee : 4 heures

- Tous les documents sont autoris´es.

- Les sources java r´epondant `a chaque exercice, et seulement les sources seront obligatoirement copi´es dans le r´epertoire examjava0304 (tout en minuscules) cr´e´e `a la racine de votre compte.

Nota Bene

Sauf mention contraire explicite, les diverses classes `a cr´eer seront non publiques (plus pr´ecis´ement sans modificateur de visibilit´e devant), non statiques et non abstraites.

Exercice 1 Op´erations sur des chaˆınes de caract`eres

Ecrire un programme java, contenant une seule classe publique nomm´´ eeGererChaine qui afficheen boucle le menu textuel suivant `a l’utilisateur :

1 Concatenation de deux chaines

2 Indice de premiere occurrence d’une sous-chaine 3 Commence par une sous-chaine

4 Se termine par une sous-chaine 5 Quitter

Veuillez entrer votre choix :

et qui attend un entier (entre 1 et () entr´e par l’utilisateur. Pour un choix entre 1 et 4, le programme demande ensuite `a l’utilisateur d’entrer les deux chaˆınes de l’op´eration

`

a effectuer, puis affiche le r´esultat de l’op´eration. Si le choix 5 est entr´e, on sort du programme.

On pourra se servir des m´ethodes suivantes de la classe String: 1

(2)

String concat(String s),int indexOf(String s), boolean startsWith(String s),

boolean endsWith(String s).

Le code fourni doit ˆetre court et doit ˆetre obligatoirement plac´e dans le fichier source GererChaine.java.

Exercice 2 D´etection d’erreurs

Ecrire, dans le fichier erreurs.txt les diff´erentes erreurs qui vous semblent ˆetre contenues dans le code suivant :

class maClasse { String ch = null;

String[] tabCh;

maClasse(String s, int nb) { String ch = s;

tabCh = new String[nb];

}

public void remplirIdentique(String s) { for(int i = 0; i < tabCh.length; i++)

tabCh[i] = s;

}

public static void affiche() { // Pas i <= mais i < tabCh.length for(int i = 0; i <= tabCh.length; i++)

System.out.print(tabCh[i] + " ");

} }

public class classeMain {

public void main(String args[]) { maClasse m = new maClasse(4);

// Il n’y a qu’un tableau de pointeurs, les differents // elts de tabCh ne sont pas alloues

m.affiche();

m.remplirIdentique("Le soleil est bleu");

// La methode affiche est statique m.affiche();

} }

(3)

Exercice 3. Jeu simple 3

Jeu de Tic/Tac/Toe

L’objet des exercices qui suivent est de d´evelopper un programme pour jouer au Tic Tac Toe avec l’ordinateur.

Exercice 3 Jeu simple

Les classes cr´ees pour cet exercice seront toutes mises dans un fichierobligatoirement nomm´e TicTacToeTrivial.java.

1. Cr´eer une classe publiqueTicTacToeTrivialservant juste `a contenir la m´ethode main(...). Elle contiendra juste une instruction : la cr´eation d’une nouvelle classe Jeu, d´ecrite ci-dessous.

2. Cr´eer une classe Plateau, dont le squelette est le suivant : class Plateau {

private int dimension; // Cas plus simple de plateaux carres private String[][] cases; // cases "physiques" du plateau materiel String cercle = new String("O");

String croix = new String("X");

// Constructeurs

public Plateau(int dimPlateau) {...}

public Plateau() {...}

// Acesseur

public int getDimension() {...}

// Vider le plateau

public void viderPlateau() {...}

// Affichage du plateau public void afficherPlateau() {

System.out.print("\n |");

for(int i = 0; i < dimension; i++) System.out.print(i+"|");

System.out.println("");

for(int i = 0; i < dimension; i++) System.out.print("--");

System.out.println("---");

for(int i = 0; i < dimension; i++) { System.out.print(i+" |");

for(int j = 0; j < dimension; j++) System.out.print(cases[i][j] + "|");

System.out.println("");

for(int j = 0; j < dimension; j++)

(4)

System.out.print("--");

System.out.println("---");

}

System.out.println("");

}

// Renvoyer la piece qui se trouve a la case specifiee public String getCase(int ligne, int colonne) {...}

// Le plateau est-il plein ?

public boolean plateauEstPlein() {...}

// La case est-elle vide ?

public boolean caseEstVide(int ligne, int colonne) {...}

// Jouer un coup, dont on teste la legalite

public boolean deplPiece(int qui, int ligne, int colonne) {...}

}// class Plateau

Les diff´erentes m´ethodes (toutes tr`es courtes) de Plateau doivent r´ealiser les op´erations suivantes :

- Les constructeurs devront initialiser les diff´erents champs.

- getDimension()renvoie la dimension du plateau (la valeur du champ nomm´e dimension).

- viderPlateau()met toutes les cases du plateau (les ´el´ements du tableau cases) `a la chaˆıne" ".

- afficherPlateau(), est fournie.

- getCase(int ligne, int colonne)renvoie l’´el´ement du tableaucases situ´e en ligne ligne et colonnecolonne.

- plateauEstPlein()teste s’il existe au moins une case du tableau cases qui est libre (c.`a.d. ´egale `a " ").

- caseEstVide(int ligne, int colonne) teste si l’´el´ement du tableau cases situ´e en ligne ligneet colonnecolonne est ´egal `a" ".

- deplPiece(int qui, int ligne, int colonne)met la chaˆınecroix ou la chaˆıne cercle `a la ligne ligne et `a la colonne colonne du tableau cases, en testant que les entiersligneet colonnesont compris entre0 et dimensionet que la case correspondante est vide.

3. Cr´eer une classe Jeu, dont le squelette est le suivant : class Jeu {

// qui gagne

public static final int HUMAIN_GAGNE = 0;

public static final int EGALITE = 1;

(5)

Exercice 3. Jeu simple 5

public static final int DOUTEUX = 2;

public static final int ORDINATEUR_GAGNE = 3;

// Joueurs

public static final int HUMAIN = 4;

public static final int ORDINATEUR = 5;

public static final int PERSONNE = 6;

BufferedReader stdin; // flux d’entree Plateau plateau; // le plateau de jeu // Constructeurs

public Jeu(int dimPlateau) {...}

public Jeu() {...}

// Si le jeu est fini, recommencer une partie public void rejouerUnePartie(String message) {...}

// Ordonnancement de partie : // - l’humain joue

// - on teste si l’humain a gagne // - on teste si le match est nul // - l’ordinateur joue

// - on teste si l’ordinateur a gagne // - on teste si le match est nul

public void actionsEffectuees(int aQuiLeTour) {...}

// renvoie true si "piece" a gagne (ou "piece" est "X", les // croix, ou bien "O", les ronds

boolean estCeGagne(String piece) {...}

// Selectionner le prochain coup a jouer par l’utilisateur public void humainJouerCoup() {...}

// Selectionner le prochain coup a jouer par l’ordinateur public void ordinateurJouerCoup() {...}

}// class Jeu

Les diff´erentes m´ethodes de Jeudoivent r´ealiser les op´erations suivantes : - Les constructeurs devront initialiser les diff´erents champs.

- rejouerUnePartie(String message): on recommence `a jouer une par- tie. Plus pr´ecis´ement, on vide le plateau, puis on l’affiche (en appelant les m´ethodesviderPlateau()etafficherPlateau()dePlateau; ensuite, on appelle la m´ethodeactionsEffectuees()d’ordonnancement d’une par- tie, d´ecrite ci-dessous, en sp´ecifiant que c’est `a l’humain de jouer (l’ordinateur est sympathique).

(6)

- actionsEffectuees(int aQuiLeTour) contient une boucle infinie, au sein de laquelle on teste si c’est au tour de l’humain ou de l’ordinateur (si aQuiLeTour´egalHUMAIN ouORDINATEUR)

* Si c’est au tour de l’humain, on appelle la m´ethodehumainJouerCoup(), puis on teste si l’humain a gagn´e (appel de la m´ethode estCeGagne() avec plateau.cercle en param`etre), auquel cas on sort de la boucle infinie (au moyen d’unbreak), puis on teste si le match est nul (au moyen de la m´ethodeplateauEstPlein()de la classe Plateau), auquel cas on sort de la boucle infinie, puis on met la variable aQuiLeTour `a la constanteORDINATEUR(c’est alors `a lui de jouer).

* Si c’est au tour de l’ordinateur, on appelle ordinateurJouerCoup(), puis on teste si l’ordinateur a gagn´e (appel de la m´ethodeestCeGagne() avec plateau.croix en param`etre), auquel cas on sort de la boucle infinie (au moyen d’unbreak), puis on teste si le match est nul (au moyen de la m´ethodeplateauEstPlein()de la classe Plateau), auquel cas on sort de la boucle infinie, puis on met la variableaQuiLeTour`aHUMAIN (c’est alors `a lui de jouer).

* Apr`es le test sur aQuiLeTour, on affiche le plateau (au moyen de la m´ethode afficherPlateau()de la classe Plateau.

* en dehors de la boucle infinie, on place un appel `arejouerUnePartie().

- estCeGagne(String piece) scrute les lignes, les colonnes et les deux di- agonales du tableau cases de la classe Tableau afin de savoir s’il y a un alignement de pi`eces identiques, toutes ´egales `a l’argument piece. Si c’est le cas, la m´ethode renvoietrue, sinon, elle renvoie false.

- humainJouerCoup()fait jouer l’utilisateur ; la m´ethode doit tester si le coup entr´e est l´egal, c’est-`a-dire si les entiers num´ero de ligne et de colonne entr´es au clavier sont bien compris entre0etdimension(la dimension du plateau)

; ensuite, le coup est jou´e par appel de la m´ethodedeplPiece()de la classe Plateau. Tant que le coup n’est pas l´egal, la m´ethode doit redemander une saisie `a l’utilisateur.

- ordinateurJouerCoup() fait jouer l’ordinateur de mani`ere stupide : on scrute les lignes et les colonnes une double boucle for() et si la m´ethode caseEstVide()renvoie true, on appelledeplPiece().

Exercice 4 Jeu normal et bˆete

Il s’agit ici de raffiner (ou plutˆot de rendre moins barbare) la structure d’objets pr´ec´edente, tout en gardant la mˆeme simplicit´e (ou plutˆot stupidit´e) algorithmique.

Les classes cr´ees pour cet exercice seront toutes mises dans un fichier obligatoire- ment nomm´e TicTacToeBete.java. Les classes suivantes devront ˆetre cr´ees :

(7)

Exercice 4. Jeu normal et bˆete 7 class Jeu Classe reponsable de l’ordonnancement

d’une partie class TTTIllegalAccessException

extends Exception

Exception propre du jeu

class Plateau Classe utilitaire pour l’interface avec l’utilisateur

abstract class Joueur Classe abstraite d’un joueur class Ordinateur extends

Joueur

Incarnation (electronique) d’un ordinateur class Humain extends Joueur Incarnation d’un joueur

final class CoupOptimal Classe representant le coup optimal selec- tionne

abstract class Piece Classe abstraite repr´esentant une pi`ece du jeu

class Cercle extends Piece Pi`ece de forme circulaire (”les ronds”) class Croix extends Piece Pi`ece cruciforme (”les croix”)

class PieceVide extends Piece Repr´esentant une pi`ece vide

1. Cr´eer une classe publique TicTacToeBete servant juste `a contenir la m´ethode main(...). Elle contiendra juste une instruction : la cr´eation d’une nouvelle classe Jeu, d´ecrite ci-dessous.

2. Cr´er une classe abstraite Piece et trois classes non publiques (non abstraites) Croix,Cercle etPieceVideh´eritant dePiece. Le squelette de ces classes est le suivant :

abstract class Piece {

abstract public String getPiece();

}

class Cercle extends Piece { String laPiece;

// Constructeur

public Cercle() {...}

// Accesseur

public String getPiece() {...}

}// class Cercle

class Croix extends Piece { String laPiece;

// Constructeur public Croix() {...}

// Accesseur

public String getPiece() {...}

}// class Croix

class PieceVide extends Piece {

(8)

String laPiece;

// Constructeur

public PieceVide() {...}

// Accesseur

public String getPiece() {...}

}// class PieceVide

Le code `a cr´eer ´etant particuli`erement trivial, il n’y a pas besoin d’explications suppl´ementaire sur chaque m´ethode.

3. Cr´eer une classeCoupOptimal, repr´esentant le coup optimal `a jouer par l’ordinateur, dont le squelette est le suivant :

final class CoupOptimal {

int ligne;

int colonne;

int val;

// Constructeurs

public CoupOptimal(int v, int lig, int col) {...}

public CoupOptimal(int v) {...}

}

Le code `a cr´eer ´etant particuli`erement trivial, il n’y a pas besoin d’explications suppl´ementaire sur chaque m´ethode.

4. Cr´eer une classe TTTIllegalAccessExceptionh´eritant de Exception et ne contenant qu’un constructeur admettant un unique argument de typeString qui appelle le constructeur de la classe m`ere en lui passant son param`etre.

5. Cr´eer une classe Plateau, dont le squelette est le suivant :

private int dimension; // Cas plus simple de plateaux carres private Piece[][] cases; // cases "physiques" du plateau materiel

private int[][] grille; // grille "immaterielle" pour coups reels ou simules private Jeu jeu;

// Constructeurs

public Plateau(int dimPlateau, Jeu j) {...}

public Plateau(Jeu j) {...}

// Accesseur

public int getDimension() {...}

// Vide cases puis appelle viderGrille() public void viderPlateau() {...}

// Affichage

public void afficherPlateau() {...}

(9)

Exercice 4. Jeu normal et bˆete 9

// Accesseur

public Piece getCase(int ligne, int colonne) {...}

// Jouer un coup, dont on teste la legalite

public boolean deplPiece(int qui, int ligne, int colonne) {...}

// Vide la grille

public void viderGrille() {...}

// Teste si la grille est pleine public boolean grilleEstPleine() {...}

// Accesseur

public int getCellule(int ligne, int colonne) {...}

// fixe un elt de grille avec test sur l’appelant public void setCellule(Object appelant, int valeur,

int ligne, int colonne)

throws TTTIllegalAccessException {...}

// Teste si une cellule de grille est vide

public boolean celluleEstVide(int ligne, int colonne) {...}

Les diff´erentes m´ethodes (toutes tr`es courtes) de Plateau doivent r´ealiser les op´erations suivantes :

- Les constructeurs devront initialiser les diff´erents champs, puis vider la grille et vider le plateau (appel des m´ethodes correspondantes)

- getDimension()renvoie la dimension du plateau (la valeur du champ nomm´e dimension).

- viderPlateau()met une pi`ece vide (voir la classePieceVide) dans toutes les cases du plateau, puis vide la grille.

- afficherPlateau(), ne varie pas par rapport `a la version de l’exercice pr´ec´edent.

- getCase(int ligne, int colonne)renvoie l’´el´ement du tableaucases situ´e en ligne ligne et colonnecolonne.

- deplPiece(int qui, int ligne, int colonne)teste que les entiers ligne etcolonnesont compris entre 0etdimensionet que la case corre- spondante est vide. Remplit ensuite grilleet casesde mani`ere ad´equate.

On se servira des constantes HUMAINetORDINATEURde la classe Joueur.

- viderGrille()vide la grille en se servant de la constante PERSONNEde la classe Joueur.

- grilleEstPleine()teste si la grille est pleine.

- getCellule(int ligne, int colonne)renvoie l’´el´ement d´esir´e du tableau grille.

(10)

- setCellule(Object appelant, int valeur, int ligne, int colonne) throws TTTIllegalAccessException fixe l’´el´ement sp´ecifi´e du tableau

grille `a valeur en testant (`a l’aide de instanceof) que la r´ef´erence de l’objet appelant (apss´e en premier param`etre) est bien une instance de la classe Joueur. Si ce n’est pas le cas, on l`eve une exception de type TTTIllegalAccessException.

- celluleEstVide(int ligne, int colonne)teste si l’´el´ement sp´ecifi´e degrilleest vide (se servir de la constantePERSONNEde la classeJoueur).

6. Cr´eer une classe abstraite Joueurdont le squelette est le suivant abstract class Joueur {

public static final int HUMAIN = 0;

public static final int ORDINATEUR = 1;

public static final int PERSONNE = 2;

protected int gameNum = 0;

protected Plateau plateau;

protected Jeu jeu;

// Constructeur

Joueur(Plateau pl, Jeu j) {...}

// Methodes abstraites

public abstract CoupOptimal choisirCoup(int cote);

public abstract void jouerCoup();

// Simulation d’un coup (sert pour les recherches optimales) public void simulerDeplPiece(int cote, int ligne, int colonne)

throws TTTIllegalAccessException {...}

}

La seule m´ethode de non abstraite de Joueur r´ealise un appel `a la m´ethode setCellule()de la classe Plateau.

7. Cr´eer une classe Ordinateur h´eritant de Joueur qui red´efinit les m´ethodes ab- straites de Joueur:

- La m´ethodechoisirCoup()choisit un coup sens´e ˆetre optimal ; ici encore, on se bornera `a renvoyer unCoupOptimalcorrespondant `a la premi`ere case libre du plateau (test´e au moyen decelluleEstVide()de la classe Plateau).

On pourra mettre comme premier argument du constructeur deCoupOptimal la constante DOUTEUXde la classeJeu.

- La m´ethode jouerCoup()appelle la m´ethode choisirCoup() (phase de r´eflexion), puis appelle la m´ethodedeplPiece()de la classePlateau(phase de passage `a l’acte).

(11)

Exercice 4. Jeu normal et bˆete 11 8. Cr´eer une classe Humain h´eritant deJoueur qui red´efinit les m´ethodes abstraites

de Joueur:

- La m´ethodechoisirCoup()ne fait rien (la phase de r´eflexion est cens´ee se passer dans la tˆete de l’utilisateur), elle renvoie juste null.

- La m´ethode jouerCoup() fait jouer l’utilisateur ; elle est identique `a la m´ethode humainJouerCoup() de l’exercice pr´ec´edent ; elle doit tester si le coup entr´e est l´egal, c’est-`a-dire si les entiers num´ero de ligne et de colonne entr´es au clavier sont bien compris entre 0 et dimension (la dimension du plateau) ; ensuite, le coup est jou´e par appel de la m´ethodedeplPiece()de la classePlateau. Tant que le coup n’est pas l´egal, la m´ethode doit redemander une saisie `a l’utilisateur.

9. Cr´eer une classe Jeu class Jeu

{

public static final int HUMAIN_GAGNE = 0;

public static final int EGALITE = 1;

public static final int DOUTEUX = 2;

public static final int ORDINATEUR_GAGNE = 3;

Plateau plateau;

Joueur humain, ordinateur;

Piece typePieceHumain, typePieceOrdinateur;

Croix typeCroix = new Croix();

Cercle typeCercle = new Cercle();

// Constructeurs

public Jeu(int dimPlateau) {...}

public Jeu() {...}

// Accesseurs

public Piece getTypePieceHumain() {...}

public Piece getTypePieceOrdinateur() {...}

// Si le jeu est fini, recommencer une partie

public void rejouerUnePartie(String message, boolean ordinCommence) {...}

// Ordonnancement de partie :

public void actionsEffectuees(Joueur aQuiLeTour) {...}

// A-t-on gagne ?

boolean estCeGagne(int cote) {...}

}// class Jeu

Les diff´erentes m´ethodes doivent r´ealiser les op´erations suivantes :

- Les constructeurs devront initialiser les diff´erents champs en cr´eant des objets

(12)

si n´ecessaire, puis appeler la m´ethodeviderPlateau()de la classePlateau et enfin appeler la m´ethoderejouerUnePartie().

- rejouerUnePartie(String message, boolean ordinCommence); cette m´ethode est tr`es analogue `a celle de l’exercice pr´ec´edent, `a part qu’il faut ici distinguer le cas o`u l’ordinateur commence (variableordinCommence´egale `a true) de celui o`u l’humain commence.

- actionsEffectuees(int aQuiLeTour)est tr`es analogue `a celle de l’exercice pr´ec´edent ; il faut en plus g´erer le fait que celui qui gagne la partie a com- mence `a jouer pour la partie suivante. Il faut faire en outre les deux adap- tations suivantes : le param`etre de la m´ethode n’est plus un int mais une r´ef´erence de type Joueur ; on se servira donc de l’op´erateur instanceof; en outre l’appel `a plateauEstPlein() doit ˆetre remplac´e par un appel `a grilleEstPleine().

- estCeGagne(String piece)est tr`es analogue `a celle de l’exercice pr´ec´edent.

Il faut faire l’adaptation suivante : l’appel `a getCase() doit ˆetre remplac´e par un appel `a getCellule().

Exercice 5 Jeu par recherche exhaustive

Cet exercice est optionnel, et n’est `a faire que lorsque les deux pr´ec´edents ont ´et´e r´ealis´es.

Il s’agit ici de raffiner un peu l’algorithme utilis´e en utilisant une recherche exhaustive pour les coups jou´es par l’ordinateur.

Les classes cr´ees pour cet exercice seront toutes mises dans un fichierobligatoirement nomm´e TicTacToeSimpleIntelliegent.java.

Les adaptations `a r´ealiser sont les suivantes

1. Ajouter une m´ethodevaleurPosition()`a la classeJeuqui renvoieORDINATEUR GAGNE si l’ordinateur a gagn´e, HUMAIN GAGNE si l’humain a gagn´e, sinon EGALITE si

la grille est pleine, sinon DOUTEUX. Cette m´ethode est utilis´ee pour la simula- tion des coups par l’ordinateur. On se servira des m´ethodes estCeGagne() et grilleEstPleine()dePlateau.

2. Cr´eer une m´ethodesimulerDeplPiece()de signature : public void simulerDeplPiece(int cote, int ligne, int colonne) throws TTTIllegalAccessException

qui appelle juste la m´ethodesetCellule()de la classePlateau.

3. La m´ethodechoisirCoup()doit r´ealiser les actions suivantes :

- Test d’arrˆet ; on teste par appel de le m´ethode valeurPosition() de la classe Jeu.

- Simulation r´ecursive de jeu :

* appel de simulerDeplPiece()

(13)

Exercice 5. Jeu par recherche exhaustive 13

* appel de choisirCoup()avec en param`etre l’adversaire

* appel de simulerDeplPiece()avec en premier param`etre la constante PERSONNEafin d’annuler la simulation

4. la m´ethodechoisirCoup()

Références

Documents relatifs

[r]

∥ d´ esigne la norme associ´ ee au produit scalaire (.. Montrer que la matrice A est d´

Examen d’analyse num´ erique.. Aucun document n’est

On se propose de trouver un point o` u le minimum de J est atteint `a l’aide de

Pour r´ epondre aux questions, vous pouvez mener des recherches dans le cours ainsi que sur le web. Le code doit ˆ etre ´ ecrit

Cr´eer un programme Python permettant de r´ealiser le chiffrement ROT13 d’un fichier texte, puis cr´eer un programme Python permettant de r´ealiser le d´echiffrement.

La formule (8) peut ˆ etre utilis´ ee pour n &gt; 1, le calcul de y 1 se faisant par exemple en utilisant la m´ ethode

Ici, dans l’exemple introductif, on va essayer les deux possibilit´ es pour en d´ eduire une r` egle (la deuxi` eme r` egle de la m´ ethode de simplexe) sur le choix de la ligne `