UnoAdventure
Consignes
Ce travail pratique de soutien fait office d'examen blanc pour vous préparer à l'épreuve finale. Il est conçu pour être réalisé en 3 heures, mais ne vous inquiétez pas si vous ne le terminez pas complètement - il est volontairement un peu plus long que l'examen réel.
L'objectif est de vous permettre de réviser et de consolider vos acquis en programmation C#. N'hésitez pas à poser des questions sur Discord si vous rencontrez des difficultés.
Voici un TP de soutien, faisant office d'exam blanc, vous étant proposé pour préparer l'exam. Ce Tp est censé pouvoir être réalisé en 3h de temps, cependant aucun stress si vous ne l'avez pas fini, il est légèrement plus long que l'exam.
Bonnes révisions et n'hésitez pas à poser des questions au besoin, que ce soit sur discord.
Architecture
À la fin, votre dépôt git doit suivre cette architecture :
.
├── .gitignore
├── README
├── UnoAdventure
│ ├── Cards
│ │ ├── BasicCard.cs
│ │ ├── Card.cs
│ │ ├── JokerCard.cs
│ │ └── SpecialCard.cs
│ ├── Enums.cs
│ ├── GameManager.cs
│ ├── Player.cs
│ ├── Program.cs
│ ├── UnoAdventure.csproj
│ └── UnoException.cs
└── UnoAdventure.sln
Vérification de l'arborescence : Vous pouvez vérifier l'arborescence actuelle de votre dépôt avec la commande suivante :
tree . -I 'obj|bin|.idea|.git' -a
Exigences importantes avant soumission :
- Remplacez évidemment prenom.nom par votre login.
- Le fichier README est obligatoire.
- Le fichier .gitignore est obligatoire.
- Supprimez tous les tests personnels de votre code, sauf ceux du dossier Tests.
- Les prototypes donnés doivent être strictement respectés.
- Le code DOIT compiler ! Sinon vous n'obtiendrez pas de note.
Exemple de création de projet :
dotnet new sln --name UnoAdventure
dotnet new console -n UnoAdventure -f net7.0 -lang 'C#'
dotnet sln add UnoAdventure/UnoAdventure.csproj
Fundamentals
File: UnoException.cs
UnoException
Ceci est une exception que nous utiliserons tout au long du TP.
Copiez là dans UnoException.cs
public class UnoException : Exception { }
File: Enums.cs
ColorEnum
Ceci est une énumération qui représente les quatre couleurs des cartes de Uno.
Vous devez définir les couleurs suivantes, leur associant la valeur entre parenthèses.
ColorGreen(0)ColorRed(1)ColorBlue(2)ColorYellow(3)
File: Card/Card.cs
Fields
Ici, nous allons définir une classe Card qui représente une carte de Uno. Nous définirons les différents types de cartes juste après.
La classe Card doit avoir les attributs suivants :
- Un attrubut privé
Valuede typestringqui représente la valeur de la carte (exemple: "7", "Reverse", ect...).
Constructeur
La classe Card doit avoir un constructeur qui initialise l'attribut Value à partir de la cardValue passée en paramètre.
public Card(string cardValue) { }
Wait the next function if you want to test properly the constructor.
GetCardValue
La classe Card doit avoir une méthode GetCardValue qui retourne l'attribut Value de la carte.
public string GetCardValue() { }
Card card = new Card("7");
Console.WriteLine(card.GetCardValue()); // Affiche "7"
Card card2 = new Card("Reverse");
Console.WriteLine(card2.GetCardValue()); // Affiche "Reverse"
File: Card/BasicCard.cs
Fields
Ici, nous allons définir une classe BasicCard qui représente une carte de Uno avec une valeur numérique (exemple: 6 rouge).
La classe BasicCard doit hériter de Card.
La classe BasicCard doit avoir les attributs suivants :
- Un attribut public
Colorde typeColorEnumqui représente la couleur de la carte.
Constructeur
La classe BasicCard doit avoir un constructeur qui initialise les attributs Value et Color à partir de la cardValue et cardColor passés en paramètre.
Attention, la valeur d'une carte basique ne peut pas excéder une taille de 1 et contenir une autre valeur qu'un chiffre. Sinon, levez une UnoException.
public BasicCard(string cardValue, ColorEnum cardColor) { }
BasicCard card = new BasicCard("7", ColorEnum.ColorRed);
Console.WriteLine(card.GetCardValue()); // Affiche "7"
Console.WriteLine(card.Color); // Affiche "ColorRed"
BasicCard card2 = new BasicCard("Reverse", ColorEnum.ColorRed); // Lève une UnoException
File: Card/SpecialCard.cs
Fields
Ici, nous allons définir une classe SpecialCard qui représente une carte de Uno spéciale (exemple: "Reverse" bleue).
La classe SpecialCard doit hériter de Card.
La classe SpecialCard doit avoir les attributs suivants :
- Un attribut public
Colorde typeColorEnumqui représente la couleur de la carte.
Constructeur
La classe SpecialCard doit avoir un constructeur qui initialise les attributs Value et Color à partir de la cardValue et cardColor passés en paramètre.
Attention, la valeur d'une carte spéciale ne peut etre que "Skip", "PickTwo" ou "Reverse".
public SpecialCard(string cardValue, ColorEnum cardColor) { }
SpecialCard card = new SpecialCard("Reverse", ColorEnum.ColorBlue);
Console.WriteLine(card.GetCardValue()); // Affiche "Reverse"
Console.WriteLine(card.Color); // Affiche "ColorBlue"
SpecialCard card2 = new SpecialCard("2", ColorEnum.ColorGreen); // Lève une UnoException
File: Card/JokerCard.cs
Fields
Ici, nous allons définir une classe JokerCard qui représente une carte de Uno spéciale (exemple: "Joker").
La classe JokerCard doit hériter de Card.
La classe JokerCard doit avoir les attributs suivants :
- Un attribut privé
_penaltyde typeushortqui représente la pénalité de la carte. (exemple: +4)
Constructeur
La classe JokerCard doit avoir un constructeur qui initialise les attributs Value et _penalty à partir de penalty passé en paramètre.
La valeur d'une carte Joker est "Joker{penalty}".
La pénalité doit être un multiple de 2 et ne doit pas être supérieure (strict) à 8.
public JokerCard(ushort penalty) { }
JokerCard card = new JokerCard(4);
Console.WriteLine(card.GetCardValue()); // Affiche "Joker4"
JokerCard card2 = new JokerCard(0);
Console.WriteLine(card2.GetCardValue()); // Affiche "Joker0"
JokerCard card3 = new JokerCard(7); // Lève une UnoException
File: Player.cs
Propriétés
Ici, nous allons définir une classe Player qui représente un joueur de Uno.
La classe Player doit avoir les propriétés suivantes :
- Une propriété publique
Namede typestringqui représente le nom du joueur (n'ayant qu'un getter). - Une propriété publique
Handde typeCard[]qui représente la main du joueur (ayant un getter et un setter). - Une propriété publique
NbCardsde typeushortn'ayant qu'un getter qui doit renvoyer le nombre de cartes que le joueur a dans sa main.
Vous devez changer le getter de base de NbCards pour qu'il puisse vous renvoyer le nombre de cartes du joueur.
Constructeur
La classe Player doit avoir un constructeur qui initialise le Name à partir du name passé en paramètre.
La main du joueur doit être vide à sa création (tableau de taille 0).
public Player(string name) { }
Player player = new Player("Alice");
Console.WriteLine(player.Name); // Affiche "Alice"
Console.WriteLine(player.NbCards); // Affiche 0
GetNumberOfCardsByColor
La classe Player doit avoir une méthode GetNumberOfCardsByColor qui retourne un dictionnaire contenant le nombre de cartes de chaque couleur que le joueur possède.
Les clés du dictionnaire sont les couleurs des cartes et les valeurs associées sont le nombre de cartes de cette couleur.
public Dictionary<ColorEnum, ushort> GetNumberOfCardsByColor() { }
Player player = new Player("Alice");
player.Hand = new Card[] { new BasicCard("7", ColorEnum.ColorRed), new SpecialCard("Reverse", ColorEnum.ColorBlue) };
Dictionary<ColorEnum, ushort> cardsByColor = player.GetNumberOfCardsByColor();
Console.WriteLine(cardsByColor[ColorEnum.ColorRed]); // Affiche 1
Console.WriteLine(cardsByColor[ColorEnum.ColorBlue]); // Affiche 1
Console.WriteLine(cardsByColor[ColorEnum.ColorGreen]); // Affiche 0
Console.WriteLine(cardsByColor[ColorEnum.ColorYellow]); // Affiche 0
GetBestColor
La classe Player doit avoir une méthode GetBestColor qui retourne la couleur la plus présente dans la main du joueur.
Si le joueur a autant de cartes de chaque couleur, la méthode doit retourner la couleur avec la plus petite valeur associée (rien à voir avec les valeurs des cartes). Souvenez-vous, nous avons associé des valeurs à nos couleurs: 0 pour vert, 1 pour rouge, 2 pour bleu et 3 pour jaune.
public ColorEnum GetBestColor() { }
Player player = new Player("Alice");
player.Hand = new Card[] { new BasicCard("7", ColorEnum.ColorRed), new SpecialCard("Reverse", ColorEnum.ColorBlue) };
Console.WriteLine(player.GetBestColor()); // Affiche ColorRed
Player player2 = new Player("Bob");
player2.Hand = new Card[] { new SpecialCard("PickTwo", ColorEnum.ColorRed), new BasicCard("7", ColorEnum.ColorBlue), new BasicCard("8", ColorEnum.ColorBlue) };
Console.WriteLine(player2.GetBestColor()); // Affiche ColorBlue
GetCardsByColor
La classe Player doit avoir une méthode GetCardsByColor qui retourne un tableau de listes de cartes. Chaque liste de cartes représente les cartes d'une couleur.
Les listes doivent être ordonnées par leur valeur (ColorEnum). Le tableau doit être de taille 5 car il y a 4 couleurs et une liste pour les cartes joker.
public List<Card>[] GetCardsByColor() { }
Player player = new Player("Alice");
player.Hand = new Card[] { new BasicCard("7", ColorEnum.ColorRed), new BasicCard("2", ColorEnum.ColorRed), new SpecialCard("Reverse", ColorEnum.ColorBlue), new JokerCard(4) };
List<Card>[] cardsByColor = player.GetCardsByColor();
Console.WriteLine(cardsByColor[(int)ColorEnum.ColorRed].Count); // Affiche 2
Console.WriteLine(cardsByColor[(int)ColorEnum.ColorBlue].Count); // Affiche 1
Console.WriteLine(cardsByColor[(int)ColorEnum.ColorGreen].Count); // Affiche 0
Console.WriteLine(cardsByColor[(int)ColorEnum.ColorYellow].Count); // Affiche 0
Console.WriteLine(cardsByColor[4].Count); // Affiche 1
Selection Sort
Ici nous allons implémenter un algorithme de tri par sélection pour trier les cartes d'une couleur donnée dans l'ordre décroissant.
La classe Player doit avoir une méthode GetMaxIndexCard qui retourne l'index de la carte de valeur maximale dans la liste cards à partir de l'index start.
La classe Player doit aussi avoir une méthode SortCardsWithSameColor qui trie les cartes de la liste cards par ordre décroissant de valeur.
Parce que les valeurs des cartes sont des string (et qu'elles peuvent être des chiffres ou des mots), vous devez utiliser la méthode String.Compare pour comparer les valeurs des cartes.
La méthode String.Compare retourne un entier négatif si l'objet est inférieur à l'objet passé en paramètre, 0 si les deux objets sont égaux et un entier positif si l'objet est supérieur à l'objet passé en paramètre.
Nous choisirons la StringComparison.Ordinal pour comparer les valeurs des cartes.
Par exemple:
String.Compare("7", "Reverse", StringComparison.Ordinal); // Retourne un entier négatif car "7" est inférieur à "Reverse"
String.Compare("7", "7", StringComparison.Ordinal); // Retourne 0 car "7" est égal à "7"
String.Compare("Reverse", "7", StringComparison.Ordinal); // Retourne un entier positif car "Reverse" est supérieur à "7"
public int GetMaxIndexCard(List<Card> cards, int start) { }
Player player = new Player("Alice");
List<Card> cards = new List<Card> { new BasicCard("7", ColorEnum.ColorRed), new SpecialCard("Reverse", ColorEnum.ColorRed), new BasicCard("2", ColorEnum.ColorRed) };
Console.WriteLine(player.GetMaxIndexCard(cards, 0)); // Affiche 1
Console.WriteLine(player.GetMaxIndexCard(cards, 2)); // Affiche 2
public void SortCardsWithSameColor(List<Card> cards) { }
Player player = new Player("Alice");
List<Card> cards = new List<Card> { new BasicCard("7", ColorEnum.ColorRed), new SpecialCard("Reverse", ColorEnum.ColorRed), new BasicCard("2", ColorEnum.ColorRed) };
player.SortCardsWithSameColor(cards);
Console.WriteLine(cards[0].GetCardValue()); // Affiche "Reverse"
Console.WriteLine(cards[1].GetCardValue()); // Affiche "7"
Console.WriteLine(cards[2].GetCardValue()); // Affiche "2"
SortHand
La classe Player doit avoir une méthode SortHand qui trie la main du joueur par couleur et par valeur décroissante.
Vous devez utiliser la méthode GetCardsByColor et SortCardsWithSameColor pour trier les cartes par couleur et par valeur.
Vous devez ensuite reconstruire la main du joueur en concaténant les listes afin de créer un nouveau tableau.
public void SortHand() { }
Player player = new Player("Alice");
player.Hand = new Card[] { new BasicCard("7", ColorEnum.ColorRed), new SpecialCard("Reverse", ColorEnum.ColorBlue), new BasicCard("2", ColorEnum.ColorRed) };
player.SortHand();
Console.WriteLine(player.Hand[0].GetCardValue()); // Affiche "7"
Console.WriteLine(player.Hand[1].GetCardValue()); // Affiche "2"
Console.WriteLine(player.Hand[2].GetCardValue()); // Affiche "Reverse"
File: GameManager.cs
Propriétés
Ici, nous allons définir une classe GameManager qui représente une partie de Uno.
La classe GameManager doit avoir les propriétés suivantes :
- Une propriété publique
Playersde typeQueue<Player>qui représente les joueurs de la partie. - Une propriété publique
Deckde typeList<Card>qui représente le paquet de cartes de la partie. - Une propriété publique
DiscardPilede typeStack<Card>qui représente la pile de défausse de la partie.
Chacune des propriétés doit avoir un getter public et setter privé, à l'exception de Deck qui doit avoir un getter public et un setter public.
Constructeur
La classe GameManager doit avoir un constructeur qui initialise les propriétés Players, Deck et DiscardPile.
Les joueurs doivent être ajoutés à la file dans l'ordre de leur création.
Le paquet de cartes doit être initialisé vide.
La pile de défausse doit être vide à la création.
public GameManager() { }
GameManager game = new GameManager();
Console.WriteLine(game.Players.Count); // Affiche 0
Console.WriteLine(game.Deck.Count); // Affiche 0
Console.WriteLine(game.DiscardPile.Count); // Affiche 0
AddPlayer
La classe GameManager doit avoir une méthode AddPlayer qui ajoute un joueur à la partie.
public void AddPlayer(Player player) { }
GameManager game = new GameManager();
Player player = new Player("Alice");
Player player2 = new Player("Bob");
game.AddPlayer(player);
game.AddPlayer(player2);
Console.WriteLine(game.Players.Count); // Affiche 2
Console.WriteLine(game.Players.Peek().Name); // Affiche "Alice"
game.Players.Dequeue();
Console.WriteLine(game.Players.Peek().Name); // Affiche "Bob"
AddPlayers
La classe GameManager doit avoir une méthode AddPlayers qui ajoute plusieurs joueurs à la partie.
public void AddPlayers(Player[] players) { }
GameManager game = new GameManager();
Player player = new Player("Alice");
Player player2 = new Player("Bob");
game.AddPlayers(new Player[] { player, player2 });
Console.WriteLine(game.Players.Count); // Affiche 2
Console.WriteLine(game.Players.Peek().Name); // Affiche "Alice"
game.Players.Dequeue();
Console.WriteLine(game.Players.Peek().Name); // Affiche "Bob"
CreateDeck
La classe GameManager doit avoir une méthode CreateDeck qui initialise le paquet de cartes de la partie.
Le paquet de cartes doit contenir deux exemplaires de toutes les cartes de Uno (4 couleurs de 0 à 9, les cartes spéciales et des jokers avec une pénalité de 0, 4, 8 uniquement).
public void CreateDeck() { }
GameManager game = new GameManager();
game.CreateDeck();
Console.WriteLine(game.Deck.Count); // Affiche 110
Proficiencies
Lorsque vous utiliserez la capacité de vos cartes, vous devrez aussi vous assurez d'enfiler le Joueur actuel dans la file de joueurs.
File: Player.cs
DrawCard
La méthode DrawCard prend en paramètre le paquet de cartes. Elle ajoute une carte au joueur en prenant la première carte du paquet (à l'index 0).
N'oubliez pas de retirer la carte du paquet.
public void DrawCard(List<Card> deck) { }
Player player = new Player("Alice");
List<Card> deck = new List<Card> { new BasicCard("6", ColorEnum.ColorRed), new BasicCard("6", ColorEnum.ColorBlue), new BasicCard("6", ColorEnum.ColorGreen) };
player.DrawCard(deck);
// player should have 1 card in his hand -> 6 red
// deck should have 2 cards -> 6 blue, 6 green
UseCard
La méthode UseCard prend en paramètre la carte à jouer et la pile de cartes. Elle ajoute la carte à la pile puis retire la carte de la main du joueur.
public void UseCard(Card card, Stack<Card> stack) { }
Player player = new Player("Alice");
player.Hand = new Card[] { new BasicCard("6", ColorEnum.ColorRed), new BasicCard("6", ColorEnum.ColorBlue) };
Stack<Card> stack = new Stack<Card>();
player.UseCard(player.Hand[0], stack);
// player should have 1 card in his hand -> 6 blue
// stack should have 1 card -> 6 red
Play
La méthode Play prend en paramètre la pile de cartes, le paquet de cartes, la file de joueurs et la couleur actuelle. Elle regarde sa main de gauche à droite, s'il peut jouer une carte, il la joue. S'il ne peut pas jouer, il pioche une carte.
Il peut jouer uniquement si la couleur de la carte est identique à la couleur actuelle ou que le chiffre est le même que la carte du dessus de la pile ou que la carte est un Joker.
La méthode doit retourner un booléen indiquant si le joueur n'a plus de cartes en main.
public bool Play(Stack<Card> pile, List<Card> deck, Queue<Player> players, ColorEnum actualColor) { }
Player player = new Player("Alice");
player.Hand = new Card[] { new BasicCard("6", ColorEnum.ColorBlue) };
Stack<Card> pile = new Stack<Card>();
pile.Push(new BasicCard("6", ColorEnum.ColorRed));
List<Card> deck = new List<Card> { new BasicCard("6", ColorEnum.ColorBlue), new BasicCard("6", ColorEnum.ColorGreen) };
Queue<Player> players = new Queue<Player>( new List<Player> { new Player("Bob"), new Player("Charlie") } );
ColorEnum actualColor = ColorEnum.ColorRed;
bool res = player.Play(pile, deck, players, actualColor);
// players should be -> Alice, Charlie, Bob ->
// Alice should have played the card and the pile should have 2 cards
// Alice should have 0 cards in her hand
// the function should return true
File: Card/SpecialCard.cs
PickTwoCard
La méthode PickTwoCard prend en paramètre le joueur actuel, la file de joueurs et le paquet de cartes. Elle retire le prochain joueur de la file, lui fait piocher deux cartes, puis remet le joueur actuel puis le prochain joueur dans la file.
Il est important de noter que le joueur actuel doit être remis dans la file avant le prochain joueur.
public void PickTwoCard(Player actualPlayer, Queue<Player> players, List<Card> deck) { }
Player actualPlayer = new Player("Alice");
actualPlayer.Hand = new Card[] { new BasicCard("7", ColorEnum.ColorRed) };
Player nextPlayer = new Player("Bob");
nextPlayer.Hand = new Card[] { new BasicCard("0", ColorEnum.ColorYellow) };
Queue<Player> players = new Queue<Player>( new List<Player> { nextPlayer, new Player("Charlie") } );
List<Card> deck = new List<Card> { new BasicCard("6", ColorEnum.ColorRed), new BasicCard("6", ColorEnum.ColorBlue), new BasicCard("6", ColorEnum.ColorGreen) };
SpecialCard card = new SpecialCard("PickTwo", ColorEnum.ColorRed);
card.PickTwoCard(actualPlayer, players, deck);
// players should be -> Bob, Alice, Charlie ->
// Bob should have 3 cards in his hand -> 0 yellow, 6 red, 6 blue
SkipCard
La méthode SkipCard prend en paramètre le joueur actuel et la file de joueurs. Elle retire le prochain joueur de la file puis le remet dans la file.
Il est important de noter que le joueur actuel doit être remis dans la file avant le prochain joueur.
public void SkipCard(Player actualPlayer, Queue<Player> players) { }
Queue<Player> players = new Queue<Player>( new List<Player> { new Player("Alice"), new Player("Bob"), new Player("Charlie") } );
Player actualPlayer = players.Dequeue();
SpecialCard card = new SpecialCard("Skip", ColorEnum.ColorRed);
card.SkipCard(actualPlayer, players);
// players should be -> Bob, Alice, Charlie ->
Console.WriteLine();
ReverseCard
La méthode ReverseCard prend en paramètre le joueur actuel et la file de joueurs. Elle inverse l'ordre des joueurs dans la file.
Il est important de noter que le joueur actuel doit être remis dans la file après l'avoir renversée.
public void ReverseCard(Player actualPlayer, Queue<Player> players) { }
Queue<Player> players = new Queue<Player>( new List<Player> { new Player("Alice"), new Player("Bob"), new Player("Charlie") } );
Player actualPlayer = players.Dequeue();
SpecialCard card = new SpecialCard("Reverse", ColorEnum.ColorRed);
card.ReverseCard(actualPlayer, players);
// players was -> Charlie, Bob ->
// players is now -> Alice, Bob, Charlie ->
UseCapacity
La méthode UseCapacity prend en paramètre le joueur actuel, la file de joueurs et le paquet de cartes. Elle appelle la méthode correspondante à la capacité de la carte.
public void UseCapacity(Player actualPlayer, Queue<Player> players, List<Card> deck) { }
File: Card/JokerCard.cs
UseCapacity
La classe JokerCard est une carte spéciale qui permet de changer la couleur du jeu. Cependant ici nous ne gèreront pas le changement de couleur (qui se fera dans une autre fonction). Nous allons simplement faire piocher des cartes au joueur suivant en fonction du malus de la carte.
La méthode UseCapacity prend en paramètre le joueur actuel et la file de joueurs. Elle fait piocher des cartes au joueur suivant en fonction du malus de la carte.
La fonction remet ensuite le joueur actuel puis le joueur suivant dans la file.
Il est important de noter que le joueur actuel doit être remis dans la file avant le prochain joueur.
public void UseCapacity(Player actualPlayer, Queue<Player> players, List<Card> deck) { }
Queue<Player> players = new Queue<Player>( new List<Player> { new Player("Alice"), new Player("Bob"), new Player("Charlie") } );
List<Card> deck = new List<Card> { new BasicCard("6", ColorEnum.ColorRed), new BasicCard("6", ColorEnum.ColorBlue), new BasicCard("6", ColorEnum.ColorGreen) };
Player actualPlayer = players.Dequeue();
JokerCard jokerCard = new JokerCard(2);
jokerCard.UseCapacity(actualPlayer, players, deck);
// players should be -> Bob, Alice, Charlie ->
// Bob should have 2 cards in his hand -> 6 red, 6 blue
// deck should have 1 card -> 6 green
File: GameManager.cs
ShuffleDeck
La méthode ShuffleDeck mélange le paquet de cartes du joueur.
Vous devez pour cela créer un tableau à deux dimensions de cartes de 5 colonnes et avec le nombre de lignes le plus petit possible pour contenir toutes les cartes du paquet.
Vous devez ensuite parcourir le deck et placer chaque carte dans le tableau, en les remplacant colonne par colonne. (d'abord arr[0][0] puis arr[1][0] etc.)
Enfin, vous devez reconstruire le deck en parcourant le tableau (ligne par ligne) et en ajoutant chaque carte non nulle dans le deck.
public void ShuffleDeck() { }
GameManager game = new GameManager();
game.Deck = new List<Card>
{
new BasicCard("1", ColorEnum.ColorRed),
new BasicCard("2", ColorEnum.ColorBlue),
new BasicCard("3", ColorEnum.ColorGreen),
new BasicCard("4", ColorEnum.ColorYellow),
new BasicCard("5", ColorEnum.ColorRed),
new BasicCard("6", ColorEnum.ColorBlue),
new BasicCard("7", ColorEnum.ColorGreen),
new BasicCard("8", ColorEnum.ColorYellow),
new BasicCard("9", ColorEnum.ColorRed)
};
game.ShuffleDeck();
// deck should be:
// done later
// 1 ColorRed
// 3 ColorGreen
// 5 ColorRed
// 7 ColorGreen
// 9 ColorRed
// 2 ColorBlue
// 4 ColorYellow
// 6 ColorBlue
// 8 ColorYellow
CountPoints
La méthode CountPoints retourne un dictionnaire contenant les points de chaque joueur.
Chaque carte spéciale vaut 20 points, chaque carte normale vaut son chiffre et chaque Joker vaut 50 points.
public Dictionary<Player,int> CountPoints() { }
Player player1 = new Player("Alice");
player1.Hand = new Card[] { new BasicCard("6", ColorEnum.ColorRed), new BasicCard("6", ColorEnum.ColorBlue), new BasicCard("6", ColorEnum.ColorGreen) };
Player player2 = new Player("Bob");
player2.Hand = new Card[] { new SpecialCard("PickTwo", ColorEnum.ColorRed), new SpecialCard("Skip", ColorEnum.ColorBlue), new SpecialCard("Reverse", ColorEnum.ColorGreen) };
GameManager game = new GameManager();
game.AddPlayer(player1);
game.AddPlayer(player2);
Dictionary<Player,int> points = game.CountPoints();
Console.WriteLine(points[player1]); // 18
Console.WriteLine(points[player2]); // 60
DealCards
La méthode DealCards distribue 7 cartes à chaque joueur. Elle doit appeler la méthode DrawCard à chaque fois. Les cartes devront être disribuées comme dans la vraie vie. Par exemple si il y a 3 joueurs: 1-2-3-1-2-3-1-...
public void DealCards() { }
PlayGame
La méthode PlayGame est la méthode principale du jeu. Elle doit appeler les méthodes créées précédemment pour jouer une partie complète.
Voici les différentes étapes à suivre:
- Appeler la méthode
DealCards - Créer la pile de défausse
DiscardPileet y ajouter un 0 jaune (pour vous faciliter la tâche) - Créer une variable
currentColorqui contiendra la couleur actuelle - Entrer dans une boucle infinie
- Entrer dans une boucle tant que le paquet de cartes n'est pas vide
- Retirer le joueur actuel de la file
- Appeler la méthode
Playdu joueur actuel - Si le joueur n'a plus de cartes, appeler la méthode
CountPointset retourner le résultat - Changer la couleur actuelle en fonction de la carte du dessus de la pile. Si la carte est un Joker, utilisez alors la méthode
GetBestColordu joueur ayant utilisé la carte pour changer la couleur actuelle.
- Retirer la carte du dessus de la pile et remettre toutes les cartes de la pile dans le paquet
- Mélanger le paquet
- Entrer dans une boucle tant que le paquet de cartes n'est pas vide
public Dictionary<Player,int> PlayGame() { }