Le but de ce TP est d'implémenter un jeu de dés. Le joueur essaye de prédire le résultat d'un lancer de dés, s'il devine juste il a gagné, sinon il a perdu.
Pour jouer, il devra lancer la commande `interface.sh p n`, où
* `p` est la prédiction,
* `n` le nombre de faces du dés.
Le joueur pourra aussi consulter des statistiques sur les résultats des parties précédentes grâce à la commande `statistiques.sh`.
Le projet comportera 3 fichiers script:
* `random.sh n` qui simule un lancer de dés à `n` faces : prend en paramètre le nombre de faces et renvoie une valeur aléatoire entre 1 et ce nombre `n`,
* `interface.sh p n` qui simule une partie où le joueur prédit que la face `p` va sortir sur un lancer de dés à `n` faces,
* `statistiques.sh` qui permettra de consulter les statistiques sur les partie précédentes.
# Level 0
---
* **Q1:** Écrire un script `random.sh` qui prend comme seul argument un entier.
Le script doit afficher un message d'erreur indiquant clairement les raisons de l'erreur et renvoyer Faux (code sortie 1) si et seulement si:
+ Le nombre d'argument n'est pas égal à 1.
+ L'unique argument passé n'est pas supérieur ou égal à 0.
* **Q2:** Si les arguments sont corrects, le script `random.sh n` doit maintenant tirer un nombre au hasard entre 1 et n et écrire le résultat obtenu dans un fichier `jet`. Pour ce faire vous pourrez utiliser la variable **$RANDOM** ainsi que modulo : étant un nombre **N**, l'opération modulo **N % 10** permet d'avoir un nombre compris entre **0** et **N-1**.
* **Q3:** Écrire un script `interface.sh` qui prend en arguments 2 entiers.
Le script doit afficher un message d'erreur indiquant clairement les raisons de l'erreur et renvoyer Faux (code sortie 1) si et seulement si:
+ Le nombre d'argument n'est pas égal à 2.
+ L'un des deux argument n'est pas supérieur ou égal à 0.
+ Le premier argument est strictement inférieur au second.
* **Q4:** Si les arguments sont corrects, le script `interface.sh p n` doit maintenant:
+ appeler le script `random.sh n`
+ lire le résultat écrit dans le fichier `jeu`
+ afficher "gagné" si le résultat est égal à `p` et "perdu" sinon.
* **Q5:** Le script `interface.sh` doit maintenant écrire dans un fichier `resultats`:
+ `0` si la partie est perdue
+ `1` si la partie est gagnée
*Attention : L'ensemble des résultats doit être stocké dans le fichier `resultats`, ainsi à chaque utilisation du script `interface.sh` le résultat doit être inscrit à la suite des résultats précédents et non pas les écraser !*
* **Q6:** Écrire un script `statistiques.sh` qui lit le fichier `resultats` et affiche la proportion de partie gagné sous la forme:
```
Vous avez gagné X partie sur Y.
```
Où `X` est le nombre de parties gagnées et `Y` le nombre total de parties.
_Note : Pour ce faire, on pourra utiliser les fonctionnalités découvertes dans les TP précédents et permettant de parcourir un fichier ligne à ligne (on lit une ligne, regarde si la valeur est ou non un 1 et en fonction on incrémente les statistiques)_
# Level 1
---
Le joueur doit maintenant pouvoir effectuer plusieurs lancés de dés à la suite avec un seul appel du script `interface.sh`, il a le droit à `k` lancers.
Dans un premier temps, l'objectif va être que le joueur lance `k` fois le dés et que les résultats de ces `k` lancers soient stockés dans le fichier `résultats.txt` et affiché à l'écran (pour chaque lancer on indique à l'écran si c'est gagné ou perdu). Pour parvenir à cela, répondez aux Q1 à Q7.
* **Q1:** Modifier `interface.sh` pour qu'il accepte un troisième entier `k` comme argument. Cet entier sera le nombre de jets de dès total. Le script renverra un message d'erreur adapté si ce troisième argument n'est pas supérieur ou égal à 0.
* **Q2:** Écrire une fonction `multiple()` dans `interface.sh` qui lancera `k` fois le dés et inscrira les résultats obtenus dans `résultats.txt`. Modifier ensuite `interface.sh p n k` pour que cette fonction `multiple()` soit appelée dans le script et que le dés soit lancé `k` fois.
* **Q3:** Lancer la commande suivante pour créer l'arborescence donnée :
```sh
mkdir R1 R1/R2 R1/R3 R1/R3/R4
```
* **Q4:** Dans chacun des dossier créés (R1, R2, R3, R4), lancer `interface.sh 3 6 10` afin qu'il y ai un fichier `résultats` par dossier `Ri`.
* **Q5:** Modifier `statistiques.sh` pour qu'il puisse parcourir tous les fichiers de l’arborescence. Le script devra afficher le taux de victoire pour chacun des fichiers `resultats` trouvés en indiquant également le dossier dans lequel ce trouve ce fichier `résultats.txt`. Par exemple :
`R3 : Vous avez gagné X partie sur Y.`
* **Q6:** Écrire une fonction `multipleRec()` qui fera la même chose que `multiple()` de manière récursive. Modifier ensuite `interface.sh` pour qu'il n'utilise plus que la fonction `multipleRec()`
* **Q7:** Le script `interface.sh` doit maintenant s'arrêter dès le premier lancer où le résultat obtenu est égal à la prédiction et indiquer au bout de combien de coups cette victoire a été obtenue. Par exemple : `Gagné après 6 coups sur 8 tentatives possibles`.
_Note : Pour ce faire, on pourra par exemple ajouter un paramètres à la fonction multipleRec() indiquant le nombre de lancers déjà effectués_
# Level 2
Le processus `random.sh` devra maintenant être appelé en arrière plan et l'interface `interface.sh` demandera des lancers via des signaux. L'objectif sera également de pouvoir afficher les résultats en utilisant des signaux.
---
* **Q1:** Dans `interface.sh`, créer une variable `pidInterface` contenant le PID de son processus, accessible à tous les processus fils.
* **Q2:** Modifier `random.sh` pour qu'à son lancement il écrive son PID dans un fichier `pid_random`.
* **Q3:** Modifier `random.sh` pour qu'il n'effectue un lancer que lorsque son processus reçoit le signal `USR1`. Pour ce faire vous devrez créer une boucle infinie dans le script `random.sh` et n'en sortir qu'à condition qu'un signal provenant de type `USR1`soit reçu. Une fois ce signal reçu et le lancer effectué, `random.sh` indiquera que le lancer est fini en envoyant un signal `USR2` à `interface.sh`.
* **Q4:** Modifier `interface.sh p n k` pour que le script lance `random.sh` en arrière plan. Une fois `random.sh` lancé, on va maintenant communiquer avec lui à l'aide de signaux :
* on lui envoie un signal `USR1` pour lui demander la génération d'un nombre random;
* on attend qu'il nous envoie en retour un signal nous indiquant qu'il a bien écrit le résultat dans un fichier;
* on lit le résultat dans le fichier et on vérifié si elle correspond au non ou au résultat attendu (pronostic de l'utilisateur). Si cette valeur correspond bien au pronostic, ou que l'on a effectué les `k` lancés autorisés, on arrête d'attendre et on tue le processus `random.sh` (en utilisant son PID).
* **Q5:** Créer un script `dernierResulat.sh` qui lira la dernière ligne du fichier `résultats.txt` et affichera:
+ `La dernière partie est gagne` si on lit un `1`
+ `La dernière partie est perdue` si on lit un `0`
* **Q6:** Modifier `dernierResulat.sh` pour qu'il n'affiche les résultats que s'il reçoit un signal `USR3`.
* **Q7:** Appeler le script `dernierResulat.sh` en arrière-plan, et afficher les résultats dans un second terminal.