001/**
002 *  This class is part of the "World of Zuul" application. 
003 *  "World of Zuul" is a very simple, text based adventure game.
004 * 
005 *  This class creates all rooms, creates the parser and starts
006 *  the game.  It also evaluates and executes the commands that 
007 *  the parser returns.
008 * 
009 * @author  Michael Kolling and David J. Barnes, Alban FERRACANI
010 * @author pour générer un nombre aléatoire : https://urlz.fr/ftf6 
011 * @version 1.0 (Jan 2003) DB edited (2019) Alban Ferracani edited (2021)
012 */
013
014import java.util.Stack;
015import java.util.Scanner;
016import java.io.File;
017import java.io.FileNotFoundException;
018import java.awt.*;
019import java.util.Date;
020import java.text.SimpleDateFormat;
021
022import java.applet.Applet;
023import java.net.URL;
024import java.applet.AudioClip;
025
026public class GameEngine
027{
028    private Parser aParser;
029    private UserInterface aGui;
030    private Player aPlayer;
031    
032    //Compteur de requêtes.
033    private int aCounterRequestMax = 0;                    //Nombre de requêtes actuel.
034    //private int aCounterRequestMaxTotal = 150;             //Nombre de requêtes maximal utilisable.
035    private int aCounterRequestMaxTotal = 100 + (int)(Math.random() * ((120 - 100) + 1));;             //Nombre aléatoire compris entre 100 et 120 (Min + (int)(Math.random() * ((Max - Min) + 1)))
036    private int aCounterRequestPourcentage = 0;            //Pourcentage du nombre de requêtes utilisé par rapport au nombre maximal utilisable.
037    private int aModeJeu = 1; 
038    
039    //Nuance de couleurs pour la conversion en HSB.
040    private int r;
041    private int g;
042    private int b;
043    
044    //Attributs de la date et de l'heure.
045    private SimpleDateFormat aSMin = new SimpleDateFormat("mm");
046    private SimpleDateFormat aSHours = new SimpleDateFormat("HH");
047    private SimpleDateFormat aSTime = new SimpleDateFormat("HH:mm");
048    private Date aDate = new Date();
049    private int aDateEndMin;                //Heure de fin minute (int).
050    private int aDateEndHours;              //Heure de fin heure (int).
051    private String aDateBeginString;        //Heure de début (string)
052    private String aDateEndString;          //Heure de fin calculée en fonction du mode de jeu (string)
053    private String aDateActualString;       //Heure actuelle (string)
054    
055    //Temps accordés pour les modes de jeu 1,2 et 3. 
056    private int aTempsModeJeu1 = 15;
057    private int aTempsModeJeu2 = 10;
058    private int aTempsModeJeu3 = 5;
059    
060    
061    /**
062     * Constructeur d'objets de la classe GameEngine
063     * @param pNomJoueur (string)
064     * @param pModeJeu (int)
065     */
066    public GameEngine(final String pNomJoueur, final int pModeJeu)
067    {
068        this.aParser = new Parser();
069        //this.aStackPreviousRoom = new Stack <Room>();
070        this.createRooms();
071        this.aPlayer.setNomJoueur(pNomJoueur);
072        //this.aPlayer.setPoidsPlayer(pPoidsJoueur);
073        this.aDateBeginString = "" + aSTime;
074        
075        if (pModeJeu == 1){ //Mode jeu facile
076            this.aCounterRequestMax = this.aCounterRequestMaxTotal;
077            this.aModeJeu = 1;
078            this.endHour(this.aTempsModeJeu1);       //On calcule l'heure de fin en attribuant un temps de jeu de aTempsModeJeu1 minutes.
079            
080        }
081        else if (pModeJeu == 2){ //Mode jeu moyen
082            this.aCounterRequestMax = this.aCounterRequestMaxTotal/2;
083            this.aModeJeu = 2;
084            this.endHour(this.aTempsModeJeu2);       //On calcule l'heure de fin en attribuant un temps de jeu de aTempsModeJeu2 minutes.
085        }
086        else if (pModeJeu == 3){ //Mode jeu difficile
087            this.aCounterRequestMax = this.aCounterRequestMaxTotal/3;
088            this.aModeJeu = 3;      
089            this.endHour(this.aTempsModeJeu3);       //On calcule l'heure de fin conseillée en attribuant un temps de jeu de aTempsModeJeu3 minutes.
090        }
091        
092        //Heure de début du jeu 
093        this.aDateBeginString = aSTime.format(aDate);
094    } //GameEngine
095
096    /**
097     * SetGUI
098     */
099    public void setGUI( final UserInterface pUserInterface )
100    {
101        this.aGui = pUserInterface;
102        this.printWelcome();
103    } //setGUI()
104
105    /**
106     * Afficher le message de bienvenue au joueur avec toutes les informations nécessaires :
107     * - Présentation du jeu et objectif. 
108     * - Nombre de requêtes maximales (time limit) et temps maximal.
109     * - Pièce de départ et commandes.
110     */
111    private void printWelcome()
112    {
113        String vNomJoueur = this.aPlayer.getNomJoueur().toUpperCase();
114        SimpleDateFormat s = new SimpleDateFormat("HH:mm");
115        Date date = new Date();
116        
117        //Audio 
118        URL url = getClass().getClassLoader().getResource("son/sound2.wav");
119        AudioClip clip = Applet.newAudioClip(url);
120        
121        URL urlwelcome = getClass().getClassLoader().getResource("son/bienvenue1.wav");
122        AudioClip clipwelcome = Applet.newAudioClip(urlwelcome);
123        
124        new Thread() {
125            public void run() {
126                clip.play();
127                clipwelcome.play();
128            }
129
130        }.start();
131        
132      
133        //Affichage
134        this.aGui.print( "\n" );
135        this.aGui.print( "Pensez à activer le son ! Des messages vocaux seront diffusés ! \n \n" );
136        this.aGui.println( "---------------------------B I E N V E N U E------------------------------" );
137        this.aGui.println( "Bienvenue " + vNomJoueur + " dans le monde Périgourdain." );
138        this.aGui.println( "Détectives du Périgord est un jeu d'aventure.\n" );
139        this.aGui.println( "Objectif du jeu : prendre les objets indispensables dans le château, aller jusqu'à la \npièce secrète et ramener les denrées de cette pièce jusque dans le jardin." );
140        this.aGui.println( "Essayez de cartographier le château afin de ne louper aucune pièce. Pour vous aider, \nà repérer les lieux, une petite carte est disponible dans l'entrée et dans l'écurie.\n" );
141        this.aGui.println( "Tapez 'help' si vous nécéssitez de l'aide ou pour voir les commandes disponibles." );
142        this.aGui.print( "\n");
143        Room aCurrentRoom = this.aPlayer.getCurrentRoom();
144        if (aModeJeu == 1){ //Mode jeu facile (n°1)
145            this.aCounterRequestMax = this.aCounterRequestMaxTotal;
146            this.aGui.println( "Vous avez sélectionné le mode jeu n°" + this.aModeJeu + " soit le mode simple.");
147            this.aGui.print("Il est : " + s.format(date));
148            this.aGui.println(". Essayez de gagner le jeu en " + this.aTempsModeJeu1 + " minutes maximum soit avant : " + this.aDateEndString + ".");
149        }
150        else if (aModeJeu == 2){ //Mode jeu moyen (n°2)
151            this.aCounterRequestMax = this.aCounterRequestMaxTotal/2;
152            this.aGui.println( "Vous avez sélectionné le mode jeu n°" + this.aModeJeu + " soit le mode moyen.");
153            this.aGui.print("Il est : " + s.format(date));
154            this.aGui.println(". Essayez de gagner le jeu en " + this.aTempsModeJeu2 + " minutes maximum soit avant : " + this.aDateEndString + ".");
155        }
156        else if (aModeJeu == 3){ //Mode jeu difficile (n°3)
157            this.aCounterRequestMax = this.aCounterRequestMaxTotal/3;
158            this.aGui.print("Il est : " + s.format(date));
159            this.aGui.println(". Essayez de gagner le jeu en " + this.aTempsModeJeu3 + " minutes maximum soit avant : " + this.aDateEndString + ".");
160        }
161        this.aGui.println("Dans ce mode, vous n'avez seulement " + this.aCounterRequestMax + " commandes autorisées. \nUne fois ce nombre de requêtes où temps dépassé, le jeu s'arrêtera. \n");
162        this.aGui.println("Votre poids est de : " +this.aPlayer.getPoidsPlayer() + ". Vous pouvez porter des items ayant un poids inférieur \nà : " + this.aPlayer.getItemPoidsMax() + " . Attention, votre poids (" +this.aPlayer.getPoidsPlayer() + ") est inclus dans ce chiffre ("+ this.aPlayer.getItemPoidsMax() +"). \n");
163        this.aGui.println( "Veuillez exécuter au moins une action une fois par minute.\n");
164        this.printLocationInfo();
165        this.aGui.print( "\n");
166        this.aGui.printBold("", Color.green.darker().darker().darker());
167        
168        // this.aGui.println( "Il est :" + java.time.LocalTime.now());
169        // this.aGui.println( "Nous sommes le :" + java.time.LocalDate.now());
170        // SimpleDateFormat s = new SimpleDateFormat("dd/MM/yyyy HH:mm");
171        // Date date = new Date();
172        // this.aGui.println(s.format(date));
173        // this.aGui.println("Vous avez jusqu'à :" + java.time.LocalTime.now()+10);
174        
175    } //printWelcome()
176    
177    /**
178     * Print location info
179     * Pour afficher la description de la piece courante dans laquelle se situe le joueur.
180     */
181    private void printLocationInfo()
182    {
183        //Affichage de la description de la pièce.
184        this.aGui.println( this.aPlayer.getCurrentRoom().getLongDescription() );
185        this.aGui.print( "\n");
186       
187        if ( this.aPlayer.getCurrentRoom().getImageName() != null )
188            {
189            this.aGui.showImage( this.aPlayer.getCurrentRoom().getImageName() );
190            
191            }
192    } //printLocationInfo()
193    
194    
195    /**
196     * Crée toutes les rooms, initialise leurs images et lie leurs sorties.
197     * Déclaration des items, magiccookies ainsi que du lieu de départ. 
198     */
199    private void createRooms()
200    {
201        
202        // Déclaration et création des Rooms sous la forme : ("NomRoom", "DescriptionRoom", "ImageRoom", "Enigme")
203        Room vForet = new Room("foret",         "dans la forêt aux alentours du château", "images/forest.gif", null);
204        Room vJardin = new Room("jardin",       "à l'extérieur de l'entrée principale du château", "images/jardin.gif", "Porter des items lourds est comme chercher un cookie dans une botte de foin...");
205        Room vEntree = new Room("entree",       "dans l'entrée principale du château", "images/entree.jpg", "Une bonne odeur venant de l'est embaume l'entrée");
206        Room vCuisine = new Room("cuisine" ,    "dans la cuisine du château", "images/cuisine.jpg", "A quoi peut servir un beamer ? Indice : vous prenez le beamer avec vous ('take'), \npuis vous le chargez 'charge beamer' dans la pièce de votre choix. \nVous pourrez alors revenir par téléportation dans cette pièce grâce à 'teleport beamer'. ");
207        Room vSalleAManger = new Room("salle a manger",         "dans la salle à manger du château", "images/sallemanger.jpg", "Mieux vaut cacher ses objets les plus précieux proche du sol, à l’abris d’intrus ou d’incendies");
208        Room vSalleDeReception = new Room("salle de reception", "dans la salle de réception du château", "images/sallereception.gif", "Quel objet majeur était caché dans la pièce du roi ? Un indice : le chiffre '2'... ");
209        Room vBureauRoyal = new Room("Bureau royal" ,           "dans le bureau royal", "images/bureauroyal.jpg", "Vous avez trouvé à quoi correspond le chiffre de la pièce voisine, non ?");
210        Room vEcurie = new Room("ecurie",             "dans l'écurie, la grange du parc", "images/ecurie.gif", "Un magiccookie, est-ce de la nourriture où un objet ( 'eat' ou 'take' ) ? \nEssayez de décortiquer l'énigme de la  pièce précédente pour comprendre son utilité." );
211        Room vSousSol = new Room("sous sol",          "dans le sous-sol du château", "images/cave.jpg", null);
212        Room vPassageSecret = new Room("passage secret",   "dans le passage secret du château", "images/passagesecret.jpg", null);
213        Room vPieceSecrete = new Room("piece secrete",      "dans la pièce secrète du château", "images/piecesecrete.jpg", "Pour porter des charges lourdes, essayez de décomposer... \nEt pour gagner, déposez les trésors dans le jardin, sans y déposer aucun autre item...\nTrouvez la commande adéquatepour déposer l'objet en tapant ' help '...");
214        
215        
216        //Déclaration des sorties de chaque pièce
217        
218        vForet.setExit("nord", vJardin, false);
219        
220        vJardin.setExit("nord", vEntree, false);
221        vJardin.setExit("ouest", vEcurie, false);
222        vJardin.setExit(null, vForet, true);            //trapdoor anti retour --> sens interdit : jardin forêt --> sens autorisé : forêt jardin
223        
224        vEcurie.setExit("est", vJardin, false);
225        
226        vEntree.setExit("nord", vSalleDeReception, false);
227        vEntree.setExit("sud", vJardin, false);
228        vEntree.setExit("est", vCuisine, false);
229        vEntree.setExit("bas", vSousSol, false);
230        
231        vCuisine.setExit("nord", vSalleAManger, false);
232        //vCuisine.setExit("ouest", vEntree, false);
233        vCuisine.setExit(null, vEntree, true);          //trapdoor anti retour --> sens interdit : cuisine entrée --> sens autorisé : entrée cuisine
234        
235        vSalleAManger.setExit("sud", vCuisine, false);
236        vSalleAManger.setExit("ouest", vSalleDeReception, false);
237       
238        vSalleDeReception.setExit("sud", vEntree, false);
239        vSalleDeReception.setExit("ouest", vBureauRoyal, false);
240        vSalleDeReception.setExit("est", vSalleAManger, false);
241        
242        vBureauRoyal.setExit("est", vSalleDeReception, false);
243        
244        vSousSol.setExit("haut", vEntree, false);
245        vSousSol.setExit("ouest", vPassageSecret, false);
246        
247        vPassageSecret.setExit("est", vSousSol, false);
248        vPassageSecret.setExit("sud", vPieceSecrete, false);
249        
250        vPieceSecrete.setExit("nord", vPassageSecret, false);
251        
252        
253        //Déclaration des Items
254        Item vCleCave = new Item (100, "cle1");
255        vCuisine.addItem(vCleCave.getShortDescription(), vCleCave);
256        
257        Item vCleCavefake = new Item (2000, "clemystere");
258        vCuisine.addItem(vCleCavefake.getShortDescription(), vCleCavefake);
259        
260        Item vCleEcurie = new Item (100, "cle2");
261        vBureauRoyal.addItem(vCleEcurie.getShortDescription(), vCleEcurie);
262        
263        Item vTresor1 = new Item (1000, "tresor1");
264        vPieceSecrete.addItem(vTresor1.getShortDescription(), vTresor1);
265        
266        Item vTresor2 = new Item (5000, "tresor2");
267        vPieceSecrete.addItem(vTresor2.getShortDescription(), vTresor2);
268        
269        Item vMagicCookie = new Item (10, "magiccookie");
270        vEcurie.addItem(vMagicCookie.getShortDescription(), vMagicCookie);
271        
272        Item vLampe = new Item (250, "lampe");
273        vEntree.addItem(vLampe.getShortDescription(), vLampe);
274        
275        //Declaration du Beamer
276        Beamer vBeamer = new Beamer(100, "beamer"); 
277        vCuisine.addItem(vBeamer.getNomItem(), vBeamer);
278        
279        //Initalisation du joueur;
280        this.aPlayer = new Player ("Joueur", vForet);           
281        
282        //Initialisation du lieu de départ
283        this.aPlayer.setCurrentRoom(vForet);
284        
285    }
286
287    /**
288     * Prend une commande en paramètre et traite, exécute la commande.
289     * @param pCommandLine pour la commande saisie.
290     */
291    public void interpretCommand( final String pCommandLine ) 
292    {
293        this.aGui.println( "> " + pCommandLine );
294        Command vCommand = this.aParser.getCommand( pCommandLine );
295
296        if ( vCommand.isUnknown() ) {
297            this.aGui.println( "Je ne comprends pas ce que vous voulez faire..." );
298            return;
299        }
300
301        String vCommandWord = vCommand.getCommandWord();
302        
303        switch(vCommandWord){
304            case "help": printHelp(); this.counterone(); break;
305            case "go"  : goRoom(vCommand); this.counterone(); this.enigmes(); break; 
306            case "back" : this.back(vCommand); this.counterone(); break; 
307            case "test" : this.test(vCommand); this.counterone(); break; 
308            case "take" : this.take(vCommand); this.counterone(); break; 
309            case "drop" : this.drop(vCommand); this.counterone(); break; 
310            case "look" : this.look(); this.counterone(); break;  
311            case "quit" : if ( vCommand.hasSecondWord() ) {
312                            this.aGui.println( "Quitter quoi?" ); this.counterone(); break; }
313                          else {this.endGame(); this.counterone(); break; } 
314            case "inventaire" : this.inventaire(); this.counterone(); break;  
315            case "eat" : this.eat(vCommand);this.counterone(); break;  
316            case "charge" : this.charge(vCommand);this.counterone(); break;  
317            case "teleport" : this.teleport(vCommand);this.counterone(); break;  
318        }
319        
320        if(timelimit())return;  //teste si le temps (nbre de requêtes) est écoulé ou non.
321        this.win();             //teste si le jeu est gagné ou non (temps).
322    } //interpretCommand() 
323
324    /**
325     * Afficher des informations d'aide.
326     * Ici nous affichons du texte d'aide ainsi que la liste des mots commande.
327     */
328    private void printHelp() 
329    {
330        this.aGui.println( "------------------------------ A I D E -------------------------------" );
331        this.aGui.println( "Vous êtes seul, vous êtes quelque part dans l'enceinte du château." );
332        this.aGui.println( "Essayez de vous diriger." + "\n" );
333        this.aGui.println( "--> Vos mots cléfs (mots commande) sont : \n -->" + this.aParser.getCommandString() );
334        this.aGui.println( "----------------------------------------------------------------------" );
335        this.aGui.print( "\n" );
336    } //printHelp()
337
338    /** 
339     * Essaye d'aller dans une direction. S'il y a une sortie,
340     * on entre dans la nouvelle pièce, sinon, on affiche un message d'erreur.
341     */
342    private void goRoom( final Command pCommand ) 
343    {
344        if ( ! pCommand.hasSecondWord() ) {
345            // if there is no second word, we don't know where to go...
346            this.aGui.println( "Aller où ?" );
347            return;
348        }
349
350        //this.aPlayer.goRoomPlayer(pCommand); 
351        
352        String vDirection = pCommand.getSecondWord();
353        Room vNextRoom = this.aPlayer.getCurrentRoom().getExit(vDirection);
354        
355        if ( vNextRoom == null ) {
356            this.aGui.println( "-----------------------------S O R T I E S -------------------------------");
357            this.aGui.println( "Il n'y a pas de sorties dans cette direction ! \n" );
358        }
359        else {
360            this.aPlayer.goRoomPlayer(vNextRoom);
361            this.printLocationInfo();
362        }
363    } //goRoom()
364    
365    /**
366     * Arret du jeu : affichage d'un message d'au revoir et arrêt de l'interface graphique.
367     */
368    private void endGame()
369    {
370        this.aGui.println( "------------------------- E N D    G A M E -------------------------------" );
371        this.aGui.println( "\n" + "Merci d'avoir joué, " + this.aPlayer.getNomJoueur() + ". \nA très bientôt et au revoir." );
372        this.aGui.println( "--------------------------------------------------------------------------" );
373        this.aGui.println( "\n" + "Copyright : Jeu développé par Alban Ferracani. \nDans le cadre de l'unité A3P/IPO 2020-2021. \nMerci à Monsieur Bureau et tous les intervenants pour l'aide \napportée dans le développement de ce jeu. \n" );
374        this.aGui.enable( false );
375    }
376    
377    /**
378     * Permet de retourner en arrière. Vérifie également la présence de trapdoor et 
379     * bloque le retour en arrière dans ce cas.
380     * @param pDirection
381     */
382    private void back(final Command pDirection){
383        
384        //this.aCurrentRoom = this.aPreviousRoom;   
385        if (pDirection.hasSecondWord()){
386              this.aGui.print("Tapez la commande back sans 2nd mot.");
387        }
388        
389        if (!(this.aPlayer.getStackPreviousRoom().empty()) ) {
390            if (!(this.aPlayer.getCurrentRoom().getTrapDoor())) {
391              this.aPlayer.backPlayer();
392              this.printLocationInfo();
393            }
394            else {
395            this.aGui.println("Vous venez de franchir une trapdoor. \nVous ne pouvez pas retourner dans cette pièce par ce chemin.\n"); 
396            }
397            }
398        
399        else {
400            this.aGui.println("Vous êtes dans la première pièce. Pas de retour possible"); 
401        }
402
403       }//back()
404        
405    /**
406     * Utilisation de fichiers de test .txt pour vérifier le bon fonctionnement du jeu.
407     * Lecture du fichier et exécution des actions résultantes aux instructions du fichier.
408     * @param pCommandFichier
409     */   
410    private void test(final Command pCommandFichier)
411    {
412        if(!(pCommandFichier.hasSecondWord()))
413        {
414            this.aGui.println("Sélectionner un fichier pour tester la commande");
415            return;
416        }
417        
418        String vNomFichier = pCommandFichier.getSecondWord();
419        
420        try {
421            Scanner vScan = new Scanner (new File ("tests/"+vNomFichier + ".txt"));
422            
423            while (vScan.hasNextLine()){
424                String vLigne = vScan.nextLine();
425                interpretCommand(vLigne);
426                /*
427                for (double i=0; i<1000000; i+=0.01){
428                }
429                */
430            }
431            
432        }// try
433        
434        catch (java.io.FileNotFoundException pException){
435            this.aGui.println("Le fichier " + vNomFichier + " n'a pas été trouvé");
436        }// catch
437    } //test()
438    
439
440    /**
441     * Permet de prendre un item. Vérifie si l'item est bien présent dans la pièce 
442     * avant de le prendre.
443     * @param pCommand
444     */
445    private void take(final Command pCommand)
446    {
447        if(!pCommand.hasSecondWord())
448        {
449            this.aGui.println("Que souhaitez vous prendre ?");
450            return;
451        }  
452
453        String vItem = pCommand.getSecondWord();
454        Item vItemAPrendre = this.aPlayer.getCurrentRoom().getItem(vItem);
455
456        //this.aGui.println(vItemAPrendre.getShortDescription());
457        
458        if (vItemAPrendre == null) this.aGui.println("Il n'y a pas d'item à prendre !");
459        else{
460            if(this.aPlayer.tooHeavyItem(vItemAPrendre.getPoids()) == true){
461            this.aPlayer.takeItem(vItem, vItemAPrendre);
462            this.aPlayer.getCurrentRoom().removeItem(vItem, vItemAPrendre);
463            this.aGui.println("Vous avez pris l'item " + vItemAPrendre.getShortDescription());
464            this.printLocationInfo();
465           }   
466            else if(this.aPlayer.tooHeavyItem(vItemAPrendre.getPoids()) == false) this.aGui.println("L'item " + vItemAPrendre.getShortDescription() + " sélectionné est trop lourd !");
467        }      
468    } //take()
469    
470    /**
471     * Permet de lacher l'objet attrapé. Appelle les méthodes d'éxécution dans player et affichage.
472     * @param pCommand
473     */
474    private void drop(final Command pCommand)
475    {
476        if(!pCommand.hasSecondWord())
477        {
478            this.aGui.println("Que souhaitez vous laisser tomber ?");
479            return;
480        }
481
482        String vItem = pCommand.getSecondWord();
483        Item vItemADrop = this.aPlayer.getItem(vItem);
484
485        if(vItemADrop == null) this.aGui.println("Je n'ai pas cet item !");
486        
487        else{
488            this.aPlayer.getCurrentRoom().addItem(vItem, vItemADrop);
489            this.aPlayer.dropItem(vItem,vItemADrop);
490            this.aGui.println("C'est bon, vous avez laissé tomber l'item " +  vItemADrop.getShortDescription()+ " !\n");
491            this.printLocationInfo();
492        }
493    } //drop()
494    
495    /**
496     * Permet d'afficher la description de la pièce courante et d'afficher 
497     * le nombre de requêtes effectuées (timelimit)
498     */
499    private void look()
500    {
501        //this.aGui.println("--------------------------------------------------------------------------");
502        this.aGui.println(this.aPlayer.getCurrentRoom().getLongDescription());
503        //this.aGui.println("Vous avez effectué " + this.aPlayer.getInputCounter() + " requêtes sur un total de " + this.aCounterRequestMax + " autorisées \n");
504        this.aCounterRequestPourcentage = ((this.aPlayer.getInputCounter()-1)*100)/this.aCounterRequestMax;
505        if (this.aPlayer.getInputCounter() < (this.aCounterRequestMaxTotal)/3)
506        {
507            this.aGui.println("\nAttention, vous avez utilisé "+ (this.aPlayer.getInputCounter()-1) + " sur " + this.aCounterRequestMax + " commandes autorisées. \nSoit " + this.aCounterRequestPourcentage + " % de vos commandes disponibles. \n");
508        }
509        //this.aGui.println("--------------------------------------------------------------------------");
510    }//look()
511    
512
513    /**
514     * Permet d'afficher l'inventaire des items attrapés et mangés et de leur poids sous forme de liste.
515     * Affiche également le poids total du joueur + des items cumulés.
516     */
517    public void inventaire()
518    {
519        this.aGui.println( "---------------------------I N V E N T A I R E------------------------------" );
520        this.aGui.println(this.aPlayer.getItemsDescriptionPlayer());
521        this.aGui.println("Votre poids total : "+this.aPlayer.getPoidsPlayer() +"\n");
522        
523        URL url = getClass().getClassLoader().getResource("son/inventaire.wav");
524        AudioClip clip = Applet.newAudioClip(url);
525        
526        new Thread() {
527            public void run() {
528                clip.play();
529                clip.play();
530            }
531
532        }.start();
533    } //inventaire()
534    
535    /**
536     * Pour manger un magiccookie ou un objet. 
537     * @param pCommand l'instruction saisie.
538     */
539    private void eat(final Command pCommand)
540    {
541        if(!pCommand.hasSecondWord())
542        {
543            this.aGui.println("Que voulez vous manger ?");
544            return;
545        }   
546
547        String vItem = pCommand.getSecondWord();
548        Item vItemAPrendre = this.aPlayer.getCurrentRoom().getItem(vItem);
549        
550        if (vItemAPrendre == null) this.aGui.println("Il n'y a pas d'item à manger !");
551        
552        else {
553            if(vItem.equals("magiccookie")){
554                this.aPlayer.takeItem(vItem, vItemAPrendre);
555                this.aPlayer.getCurrentRoom().removeItem(vItem, vItemAPrendre);
556                this.aPlayer.setItemPoidsMax(this.aPlayer.getItemPoidsMax()*2);
557                this.aGui.println("------------------------E A T   M A G I C C O O K I E------------------------");
558                this.aGui.println("Vous avez mangé le magic cookie et avez doublé le poids des items que vous pouvez prendre");
559                this.aGui.println("Vous pouvez désormais porter des items d'un poids allant jusqu'à " + this.aPlayer.getItemPoidsMax() + "\n");
560            }
561            else
562                this.aGui.println("Vous ne pouvez pas manger cet item mais vous pouvez l'attraper.");
563        }
564    } //eat()
565    
566    /**
567     * Permet de compter le nombre de requetes effectuées par le joueur 
568     * et d'alerter le joueur lorsqu'il a utilisé plus d'1/3 des commandes 
569     * et d'arrêter le jeu lorsque le nombre maximal de requêtes autorisées est dépassé.
570     */
571    private boolean timelimit(){
572        
573        if(this.aPlayer.getInputCounter()>aCounterRequestMax){
574            this.aGui.clearText();
575            this.aGui.println("Vous avez utilisé "+ (this.aPlayer.getInputCounter()-1) + " sur " + this.aCounterRequestMax + " commandes autorisées. \nLe jeu va s'arrêter.");
576            this.endGame();
577            
578            URL url = getClass().getClassLoader().getResource("son/cheval.wav");
579            AudioClip clip = Applet.newAudioClip(url);
580        
581            URL urlfin = getClass().getClassLoader().getResource("son/sound2.wav");
582            AudioClip clipfin = Applet.newAudioClip(urlfin);
583
584            URL urlfin1 = getClass().getClassLoader().getResource("son/perducommandes.wav");
585            AudioClip clipfin1 = Applet.newAudioClip(urlfin1);
586            
587            new Thread() {
588                        public void run() {
589                            clip.play();        //cheval
590                            clipfin1.play();    //texte audio perdu
591                            clipfin.play();     //musique
592                        }
593                         
594                    }.start();
595                    
596            //this.aGui.enable(false);
597            return true;
598        }
599        else if(this.aPlayer.getInputCounter()>(aCounterRequestMax)/3){
600            this.aCounterRequestPourcentage = ((this.aPlayer.getInputCounter()-1)*100)/this.aCounterRequestMax;
601            this.aGui.println("Attention, vous avez utilisé "+ (this.aPlayer.getInputCounter()-1) + " sur " + this.aCounterRequestMax + " commandes autorisées. \nSoit " + this.aCounterRequestPourcentage + " % de vos commandes disponibles. \n");
602            
603            URL url = getClass().getClassLoader().getResource("son/coucou1.wav");
604            AudioClip clip = Applet.newAudioClip(url);
605        
606            new Thread() {
607            public void run() {
608                clip.play();
609            }
610            }.start();
611            
612            return false;
613        }
614        else return false;
615    } //timelimit()
616    
617    
618    /**
619     * Procédure permettant d'incrémenter de 1 le nombre de requêtes qu'a effectué le joueur.
620     * Permet d'éviter la diplication de code dans interpretCommand().
621     */
622    private void counterone(){
623        this.aPlayer.setInputCounter((this.aPlayer.getInputCounter())+1);
624    } //counterone() 
625    
626
627    /**
628     * Permet de charger le beamer.
629     * @param pCommand pour l'instruction saisie par le joueur.
630     */
631    private void charge(final Command pCommand)
632    {
633        if(!pCommand.hasSecondWord())
634        {
635            this.aGui.println("Que voulez vous charger ?");
636            return;
637        }
638
639        String vNom = pCommand.getSecondWord();
640        Beamer vBeamer = (Beamer)this.aPlayer.getItem(vNom);
641
642        if(vBeamer == null) this.aGui.println("Je ne l'ai pas !");
643        else{
644            vBeamer.charge(this.aPlayer.getCurrentRoom());
645            this.aGui.println("Le beamer est chargé. \nN'oubliez pas, pour savoir comment utiliser le beamer, revenez à l'énigme de la cuisine.\n");
646        }
647    } //charge()
648    
649    /**
650     * Teleport 
651     * @param pCommand pour l'instruction saisie par le joueur.
652     */
653    
654    private void teleport(final Command pCommand)
655    {
656        if(!pCommand.hasSecondWord())
657        {   
658            this.aGui.println("Tapez 'teleport' sans 2nd mot");
659            return;
660        }
661
662        String vNom = pCommand.getSecondWord();
663        Beamer vBeamer = (Beamer)this.aPlayer.getItem(vNom);
664
665        if(vBeamer == null) {
666            this.aGui.println("Je ne l'ai pas...");
667        }
668        else if(vBeamer.isCharged()==false) {
669            this.aGui.println("Le beamer n'est pas chargé !");
670        }
671        else{
672            vBeamer.discharge();
673            this.aPlayer.getStackPreviousRoom();
674            this.aPlayer.setCurrentRoom(vBeamer.getRoomCharge());
675            this.printLocationInfo();
676        }
677        }//teleport();
678    
679    /**
680     * Permet d'afficher les énigmes présentes dans chaque pièce.
681     */
682    private void enigmes(){
683        String vCurrentRoom = this.aPlayer.getCurrentRoom().getNomRoom();
684        String vEnigme = this.aPlayer.getCurrentRoom().getEnigme();
685        //this.aGui.printBold("", Color.blue.darker().darker().darker());  //Couleur du texte des autres pièces que la forêt.
686        this.aGui.println("-----------------------------E N I G M E S -------------------------------");
687        
688        if (vEnigme != null){
689        
690            switch(vCurrentRoom){
691                case "ecurie":              this.aGui.println(vEnigme); break;
692                case "jardin"  :            this.aGui.println(vEnigme); break; 
693                case "foret" :              this.aGui.println(vEnigme); break; 
694                case "entree" :             this.aGui.println(vEnigme); break; 
695                case "cuisine" :            this.aGui.println(vEnigme); break; 
696                case "salle a manger" :     this.aGui.println(vEnigme); break; 
697                case "salle de reception" : this.aGui.println(vEnigme); break;  
698                case "bureau royal" :       this.aGui.println(vEnigme); break;  
699                case "sous sol" :           this.aGui.println(vEnigme); break;  
700                case "passage secret" :     this.aGui.println(vEnigme); break;  
701                case "piece secrete" :      this.aGui.println(vEnigme); break;  
702            }
703        }
704        else if (vEnigme == null){
705            this.aGui.println("Pas d'énigmes pour vous guider, essayez de réfléchir...");
706        }
707        this.aGui.println("\n");
708    } //enigmes();
709    
710    /**
711     * Permet de vérifier si le joueur à gagné ou non et si oui d'afficher un message
712     * et d'arrêter le jeu.
713     * Prend en compte deux conditions : le nombre de requêtes ainsi que le temps passé sur le jeu.
714     */
715    private void win(){
716        String vItemStringRoom = this.aPlayer.getCurrentRoom().getItemWin();    
717        Date aDateActual = new Date();
718        this.aDateActualString = "" + aSTime.format(aDateActual);
719        
720        URL url = getClass().getClassLoader().getResource("son/cheval.wav");
721        AudioClip clip = Applet.newAudioClip(url);
722        
723        URL urlfin = getClass().getClassLoader().getResource("son/sound2.wav");
724        AudioClip clipfin = Applet.newAudioClip(urlfin);
725
726        URL urlfin1 = getClass().getClassLoader().getResource("son/gagne.wav");
727        AudioClip clipfin1 = Applet.newAudioClip(urlfin1);
728        
729        URL urlfin2 = getClass().getClassLoader().getResource("son/perdu.wav");
730        AudioClip clipfin2 = Applet.newAudioClip(urlfin2);
731                
732        
733        if (this.aPlayer.getCurrentRoom().getNomRoom().equals("jardin")){ 
734            if(vItemStringRoom != ""){
735                if(vItemStringRoom.equals("tresor1       Poids de l'item :1000.0tresor2       Poids de l'item :5000.0")){
736                    this.aGui.clearText();
737                    this.aGui.printBold("", Color.orange.darker().darker());
738                    this.aGui.println( "---------------------------G A G N E ! ! ! ! !-----------------------------" );
739                    this.aGui.println("Bravo, " + this.aPlayer.getNomJoueur() + ", vous avez réussi à prendre les deux trésors et \navez gagné ! ");
740                    if (aModeJeu == 1){ //Mode jeu facile
741                         this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode simple.");
742                    }
743                    else if (aModeJeu == 2){ //Mode jeu moyen
744                        this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode moyen.");
745                    }
746                    else if (aModeJeu == 3){ //Mode jeu difficile
747                        this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode difficile.");
748                    }
749                    this.aGui.println( "Vous pouvez rejouer en utilisant un mode plus difficile ! \n");
750                    this.endGame();
751                    //Musique de fin 
752                    new Thread() {
753                        public void run() {
754                            
755                            //clip.play();        //son cheval
756                            clipfin1.play();    //texte audio gagné
757                            //clipfin.play();     //musique
758                        } 
759                    }.start();
760                    
761                    new Thread() {
762                        public void run() {
763                            //clip.play();        //cheval
764                            //clipfin2.play();    //texte audio perdu
765                            clipfin.play();     //musique
766                        }
767                         
768                    }.start();
769                    
770                }
771                else if(vItemStringRoom.equals("tresor2       Poids de l'item :5000.0tresor1       Poids de l'item :1000.0")){
772                    this.aGui.clearText();
773                    this.aGui.printBold("", Color.orange.darker().darker());
774                    this.aGui.println( "---------------------------G A G N E ! ! ! ! !-----------------------------" );
775                    this.aGui.printBold("", Color.orange.darker().darker());
776                    this.aGui.println("Bravo, " + this.aPlayer.getNomJoueur() + ", vous avez réussi à prendre les deux trésors et \navez gagné ! ");
777                    if (aModeJeu == 1){ //Mode jeu facile
778                         this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode simple.");
779                    }
780                    else if (aModeJeu == 2){ //Mode jeu moyen
781                        this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode moyen.");
782                    }
783                    else if (aModeJeu == 3){ //Mode jeu difficile
784                        this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode difficile.");
785                    }
786                    this.aGui.println( "Vous pouvez rejouer en utilisant un mode plus difficile ! \n");
787                    this.endGame();
788                }
789            }
790            // this.aGui.println("Heure départ du jeu : " + this.aDateBeginString);
791            // this.aGui.println("Heure fin du jeu : " + this.aDateEndString);
792            // this.aGui.println("Heure actuelle : " + this.aDateActualString + "\n");
793            
794        }
795        
796        //Si le temps est dépassé.
797        else if (this.aDateActualString.equals(this.aDateEndString)){
798            this.aGui.clearText();
799            this.aGui.println( "---------------------------P E R D U ! ! ! ! !-----------------------------" );
800            this.aGui.printBold("", Color.orange.darker().darker());
801            this.aGui.println("Dommage, " + this.aPlayer.getNomJoueur() + ", vous avez perdu car vous avez dépassé le temps limite !");
802            if (aModeJeu == 1){ //Mode jeu facile
803                         this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode simple.");
804                         this.aGui.println( "Vous pouvez rejouer en utilisant le même mode car c'est le plus facile ! \n");
805                    }
806                    else if (aModeJeu == 2){ //Mode jeu moyen
807                        this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode moyen.");
808                        this.aGui.println( "Vous pouvez rejouer en utilisant un mode plus facile (mode 1) ! \n");
809                    }
810                    else if (aModeJeu == 3){ //Mode jeu difficile
811                        this.aGui.println( "Vous avez joué avec le mode jeu n°" + this.aModeJeu + " soit le mode difficile.");
812                        this.aGui.println( "Vous pouvez rejouer en utilisant un mode plus facile (mode 1 ou 2) ! \n");
813                    }
814            this.endGame();
815            //Musique de fin 
816            new Thread() {
817                        public void run() {
818                            //clip.play();        //cheval
819                            clipfin2.play();    //texte audio perdu
820                            //clipfin.play();     //musique
821                        }
822                         
823                    }.start();
824                    
825            new Thread() {
826                        public void run() {
827                            //clip.play();        //cheval
828                            //clipfin2.play();    //texte audio perdu
829                            clipfin.play();     //musique
830                        }
831                         
832                    }.start();
833        } 
834        
835        // Dans les autres cas, on affiche l'heure de départ, de fin et celle courante.
836        else {
837            this.aGui.println("Heure départ du jeu : " + this.aDateBeginString);
838            this.aGui.println("Heure fin du jeu : " + this.aDateEndString);
839            this.aGui.println("Heure actuelle : " + this.aDateActualString + "\n");
840        } 
841    } //win()
842    
843    
844    /**
845     * endHour pour calculer l'heure finale à partie de l'heure actuelle.
846     * @param pMinConseille un entier qui correspond au temps imparti en minutes.
847     */
848    private String endHour(final int pMinConseille){
849            //Partie calcul de l'heure de fin.
850            int vDateEndMin = Integer.parseInt(aSMin.format(aDate));        //On convertit les minutes (string) en un int.
851            vDateEndMin += pMinConseille;                                   //On ajoute le temps conseillé (minutes).
852            this.aDateEndMin =  vDateEndMin;                            
853            
854            int vDateEndHours = Integer.parseInt(aSHours.format(aDate));    //On convertit les minutes (string) en un int.
855            vDateEndHours += 0;                                             //On ajoute le temps conseillé (heures).
856            this.aDateEndHours = vDateEndHours;
857            
858            String vDateEndMinString ="";
859            String vDateEndHoursString ="";
860            //Si les minutes de l'heure de fin est supérieure à 60 on ajoute 1h et soustrait 60 min.
861            if (!(this.aDateEndMin < 60)) {
862                this.aDateEndMin =  aDateEndMin -= 60;
863                this.aDateEndHours = aDateEndHours += 1 ; 
864                //Si le nombre des minutes est inférieur à 10, on ajoute un 0 pour afficher 20:09 au lieu de 20:9 du à la soustraction des minutes.
865                if (this.aDateEndMin < 10){
866                    vDateEndMinString = "0" + aDateEndMin;
867                }
868                else {
869                    vDateEndMinString = "" + aDateEndMin;
870                }
871            }
872            // Sinon, on n'ajoute rien (on considère que le joueur ne passera pas plus d'une heure sur le jeu).
873            else {
874                //vDateEndMinString = "" + this.aDateEndMin;
875                //this.aDateEndHours = aDateEndHours ; 
876                
877                if (this.aDateEndMin < 10){
878                    vDateEndMinString = "0" + aDateEndMin;
879                }
880                else {
881                    vDateEndMinString = "" + aDateEndMin;
882                }
883                this.aDateEndHours = aDateEndHours ;   
884            }
885            
886            //Si le nombre des heures est inférieur à 10, on ajoute un 0 devant pour afficher 09:12 au lieu de 9:12.
887            if(this.aDateEndHours < 10){
888                vDateEndHoursString = "0" + aDateEndHours;
889            }
890            else if(10 <= this.aDateEndHours ){
891                vDateEndHoursString = "" + aDateEndHours;
892            }
893            
894            this.aDateEndString = vDateEndHoursString + ":" + vDateEndMinString;  //Heure de fin conseillée. 
895            return this.aDateEndString; //Heure de fin conseillée. 
896    }// endHour()
897    
898    
899}
900