init
This commit is contained in:
commit
30c2482ec2
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"/usr/share/java/junit.jar",
|
||||
"/usr/share/java/hamcrest-core.jar"
|
||||
]
|
||||
}
|
65
LISEZ-MOI.txt
Normal file
65
LISEZ-MOI.txt
Normal file
|
@ -0,0 +1,65 @@
|
|||
Nom : Fainsin
|
||||
Prénom : Laurent
|
||||
Groupe TP : I
|
||||
|
||||
Les « ... » indiquent les endroits à compléter.
|
||||
|
||||
=====[ Temps passé ]============================================================
|
||||
|
||||
Ces informations de temps sont demandées à titre indicatif et ne sont pas
|
||||
prises en compte dans la notation du projet.
|
||||
|
||||
Toutes les durées sont à saisir en heures. Par exemple, si vous avez passé
|
||||
1h45, il faudra indiquer 1.75. Si vous avez passé 2h30, il faudra indiquer
|
||||
2.5.
|
||||
|
||||
* Temps passé sur la V1 (en h) : 7.5
|
||||
* Temps passé sur la V2 (en h) : 0.5
|
||||
|
||||
|
||||
=====[ Questions ]==============================================================
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Pourquoi l'exception OperationInterditeException ne peut pas être définie
|
||||
comme vérifiée par le compilateur ?
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
PartieSafe.retirer doit lever l'exception OperationInterditeException, mais on ne
|
||||
peut pas (à cause de l'override) lui faire lever plus d'exceptions que
|
||||
CoupInvalideException. Il faut alors que OperationInterditeException ne soit pas
|
||||
vérifié à la compilation, on construit alors OperationInterditeException comme
|
||||
héritant de RuntimeException.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Expliquer ce qu'il faut faire pour ajouter un nouveau niveau de jeu, par
|
||||
exemple la stratégie lente (C13). Pour plus de précision, on numérotera
|
||||
les étapes à faire.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1. Créer une nouvelle Classe implémentant l'interface Stratégie
|
||||
2. Définir sa méthode nbPrise
|
||||
3. Ajouter son identifiant (nom) dans le switch de Jouer.parsePlayer()
|
||||
4. Dans le cas de sa sélection (case), affecter à strat la stratégie (constructeur)
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Expliquer ce qui permet, dans votre conception, de changer dynamiquement
|
||||
(en cours d'exécution du programme) la stratégie d'un joueur (C14).
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
La stratégie du joueur est un attribut (de la classe) on peut donc la ré-attribuer en
|
||||
cours de partie.
|
||||
On peut créer la méthode de classe setStrat(Stratégie) dans cet unique but.
|
||||
|
||||
|
||||
=====[ Explications ]===========================================================
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Donner ici les explications supplémentaires utiles à la compréhension du
|
||||
travail rendu.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Utiliser un Tab size de 4 pour avoir une lecture correcte.
|
||||
|
||||
--------------------------------------------------------------------------------
|
125
allumettes/Arbitre.java
Normal file
125
allumettes/Arbitre.java
Normal file
|
@ -0,0 +1,125 @@
|
|||
package allumettes;
|
||||
|
||||
public class Arbitre {
|
||||
|
||||
// Attributs
|
||||
|
||||
/** Joueurs de la partie */
|
||||
private Joueur j1;
|
||||
private Joueur j2;
|
||||
|
||||
/** Joueur jouant actuellement */
|
||||
private Joueur courant;
|
||||
|
||||
/** Détermine si l'arbitre vérifie la triche */
|
||||
private Boolean confiant = false;
|
||||
|
||||
// Constructeurs
|
||||
|
||||
/**
|
||||
* Construire un arbitre à partir de deux joueurs.
|
||||
*
|
||||
* @param j1 Joueur n°1
|
||||
* @param j2 Joueur n°2
|
||||
*/
|
||||
public Arbitre(Joueur j1, Joueur j2) throws ConfigurationException {
|
||||
if (j1 == null) {
|
||||
throw new ConfigurationException("j1 n'existe pas");
|
||||
} else if (j2 == null) {
|
||||
throw new ConfigurationException("j2 n'existe pas");
|
||||
} else {
|
||||
this.j1 = j1;
|
||||
this.j2 = j2;
|
||||
this.courant = j1;
|
||||
}
|
||||
}
|
||||
|
||||
// GETS
|
||||
|
||||
/**
|
||||
* Déterminer quel joueur ne joue pas actuellement.
|
||||
*/
|
||||
private Joueur getAutre() {
|
||||
if (this.courant == j1) {
|
||||
return this.j2;
|
||||
} else {
|
||||
return this.j1;
|
||||
}
|
||||
}
|
||||
|
||||
// SETs
|
||||
|
||||
public void setConfiant(Boolean confiant) {
|
||||
this.confiant = confiant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de changer le joueur courant de la partie
|
||||
*/
|
||||
private void swapCourant() {
|
||||
if (this.courant == this.j1) {
|
||||
this.courant = this.j2;
|
||||
} else {
|
||||
this.courant = this.j1;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthodes
|
||||
|
||||
/**
|
||||
* Arbitrer un jeu d'allumettes.
|
||||
*
|
||||
* @param game Jeu que l'on arbitre
|
||||
*/
|
||||
public void arbitrer(Jeu game) {
|
||||
while (true) {
|
||||
int nbPrise;
|
||||
System.out.format("Nombre d'allumettes restantes : %d\n", game.getNombreAllumettes());
|
||||
try {
|
||||
|
||||
// le joueur choisit sont coup
|
||||
if (this.confiant) {
|
||||
nbPrise = this.courant.getPrise(game);
|
||||
} else {
|
||||
nbPrise = this.courant.getPrise(new PartieSafe(game));
|
||||
}
|
||||
|
||||
// l'arbitre énonce le coup
|
||||
if (nbPrise == 1 || nbPrise == 0 || nbPrise == -1) {
|
||||
System.out.format("%s prend %d allumette.\n", this.courant.getNom(), nbPrise);
|
||||
} else {
|
||||
System.out.format("%s prend %d allumettes.\n", this.courant.getNom(), nbPrise);
|
||||
}
|
||||
|
||||
// l'arbitre vérifie la validité du coup
|
||||
if (nbPrise > game.getNombreAllumettes()) {
|
||||
throw new CoupInvalideException(nbPrise, String.format("> %d", game.getNombreAllumettes()));
|
||||
} else if (nbPrise > Jeu.PRISE_MAX) {
|
||||
throw new CoupInvalideException(nbPrise, String.format("> %d", Jeu.PRISE_MAX));
|
||||
} else {
|
||||
game.retirer(nbPrise);
|
||||
}
|
||||
|
||||
// l'arbitre passe la main
|
||||
this.swapCourant();
|
||||
System.out.println();
|
||||
break;
|
||||
|
||||
} catch (OperationInterditeException e) {
|
||||
System.out.format("Abandon de la partie car %s triche !\n", this.courant.getNom());
|
||||
throw e;
|
||||
} catch (CoupInvalideException e) {
|
||||
System.out.format("Impossible ! %s\n\n", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Déterminer le vainqueur en fin de partie.
|
||||
*/
|
||||
public void afficherGagnant() {
|
||||
System.out.format("%s perd !\n", this.getAutre().getNom());
|
||||
System.out.format("%s gagne !\n", this.courant.getNom());
|
||||
}
|
||||
|
||||
}
|
16
allumettes/ConfigurationException.java
Normal file
16
allumettes/ConfigurationException.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package allumettes;
|
||||
|
||||
/** Exception qui indique que la configuration d'une partie est incorrecte.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class ConfigurationException extends RuntimeException {
|
||||
|
||||
/** Initaliser une ConfigurationException avec le message précisé.
|
||||
* @param message le message explicatif
|
||||
*/
|
||||
public ConfigurationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
29
allumettes/CoupInvalideException.java
Normal file
29
allumettes/CoupInvalideException.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package allumettes;
|
||||
|
||||
/** Exception qui indique qu'un coup invalide est joué.
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class CoupInvalideException extends Exception {
|
||||
|
||||
/** Nombre d'allumettes prises. */
|
||||
private int nbAllumettes;
|
||||
|
||||
/** Initialiser CoupInvalideException à partir du nombre d'allumettes
|
||||
* prises et le problème constaté. Par exemple, on peut avoir nombre
|
||||
* d'allumettes qui vaut 0 et le problème "< 1".
|
||||
* @param nb le nombre d'allumettes prises
|
||||
* @param probleme le problème sur le nombre d'allumettes
|
||||
*/
|
||||
public CoupInvalideException(int nb, String probleme) {
|
||||
super("Nombre d'allumettes invalide : " + nb + " (" + probleme + ")");
|
||||
this.nbAllumettes = nb;
|
||||
}
|
||||
|
||||
/** Indiquer le nombre d'allumettes qu'un joueur a voulu prendre.
|
||||
* @return le nombre d'allumettes qu'un joueur a voulu prendre. */
|
||||
public int getNombreAllumettes() {
|
||||
return this.nbAllumettes;
|
||||
}
|
||||
|
||||
}
|
25
allumettes/Expert.java
Normal file
25
allumettes/Expert.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package allumettes;
|
||||
|
||||
public class Expert implements Strategie {
|
||||
|
||||
// TODO: à généraliser ?
|
||||
|
||||
@Override
|
||||
public int nbPrise(Jeu game, String nom) {
|
||||
int prise = 0;
|
||||
switch (game.getNombreAllumettes() % 4) {
|
||||
case 0:
|
||||
prise = 3;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
prise = 1;
|
||||
break;
|
||||
case 3:
|
||||
prise = 2;
|
||||
break;
|
||||
}
|
||||
return prise;
|
||||
}
|
||||
|
||||
}
|
34
allumettes/Humain.java
Normal file
34
allumettes/Humain.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package allumettes;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Humain implements Strategie {
|
||||
|
||||
/**
|
||||
* Scanner qui permet de récupérer les entrées des joueurs humains sc est static
|
||||
* car avoir plus d'un scanner ouvert à la fois semble faire bugger la lecture.
|
||||
*/
|
||||
private static Scanner sc = new Scanner(System.in);
|
||||
|
||||
@Override
|
||||
public int nbPrise(Jeu game, String nom) throws CoupInvalideException {
|
||||
int prise = 1;
|
||||
while (true) {
|
||||
try {
|
||||
System.out.printf("%s, combien d'allumettes ? ", nom);
|
||||
String input = sc.nextLine();
|
||||
if (input.equals("triche")) {
|
||||
game.retirer(1);
|
||||
System.out.format("[Une allumette en moins, plus que %d. Chut !]\n", game.getNombreAllumettes());
|
||||
} else {
|
||||
prise = Integer.parseInt(input);
|
||||
break;
|
||||
}
|
||||
} catch (java.lang.NumberFormatException e) {
|
||||
System.out.println("Vous devez donner un entier.");
|
||||
}
|
||||
}
|
||||
return prise;
|
||||
}
|
||||
|
||||
}
|
21
allumettes/Jeu.java
Normal file
21
allumettes/Jeu.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package allumettes;
|
||||
|
||||
public interface Jeu {
|
||||
|
||||
/** Nombre maximal d'allumettes pouvant être prises. */
|
||||
int PRISE_MAX = 3;
|
||||
|
||||
/** Obtenir le nombre d'allumettes encore en jeu.
|
||||
* @return nombre d'allumettes encore en jeu
|
||||
*/
|
||||
int getNombreAllumettes();
|
||||
|
||||
/** Retirer des allumettes. Le nombre d'allumettes doit être compris
|
||||
* entre 1 et PRISE_MAX, dans la limite du nombre d'allumettes encore
|
||||
* en jeu.
|
||||
* @param nbPrises nombre d'allumettes prises.
|
||||
* @throws CoupInvalideException tentative de prendre un nombre invalide d'alumettes
|
||||
*/
|
||||
void retirer(int nbPrises) throws CoupInvalideException;
|
||||
|
||||
}
|
130
allumettes/Jouer.java
Normal file
130
allumettes/Jouer.java
Normal file
|
@ -0,0 +1,130 @@
|
|||
package allumettes;
|
||||
|
||||
/**
|
||||
* Lance une partie du jeu des allumettes en fonction des arguments fournis sur
|
||||
* la ligne de commande.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.5$
|
||||
*/
|
||||
public class Jouer {
|
||||
|
||||
/**
|
||||
* Lancer une partie. En argument sont donnés les deux joueurs sous la forme
|
||||
* nom@stratégie.
|
||||
*
|
||||
* @param args la description des deux joueurs
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
Joueur j1 = null;
|
||||
Joueur j2 = null;
|
||||
Arbitre arbitre = null;
|
||||
Jeu game = null;
|
||||
|
||||
try {
|
||||
|
||||
verifierNombreArguments(args);
|
||||
|
||||
if (args.length > 2) {
|
||||
j1 = parsePlayer(args[1]);
|
||||
j2 = parsePlayer(args[2]);
|
||||
} else {
|
||||
j1 = parsePlayer(args[0]);
|
||||
j2 = parsePlayer(args[1]);
|
||||
}
|
||||
|
||||
arbitre = new Arbitre(j1, j2);
|
||||
arbitre.setConfiant(args[0].equals("-confiant"));
|
||||
game = new Partie();
|
||||
|
||||
} catch (ConfigurationException e) {
|
||||
System.out.println("\nErreur : " + e.getMessage());
|
||||
afficherUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
while (game.getNombreAllumettes() > 0) {
|
||||
arbitre.arbitrer(game);
|
||||
}
|
||||
arbitre.afficherGagnant();
|
||||
} finally {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Créer un joueur à partir d'une chaine de caractères.
|
||||
*
|
||||
* @param arg chaine de caractère permettant de créer le joueur
|
||||
* @throws ConfigurationException si le joueur ne peut pas être créé
|
||||
*/
|
||||
private static Joueur parsePlayer(String arg) throws ConfigurationException {
|
||||
String[] pre = arg.split("@");
|
||||
if (pre.length != 2) {
|
||||
throw new ConfigurationException("Configuration d'un joueur invalide");
|
||||
}
|
||||
|
||||
String nom = pre[0];
|
||||
|
||||
Strategie strat;
|
||||
switch (pre[1].toLowerCase()) {
|
||||
case "naif":
|
||||
strat = new Naif();
|
||||
break;
|
||||
case "rapide":
|
||||
strat = new Rapide();
|
||||
break;
|
||||
case "expert":
|
||||
strat = new Expert();
|
||||
break;
|
||||
case "humain":
|
||||
strat = new Humain();
|
||||
break;
|
||||
case "lente":
|
||||
strat = new Lente();
|
||||
break;
|
||||
case "tricheur":
|
||||
strat = new Tricheur();
|
||||
break;
|
||||
default:
|
||||
throw new ConfigurationException(String.format("Stratégie de %s invalide", nom));
|
||||
}
|
||||
return new Joueur(nom, strat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifier si le nombre d'arguments fournis dans la ligne de commande est
|
||||
* cohérent.
|
||||
*
|
||||
* @param args arguments de la ligne de commande
|
||||
* @throws ConfigurationException si les argument ne sont pas correctes
|
||||
*/
|
||||
private static void verifierNombreArguments(String[] args) throws ConfigurationException {
|
||||
final int nbJoueurs = 2;
|
||||
if (args.length < nbJoueurs) {
|
||||
throw new ConfigurationException("Trop peu d'arguments : " + args.length);
|
||||
}
|
||||
if (args.length > nbJoueurs + 1) {
|
||||
throw new ConfigurationException("Trop d'arguments : " + args.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Afficher des indications sur la manière d'exécuter cette classe.
|
||||
*/
|
||||
public static void afficherUsage() {
|
||||
System.out.println("\n"
|
||||
+ "Usage :"
|
||||
+ "\n\t" + "java allumettes.Jouer joueur1 joueur2"
|
||||
+ "\n\t\t" + "joueur est de la forme nom@stratégie"
|
||||
+ "\n\t\t" + "strategie = naif | rapide | expert | humain | tricheur | lente"
|
||||
|
||||
+ "\n\n\t" + "Exemple :"
|
||||
+ "\n\t\t" + "java allumettes.Jouer Xavier@humain Ordinateur@naif"
|
||||
+ "\n");
|
||||
}
|
||||
|
||||
}
|
75
allumettes/Joueur.java
Normal file
75
allumettes/Joueur.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
package allumettes;
|
||||
|
||||
public class Joueur {
|
||||
|
||||
// Attributs
|
||||
|
||||
/** Le nom du joueur */
|
||||
private String nom;
|
||||
|
||||
/** Stratégie adoptée par le joueur */
|
||||
private Strategie strat;
|
||||
|
||||
// Constructeurs
|
||||
|
||||
/**
|
||||
* Construire un joueur à partir de son nom et du nom de sa stratégie.
|
||||
*
|
||||
* @param nom nom du joueur
|
||||
* @param strat stratégie à adopter
|
||||
*/
|
||||
public Joueur(String nom, Strategie strat) {
|
||||
|
||||
if (nom == null) {
|
||||
throw new ConfigurationException("Un joueur n'a pas de nom");
|
||||
} else if (strat == null) {
|
||||
throw new ConfigurationException(this.nom + " n'a pas de stratégie");
|
||||
} else {
|
||||
this.nom = nom;
|
||||
this.strat = strat;
|
||||
}
|
||||
}
|
||||
|
||||
// GETs
|
||||
|
||||
public String getNom() {
|
||||
return this.nom;
|
||||
}
|
||||
|
||||
// SETs
|
||||
|
||||
public void setNom(String nom) throws ConfigurationException {
|
||||
if (nom == null) {
|
||||
throw new ConfigurationException(this.nom + "doit avoir un nouveau nom valide");
|
||||
} else {
|
||||
this.nom = nom;
|
||||
}
|
||||
}
|
||||
|
||||
public void setStrat(Strategie strat) throws ConfigurationException {
|
||||
if (strat == null) {
|
||||
throw new ConfigurationException(this.nom + "doit avoir une stratégie valide");
|
||||
} else {
|
||||
this.strat = strat;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthodes
|
||||
|
||||
/**
|
||||
* Obtenir le nombre d'allumettes que le joueur prends.
|
||||
*
|
||||
* @param game Le jeu auquel on prend des allumettes
|
||||
* @return le nombre d'allumettes que le joueur prends
|
||||
* @throws CoupInvalideException si le coup
|
||||
* @throws ConfigurationException si le jeu fournis est null
|
||||
*/
|
||||
public int getPrise(Jeu game) throws CoupInvalideException, ConfigurationException {
|
||||
if (game == null) {
|
||||
throw new ConfigurationException(this.nom + " ne trouve pas la partie");
|
||||
} else {
|
||||
return this.strat.nbPrise(game, this.nom);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
10
allumettes/Lente.java
Normal file
10
allumettes/Lente.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package allumettes;
|
||||
|
||||
public class Lente implements Strategie {
|
||||
|
||||
@Override
|
||||
public int nbPrise(Jeu game, String nom) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
21
allumettes/Naif.java
Normal file
21
allumettes/Naif.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package allumettes;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Naif implements Strategie {
|
||||
|
||||
/** Générateur de nombres aléatoire */
|
||||
private Random random = new Random();
|
||||
|
||||
@Override
|
||||
public int nbPrise(Jeu game, String nom) {
|
||||
int rd = random.nextInt(Jeu.PRISE_MAX) + 1;
|
||||
int nb = game.getNombreAllumettes();
|
||||
if (rd > nb) {
|
||||
return nb;
|
||||
} else {
|
||||
return rd;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
5
allumettes/OperationInterditeException.java
Normal file
5
allumettes/OperationInterditeException.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
package allumettes;
|
||||
|
||||
public class OperationInterditeException extends RuntimeException {
|
||||
|
||||
}
|
48
allumettes/Partie.java
Normal file
48
allumettes/Partie.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package allumettes;
|
||||
|
||||
public class Partie implements Jeu {
|
||||
|
||||
// Attributs
|
||||
|
||||
/** variable stockant le nombre d'allumettes encore en jeu */
|
||||
private int nbAllumettes;
|
||||
|
||||
// Constructeurs
|
||||
|
||||
/** Constructeur par défaut de la classe Partie. */
|
||||
public Partie() {
|
||||
this.nbAllumettes = 13;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructeur de la classe Partie.
|
||||
*
|
||||
* @param nbAllumettes nombre d'allumettes initiales ( > 0 )
|
||||
*/
|
||||
public Partie(int nbAllumettes) {
|
||||
if (nbAllumettes < 1) {
|
||||
throw new ConfigurationException("Nombre d'allumettes initiales incorrectes ( < 1 )");
|
||||
} else {
|
||||
this.nbAllumettes = nbAllumettes;
|
||||
}
|
||||
}
|
||||
|
||||
// GETs
|
||||
|
||||
@Override
|
||||
public int getNombreAllumettes() {
|
||||
return this.nbAllumettes;
|
||||
}
|
||||
|
||||
// Méthodes
|
||||
|
||||
@Override
|
||||
public void retirer(int nbPrises) throws CoupInvalideException {
|
||||
if (nbPrises < 1) {
|
||||
throw new CoupInvalideException(nbPrises, "< 1");
|
||||
} else {
|
||||
this.nbAllumettes -= nbPrises;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
32
allumettes/PartieSafe.java
Normal file
32
allumettes/PartieSafe.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package allumettes;
|
||||
|
||||
public class PartieSafe implements Jeu {
|
||||
|
||||
// ATTRIBUTS
|
||||
|
||||
Jeu vraiGame;
|
||||
|
||||
// CONSTRUCTEUR
|
||||
|
||||
/**
|
||||
* Constructeur d'une partie dont le nombre d'allumettes ne peut être modifié.
|
||||
*
|
||||
* @param game Jeu que l'on utilise pour créer le proxy
|
||||
*/
|
||||
public PartieSafe(Jeu game) {
|
||||
this.vraiGame = game;
|
||||
}
|
||||
|
||||
// MÉTHODES
|
||||
|
||||
@Override
|
||||
public void retirer(int nbPrises) {
|
||||
throw new OperationInterditeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNombreAllumettes() {
|
||||
return vraiGame.getNombreAllumettes();
|
||||
}
|
||||
|
||||
}
|
15
allumettes/Rapide.java
Normal file
15
allumettes/Rapide.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package allumettes;
|
||||
|
||||
public class Rapide implements Strategie {
|
||||
|
||||
@Override
|
||||
public int nbPrise(Jeu game, String nom) {
|
||||
int nb = game.getNombreAllumettes();
|
||||
if (nb > Jeu.PRISE_MAX) {
|
||||
return Jeu.PRISE_MAX;
|
||||
} else {
|
||||
return nb;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
14
allumettes/Strategie.java
Normal file
14
allumettes/Strategie.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package allumettes;
|
||||
|
||||
public interface Strategie {
|
||||
|
||||
/**
|
||||
* Renvoyer le nombre d'allumettes que le joueur doit prendre.
|
||||
*
|
||||
* @param nb nombre d'allumettes encore en jeu
|
||||
* @param nom nom du joueur
|
||||
* @return nombre d'allumettes à prendre
|
||||
*/
|
||||
int nbPrise(Jeu game, String nom) throws CoupInvalideException;
|
||||
|
||||
}
|
41
allumettes/TestArbitre.java
Normal file
41
allumettes/TestArbitre.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package allumettes;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
public class TestArbitre {
|
||||
|
||||
Partie game = new Partie(100);
|
||||
|
||||
Joueur j1 = new Joueur("j1", new Rapide());
|
||||
Joueur j2 = new Joueur("j2", new Lente());
|
||||
Joueur j3 = new Joueur("j3", new Tricheur());
|
||||
|
||||
@Test
|
||||
public void TestConstructeur() {
|
||||
Arbitre a1 = new Arbitre(j1, j2);
|
||||
Arbitre a2 = new Arbitre(j1, j2);
|
||||
a1.setConfiant(true);
|
||||
a2.setConfiant(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestArbitrer() {
|
||||
Arbitre a1 = new Arbitre(j1, j2);
|
||||
a1.setConfiant(false);
|
||||
a1.arbitrer(game);
|
||||
}
|
||||
|
||||
@Test(expected = OperationInterditeException.class)
|
||||
public void TestArbitrerTricheur() {
|
||||
Arbitre a1 = new Arbitre(j3, j2);
|
||||
a1.arbitrer(game);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestArbitrerTricheurConfiant() {
|
||||
Arbitre a1 = new Arbitre(j3, j2);
|
||||
a1.setConfiant(true);
|
||||
a1.arbitrer(game);
|
||||
}
|
||||
|
||||
}
|
26
allumettes/TestLente.java
Normal file
26
allumettes/TestLente.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package allumettes;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
public class TestLente {
|
||||
|
||||
Strategie strat = new Lente();
|
||||
|
||||
@Test
|
||||
public void TestRetirer() throws CoupInvalideException {
|
||||
|
||||
Random rd = new Random();
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Partie game = new Partie(rd.nextInt(100) + 1);
|
||||
int nb = strat.nbPrise(game, "nom");
|
||||
assertEquals(nb, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
48
allumettes/TestPartie.java
Normal file
48
allumettes/TestPartie.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package allumettes;
|
||||
|
||||
import org.junit.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestPartie {
|
||||
|
||||
@Test(expected = ConfigurationException.class)
|
||||
public void TestConstructeurNegatif() {
|
||||
new Partie(-1);
|
||||
}
|
||||
|
||||
@Test(expected = ConfigurationException.class)
|
||||
public void TestConstructeurNul() {
|
||||
new Partie(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestConstructeurPositif() {
|
||||
new Partie(1);
|
||||
}
|
||||
|
||||
@Test(expected = CoupInvalideException.class)
|
||||
public void TestRetirerNegatif() throws CoupInvalideException {
|
||||
new Partie(1).retirer(-1);
|
||||
}
|
||||
|
||||
@Test(expected = CoupInvalideException.class)
|
||||
public void TestRetirerNul() throws CoupInvalideException {
|
||||
new Partie(1).retirer(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestRetirerPositif() throws CoupInvalideException {
|
||||
Partie game = new Partie(20);
|
||||
game.retirer(1);
|
||||
assertEquals(game.getNombreAllumettes(), 19);
|
||||
game.retirer(2);
|
||||
assertEquals(game.getNombreAllumettes(), 17);
|
||||
game.retirer(3);
|
||||
assertEquals(game.getNombreAllumettes(), 14);
|
||||
game.retirer(4);
|
||||
assertEquals(game.getNombreAllumettes(), 10);
|
||||
game.retirer(10);
|
||||
assertEquals(game.getNombreAllumettes(), 0);
|
||||
}
|
||||
|
||||
}
|
24
allumettes/TestPartieSafe.java
Normal file
24
allumettes/TestPartieSafe.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package allumettes;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
public class TestPartieSafe {
|
||||
|
||||
PartieSafe game = new PartieSafe(new Partie(10));
|
||||
|
||||
@Test(expected = OperationInterditeException.class)
|
||||
public void TestRetirerNegatif() throws CoupInvalideException {
|
||||
game.retirer(-1);
|
||||
}
|
||||
|
||||
@Test(expected = OperationInterditeException.class)
|
||||
public void TestRetirerNul() throws CoupInvalideException {
|
||||
game.retirer(0);
|
||||
}
|
||||
|
||||
@Test(expected = OperationInterditeException.class)
|
||||
public void TestRetirerPositif() throws CoupInvalideException {
|
||||
game.retirer(1);
|
||||
}
|
||||
|
||||
}
|
54
allumettes/TestRapide.java
Normal file
54
allumettes/TestRapide.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
package allumettes;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
public class TestRapide {
|
||||
|
||||
Strategie strat = new Rapide();
|
||||
|
||||
@Test
|
||||
public void TestSuperieur() throws CoupInvalideException {
|
||||
|
||||
Random rd = new Random();
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Partie game = new Partie(rd.nextInt(1000) + Jeu.PRISE_MAX);
|
||||
int nb = strat.nbPrise(game, "nom");
|
||||
assertEquals(nb, Jeu.PRISE_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestInferieur() throws CoupInvalideException {
|
||||
|
||||
for (int i = 1; i < Jeu.PRISE_MAX; i++) {
|
||||
Partie game = new Partie(i);
|
||||
int nb = strat.nbPrise(game, "nom");
|
||||
assertNotEquals(nb, Jeu.PRISE_MAX);
|
||||
assertEquals(nb, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestArbitre() throws CoupInvalideException {
|
||||
|
||||
Joueur j1 = new Joueur("j1", new Rapide());
|
||||
Joueur j2 = new Joueur("j2", new Rapide());
|
||||
Arbitre arbitre = new Arbitre(j1, j2);
|
||||
|
||||
for (int i = 1; i < 100; i++) {
|
||||
Partie game = new Partie(i);
|
||||
while (game.getNombreAllumettes() > 0) {
|
||||
arbitre.arbitrer(game);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
13
allumettes/Tricheur.java
Normal file
13
allumettes/Tricheur.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package allumettes;
|
||||
|
||||
public class Tricheur implements Strategie {
|
||||
|
||||
@Override
|
||||
public int nbPrise(Jeu game, String nom) throws CoupInvalideException {
|
||||
System.out.println("[Je triche...]");
|
||||
game.retirer(game.getNombreAllumettes() - 2);
|
||||
System.out.format("[Allumettes restantes : %d]\n", game.getNombreAllumettes());
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
104
testeur.sh
Normal file
104
testeur.sh
Normal file
|
@ -0,0 +1,104 @@
|
|||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------
|
||||
# Programme de test en boîte noire pour les 13 allumettes
|
||||
# -------------------------------------------------------
|
||||
|
||||
usage() {
|
||||
echo "Erreur : $1"
|
||||
echo
|
||||
echo "Usage : sh testeur.sh [-d dossier] fichier.run..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo "**** $1" 1>&2
|
||||
}
|
||||
|
||||
mainClass=allumettes.Jouer
|
||||
mainFile=`echo $mainClass | tr . /`.java
|
||||
|
||||
# Déterminer si l'option -enconding latin1 est nécessaire
|
||||
javacOpt=
|
||||
if file -i $mainFile | grep iso-8859 > /dev/null 2>&1 ; then
|
||||
echo "Le fichier $mainClass est en latin1. Utilisation de l'option -encoding latin1 de javac"
|
||||
javacOpt="-encoding latin1"
|
||||
fi
|
||||
|
||||
# Traiter les arguments de la ligne de commande
|
||||
# | Un seul argument possible -d pour déterminer le dossier dans lequel
|
||||
# | mettre les résutlats du test (.computed et .diff)
|
||||
if [ "$1" = "-d" ] ; then
|
||||
shift
|
||||
testdiropt="$1"
|
||||
shift
|
||||
[ -d "$testdiropt" ] || mkdir "$testdiropt"
|
||||
if [ ! -d "$testdiropt" ] ; then
|
||||
usage "$testdiropt n'est pas un dossier"
|
||||
elif [ ! -w "$testdiropt" ] ; then
|
||||
usage "impossible d'écrire dans $testdiropt"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -z "$testdiropt" ] ; then
|
||||
echo "Les résultats seront dans $testdiropt"
|
||||
fi
|
||||
|
||||
|
||||
# Jouer les tests
|
||||
if javac $javacOpt $mainFile ; then
|
||||
while [ "$1" ] ; do
|
||||
test="$1"
|
||||
shift
|
||||
|
||||
if [ ! -f "$test" ] ; then
|
||||
warning "Fichier de test inexitant : $test"
|
||||
continue
|
||||
elif [ ! -r "$test" ] ; then
|
||||
warning "Fichier de test interdit en lecture : $test"
|
||||
continue
|
||||
fi
|
||||
|
||||
testName=$(basename $test .run)
|
||||
outputDir=${testdiropt:-$(dirname $test)}
|
||||
|
||||
if [ "$testName" = "$(basename $test)" ] ; then
|
||||
warning "Test ignoré (le suffixe doit être .run) : $test"
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
# Définir les noms de fichiers utilisés
|
||||
computed=$outputDir/$testName.computed
|
||||
expected=${test%.run}.expected
|
||||
diff=$outputDir/$testName.diff
|
||||
|
||||
|
||||
if [ ! -r "$expected" ] ; then
|
||||
warning "Fichier de résultat absent ou interdit en lecture : $expected"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Lancer le test
|
||||
sh $test > $computed 2>&1
|
||||
|
||||
# Transformer le résultat en utf8 (si nécessaire)
|
||||
if file -i $computed | grep iso-8859 > /dev/null 2>&1 ; then
|
||||
echo "Résultat en latin1. Je transforme en utf8."
|
||||
recode latin1..utf8 $computed
|
||||
fi
|
||||
|
||||
# Afficher le résultat
|
||||
echo -n "$testName : "
|
||||
if diff -Bbw $computed $expected > $diff 2>&1 ; then
|
||||
echo "ok"
|
||||
else
|
||||
echo "ERREUR"
|
||||
cat $diff
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Erreur de compilation !"
|
||||
fi
|
||||
|
BIN
to-1sn-2020-pr-02-sujet.pdf
Normal file
BIN
to-1sn-2020-pr-02-sujet.pdf
Normal file
Binary file not shown.
Loading…
Reference in a new issue