card_game_vector
Table des matières
Le but de cet exercice est, dans un premier temps, de manipuler les vecteurs de la STL. Puis, vous utiliserez le framework GoogleTest pour faire les tests unitaires.
1 Partie 1 : Manipulation des vecteurs
Nous supposons qu'il y a une partie de coinche en cours entre deux joueurs : vous et l'ordinateur. L'idée est de savoir, pour une configuration donnée (c'est-à-dire une carte jouée par votre adversaire et les cartes de votre main), si vous allez prendre le pli ou pas. Pour ceux qui ne connaissent pas du tout la coinche, commencez par lire la section 1.4.
1.1 Règles
Les règles de notre jeu de coinche simplifié sont les suivantes:
- Vous disposez d'un jeu de 32 cartes.
- Vous prenez 8 cartes et l'adversaire pose une carte. Vous ne vous souciez pas du jeu de l'adversaire. En d'autres termes, cette carte est sélectionnée aléatoirement parmi les 24 cartes restantes.
- L'atout est choisi au hasard.
- Si vous avez au moins une carte de la même couleur :
- Si vous avez plusieurs cartes de valeurs supérieures, vous mettez la plus proche de la valeur de la carte posée et vous gagnez le pli.
- Sinon vous mettez la carte la plus petite (il en va de même si la carte posée est un atout) et vous perdez le pli.
- Si vous n'avez pas de carte de la même couleur et que vous avez des atouts, vous mettez le plus petit atout et vous gagnez le pli.
- Sinon vous mettez la carte la plus petite d'une autre couleur (si, par exemple, vous avez deux mêmes cartes de deux couleurs différentes (disons des septs), on suppose, par souci de simplicité, que coeur < carreau < pique < trefle. Dans ce cas vous perdez le pli.
Le but n'est pas de savoir qui gagne la partie. L'idée est de partir d'une configuration de base, c'est-à-dire une carte jouée et 8 cartes dans votre main et de savoir qui prend le pli. Ce qui signifie qu'il y aura un seul tour (et donc que vous ne jouerez pas vos 8 cartes).
1.2 Etapes
Les étapes du jeu sont les suivantes :
- Construire le jeu de carte
- Mélanger le jeu
- Tirer les huit premières cartes
- Choisir un atout au hasard et mettre à jour les valeurs des cartes (14 pour le 9 et 20 pour le valet).
- Tirer la 9e carte (parmi les 24 qui restent) qui sera jouée par l'adversaire.
- Jouer une carte en respectant les règles décrite ci-dessus.
- Afficher le gagnant de la manche.
1.3 Détails d'implémentation
Commencez par créer un projet Console que vous appellerez Coinche. Un fichier Coinche.h
vous est fourni ici. Vous pouvez l'étendre, mais pas modifier les prototypes des fonctions. Pour information, afin d'ajouter un fichier Coinche.h
à votre projet Coinche, il suffit de faire un clic droit sur le projet Coinche (au niveau de l'explorateur de solution) -> add -> new item -> header file et donnez Coinche.h en nom. Copier les prototypes de fonctions et ce que vous jugez nécessaires dans ce fichier
Afin de représenter le jeu de cartes, vous utiliserez un vecteur. Chaque case du vecteur est une carte représentée par une structure. La structure est composée de :
- La couleur de la carte représentée par un enum (coeur, carreau, pique, trefle)
- La force de la carte représentée par un enum ("sept", "huit", …", "dame", "roi", "as")
- Une valeur représentant le nombre de points (0, 0, …, 3, 4, 11). Notez que les points du 9 et du valet doivent être mis à jour si leur couleur est celle de l'atout.
1.4 Règle complète de la coinche (pour ceux qui n'y ont jamais joué)
Règle de la coinche (l'explication pour 2 joueurs seulement) :
- 32 cartes, 8 cartes dans une main.
- Les valeurs des cartes sont : 7, 8, 9 -> 0, 10 -> 10, Valet -> 2, Dame -> 3, Roi -> 4, As -> 11.
- Même si 7, 8 et 9 valent 0, si une personne pose un 7 et une personne pose un 8 (de la même couleur) le 8 gagne.
- Pour chaque partie, il y a une couleur d'atout. Le 9 et le Valet ont des valeurs différences dans ce cas (14 pour le 9 et 20 pour le valet). L'atout peut se jouer comme n'importe quelle autre carte. De plus, c'est une carte qu'on peut jouer lorsqu'on n'a pas une carte de la même couleur que la carte jouée et permet de prendre la main. Notez que si un atout est posé, le 2e joueur est obligé de mettre un atout d'une valeur supérieure lorsqu'il en a un.
- Supposons que le joueur A pose une carte :
- Si le joueur B pose une carte de la même couleur, et qu'elle a une valeur supérieure, il prend le pli
- Sinon il perd le pli
- Si le joueur B n'a pas de carte de la même couleur, et qu'il a un atout, il pose son atout, et prend le pli.
- Si le jouer B n'a ni atout, ni carte de la même couleur, il joue une carte d'une autre couleur et perd le pli.
2 Partie 2 : Utilisation de GoogleTest
Dans cette section, nous allons mettre en oeuvre des tests unitaires.
2.1 Installation de l'environnement de tests unitaires
- Décompressez l'archive SampleGoogleTest.zip dans le répertoire de votre
choix (par exemple, dans
C:\users\votre_login\CSC4526
). - Exploitez le canevas de projet obtenu selon la procédure
cmake
de ce document. - Exécutez le test unitaire présent dans le canevas en exécutant la procédure Google Test de ce document.
- Avant que vous n'écriviez vos propres tests unitaires, voyons comment tout cet environnement a été mis en place.
2.2 Présentation de l'environnement mis en place par cmake
Cette section décrit l'environnement mis en place par cmake
:
CoincheAvecGoogleTest\CMakeLists.txt
- déclare les 3 répertoires
src
,unitTests
etmainLauncher
dont nous nous servirons pour le codage de l'exercice.
- déclare les 3 répertoires
- Le répertoire
src
contient tous les sources (.h
et.cpp
) de notre application.CoincheAvecGoogleTest\src\CMakeLists.txt
permet d'indiquer que nous utiliserons tous ces sources (définition et initialisation de la variableSOURCES
par l'instruction(GLOB... CONFIGURE_DEPENDS...)
et son utilisation dans l'instructionadd_library()
) pour générer la bibliothèque statiquesrc
(instructionadd_library()
). L'inclusion des fichiers sources par d'autres projets est rendue possible par l'(instructiontarget_include_directories
). Le répertoiresrc
ne contient pas de fichier codant la fonction C++main()
, mais un fichiermyMain.h
contenant la déclaration de la fonctionmyMain()
et un fichiermyMain.cpp
contenant sa définition.
// Fichier myMain.h #pragma once int monMain();
// Fichier myMain.cpp #include "monMain.h" int monMain() { // Inserer ici le code a appeler par myMain(). NB : rien a faire pour le present exercice. return 0; }
- Le répertoire
unitTests
contient les tests unitaires. Dans ce répertoire, vous n'aurez besoin que de modifierunitTests.cpp
. Après avoir été téléchargé GoogleTest,CoincheAvecGoogleTest\unitTests\CMakeLists.txt
définit cet environnement de tests avec les instructionssadd_executable()
etadd_test()
. De plus, il indique que l'exécutableunitTests
est contruit à l'aide des bibliothèquesgtest
,gtest_main
etsrc
(cf. les deux instructionstarget_link_libraries()
). Notez que :- Ces instructions
target_link_libraries()
permettent également d'indiquer à cmake qu'il doit générer les directives pour que le compilateur puisse retrouver les fichier d'include degoogletest
etsrc
. - La bibliothèqe
gtest_main
contient une fonctionmain()
. C'est pourquoi nous avons sorti la fonctionmain()
des fichiers sources desrc
. Ainsi, au moment de l'édition de liens entre les bibliothèques de googletest et la bibliothèquesrc
, nous avons bien une seule fonctionmain()
.
- Ces instructions
- Le répertoire
mainLauncher
contient le fichiermainLauncher.cpp
. Ce fichier définit une fonctionmain()
qui est chargé d'appeler la fonctionmyMain()
. Grâce à l'instructionadd_executable
,CoincheAvecGoogleTest\unitTests\CMakeLists.txt
spécifie la génération de l'exécutablemainLauncher
en utilisant la bibliothèquesrc
(cf. instructiontarget_link_libraries
),src
contenant la définition de la fonctionmyMain()
.
// Fichier mainLauncher.cpp #include "myMain.h" int main() { return myMain(); }
- L'exécution de la commande
cmake
dans le répertoirebuild
permet de configurer les différents projets Visual Studio de votre application en configurant correctement les chemins d'accès aux répertoires d'include et aux bibliothèques utilisés.
2.3 Création de tests
Créez Coinche.h
et Coinche.cpp
dans le répertoire src
. Recopiez
dans ces fichiers le contenu des fichiers de votre projet Coinche initial.
Dans Coinche.cpp
, renommez main()
en myMain()
.
Dans l'explorateur de solutions, cliquez droit sur mainLauncher
,
puis sélectionnez "Définir comme projet par défaut". Ensuite, exécutez
votre application et vérifier qu'elle fonctionn comme précédemment.
Mettez à jour le fichier unitTests\unitTests.cpp
avec quelques
tests, comme par exemple : exemple de test est présenté ci-dessous
/* Test : la valeur du 9 d'atout est 14*/ TEST(TestAtout, TestUpdate9Atout) { card played; std::vector<card> jeu(1); std::vector<card> deck(0); Couleur atout = pique; jeu[0].force = neuf; jeu[0].value = 0; jeu[0].couleur = pique; update_values(atout, deck, jeu); EXPECT_EQ(14, jeu[0].value); }