parent
a847108b95
commit
a1223abe73
@ -0,0 +1,78 @@
|
||||
# TP1
|
||||
|
||||
Réalisez un jeu dans le style de wordle. Il doit permettre de saisir un mot au joueur tant que ce dernier est en vie. Après chaque saisie, le programme donne au joueur son nombre de vies restantes et les lettres trouvées. Sinon, il s'arrête.
|
||||
Les vies doivent être représentées par un nombre de ♥ (\u2665) dans une String.
|
||||
|
||||
Voici un exemple :
|
||||
|
||||
````
|
||||
Vous devez trouver _ _ _ _
|
||||
PV : ♥♥♥♥
|
||||
Entrez votre proposition : liste
|
||||
li _ _
|
||||
PV : ♥♥♥
|
||||
Entrez votre proposition : lien
|
||||
li _ n
|
||||
PV : ♥♥
|
||||
Entrez votre proposition : lion
|
||||
lion
|
||||
C'est gagné !
|
||||
|
||||
````
|
||||
|
||||
Codé en Java, voici ce que celà donne :
|
||||
````Java
|
||||
public class Main {
|
||||
|
||||
private static final String ECHAPEMENT = "_";
|
||||
|
||||
private static String verifieChaqueCaractereEtConcatener(String motATrouver, String motSaisi) {
|
||||
String retour = "";
|
||||
for (int i=0;i<motATrouver.length();i++){
|
||||
retour += prendSiIdentique(motATrouver.toLowerCase().charAt(i),motSaisi.toLowerCase().charAt(i))
|
||||
?motSaisi.charAt(i)
|
||||
:ECHAPEMENT;
|
||||
}
|
||||
return retour;
|
||||
}
|
||||
|
||||
private static boolean prendSiIdentique(char aTrouver, char proposition) {
|
||||
return aTrouver == proposition;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final String MOT_A_TROUVER = "Lion";
|
||||
|
||||
var saisie = new Scanner(System.in);
|
||||
var vie = "♥♥♥♥";
|
||||
|
||||
System.out.println("Vous devez trouver ____");
|
||||
while (!vie.isEmpty()) {
|
||||
System.out.println("PV : "+vie);
|
||||
System.out.print("Entrez votre proposition :");
|
||||
String motSaisi = saisie.nextLine();
|
||||
String resultat = verifieChaqueCaractereEtConcatener(MOT_A_TROUVER,motSaisi);
|
||||
System.out.println(resultat);
|
||||
if (resultat.contains(ECHAPEMENT)) {
|
||||
vie = vie.substring(0,vie.length()-1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(vie.isEmpty()){
|
||||
System.out.println("C'est perdu");
|
||||
} else {
|
||||
System.out.println("C'est gagné");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
### Q1 : Traduisez en Kotlin le code Java ci-dessous.
|
||||
|
||||
### Q2 : Transformez votre code pour le rendre plus "kotlin spirit". Par exemple, vous pourriez créer l'opérateur -- sur String.
|
||||
|
||||
### Q3 : Essayez de réduire au maximum le nombre de lignes de votre code.
|
||||
|
||||
### Q4 : Ajoutez la gestion des lettres mal placées avec une coloration différente pour les signaler.
|
@ -0,0 +1,127 @@
|
||||
Le but de cet exercice est d'implémenter un petit système de notifications simple, dans lequel un `Notifier` peut prévenir d'autres objets, les `Receiver`, qu'un événement intéressant s'est produit. Les seuls *notifiers* que nous créerons sont des générateurs d'objets qui notifient leurs *receivers* dès qu'un nouvel objet a été créé. Ces différents éléments sont architecturés comme décrit dans le diagramme suivant :
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
skinparam classAttributeIconSize 0
|
||||
skinparam monochrome true
|
||||
skinparam shadowing false
|
||||
skinparam linetype ortho
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor transparent
|
||||
}
|
||||
|
||||
skinparam note {
|
||||
BackgroundColor transparent
|
||||
}
|
||||
|
||||
hide circle
|
||||
|
||||
|
||||
abstract class Notifier {
|
||||
+notifyAllReceivers(data : Any)
|
||||
+addReceiver(rec : Receiver) {exceptions = FullException}
|
||||
+removeLastReceiver(rec : Receiver)
|
||||
}
|
||||
|
||||
interface Receiver {
|
||||
+receive(data : Any)
|
||||
}
|
||||
|
||||
abstract class Generator {
|
||||
-millisecToWait : Int
|
||||
-continueGeneration : Boolean
|
||||
-thread : Thread
|
||||
|
||||
+Generator(secondsToWait : Float)
|
||||
+startGenerate()
|
||||
+stopGenerate()
|
||||
+{abstract}generate() : Any
|
||||
}
|
||||
|
||||
class FullException extends Exception { }
|
||||
|
||||
class FloatGenerator {
|
||||
+FloatGenerator()
|
||||
+FloatGenerator(secondsToWait : Float, upperBound : Float)
|
||||
+generate() : Float
|
||||
}
|
||||
|
||||
class Person {
|
||||
-firstName : String
|
||||
-lastName : String
|
||||
|
||||
+Person(firstName : String, lastName : String)
|
||||
+getFirstName() : String
|
||||
+getLastName() : String
|
||||
}
|
||||
|
||||
class PersonGenerator {
|
||||
-{static}lastNames : String[] = {"Dupont", "Schmidt", "Clavore"}
|
||||
-{static}firstNames : String[] = {"Jean", "Paul", "Marie"}
|
||||
|
||||
+PersonGenerator(secondsToWait : Float)
|
||||
+generate() : Person
|
||||
}
|
||||
|
||||
class ConsolePrinter {
|
||||
-id : String
|
||||
|
||||
+ConsolePrinter(id : String)
|
||||
+receive(data : Any)
|
||||
}
|
||||
|
||||
class NumberAccumulator {
|
||||
-accumulatedValue : Double
|
||||
|
||||
+receive(data : Any)
|
||||
+getAccumulatedValue() : Double
|
||||
}
|
||||
|
||||
Notifier ---> "0..3\n-receivers" Receiver
|
||||
Notifier <|-- Generator
|
||||
Generator <|-- FloatGenerator
|
||||
Generator <|-- PersonGenerator
|
||||
PersonGenerator ..> Person
|
||||
Receiver <|.. ConsolePrinter
|
||||
Receiver <|.. NumberAccumulator
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
Il vous est demandé de coder cette conception en Kotlin.
|
||||
|
||||
**Attention**, le but n'est pas d'aller le plus rapidement possible, mais de prendre le temps d'explorer les possibilités du langage pour essayer d'être concis et d'adopter le Kotlin spirit.
|
||||
|
||||
Les noms des méthodes sont explicites, vous devez être capable de déterminer quoi code. Voici juste quelques informations supplémentaires qui pourront vous aider :
|
||||
|
||||
* Les *receivers* seront stockés dans un simple tableau;
|
||||
* La méthode `addReceiver(…)` lèvera une exception lorsque le tableau des *receivers* sera plein;
|
||||
* La classe `ConsolePrinter`, dès qu'elle sera notifiée de la réception d'une donnée, affichera cette donnée sur la sortie standard, préfixée par «id:» où id est évidemment l'`id` du `ConsolePrinter`;
|
||||
* La classe `NumberAccumulator`, dès qu'elle sera notifiée de la réception d'une donnée, ajoutera cette donnée à son `accumulatedValue` si cette dernière est un nombre (peu importe son type réel);
|
||||
* La classe `Generator` doit permet de générer un objet (grâce à `generate(…)`) toutes les `secondsToWait` secondes. Chaque générateur possèdera son thread pour effectuer cette génération.
|
||||
* La classe `FloatGenerator` générera un flottant compris entre 0 et `upperBound`. Sans informations explicites, cette génération se fera toutes les secondes et la borne supérieure sera 1000.
|
||||
* La classe `PersonGenerator` génèrera des personnes dont la combinaison «Prénom Nom» est choisie aléatoirement parmi les tableaux `firstNames` et `lastNames`.
|
||||
|
||||
Le programme suivant devra compiler :
|
||||
|
||||
```kotlin
|
||||
fun main() {
|
||||
val personGen = PersonGenerator(0.8f)
|
||||
val numGen = FloatGenerator(0.2f, 91827364.5f)
|
||||
val acc = NumberAccumulator()
|
||||
|
||||
personGen.addReceiver(::println)
|
||||
personGen.addReceiver(acc)
|
||||
numGen.addReceiver(::println)
|
||||
numGen.addReceiver(acc)
|
||||
|
||||
personGen.startGenerate()
|
||||
numGen.startGenerate()
|
||||
Thread.sleep(5000)
|
||||
personGen.stopGenerate()
|
||||
numGen.stopGenerate()
|
||||
|
||||
println(acc.accumulatedValue)
|
||||
}
|
||||
```
|
Loading…
Reference in new issue