Prototype de blackjack C#
J'aimerais avoir des commentaires sur mon code, je suis nouveau dans le codage avec C # mais j'ai quelques connaissances sur Lua et Python. Y a-t-il quelque chose que je dois changer/nettoyer pour le rendre plus simple ?
using System;
using System.Linq;
class MainClass {
public static void Main () {
int[] cards = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};
Console.WriteLine("Welcome to Blackjack. Here are your draws.");
Random drawCard = new Random();
int draw1 = drawCard.Next(cards.Min(), cards.Max());
int draw2 = drawCard.Next(cards.Min(), cards.Max());
Console.WriteLine("You recieved a " + draw1 + " card!");
Console.WriteLine("You recieved a " + draw2 + " card!");
int sum1 = draw1 + draw2;
if (sum1 == 21) //Blackjack Ending
{
Console.WriteLine("Congratulations! You got " + sum1 + "!");
}
else if (sum1 >= 11) //Choice of 3rd draw
{
Console.WriteLine("Is " + sum1 + " enough?");
bool cont1 = false;
drawChoice(cont1); //Call the draw choice function
if (cont1 == true)
{
int draw3 = drawCard.Next(cards.Min(), cards.Max());
Console.WriteLine("You drawed a " + draw3 + " card!");
int sum2 = draw3 + sum1;
Console.WriteLine("You have a total of " + sum2 + ".");
if (sum2 > 21) Console.WriteLine("Game Over!");
}
else //NPC's turn starts
{
}
}
else //Player has less than 11 cards, auto draw
{
Console.WriteLine("You have a total of " + sum1 + ".");
Console.WriteLine("You will be forced to draw another card.");
int draw3 = drawCard.Next(cards.Min(), cards.Max());
Console.WriteLine("You drawed a " + draw3 + " card!");
int sum2 = draw3 + sum1;
Console.WriteLine("You have a total of " + sum2 + ".");
}
}
static void drawChoice(bool contChoice) //Function for player to choose whether to draw
{
Console.WriteLine("Would you like to draw another card? Y/N");
string choice1 = Console.ReadLine();
if (choice1 == "Y" || choice1 == "y")
{
contChoice = true;
Console.WriteLine(contChoice);
}
else if (choice1 == "N" || choice1 == "n")
{
contChoice = false;
Console.WriteLine(contChoice);
}
}
}
Réponses
J'ai fait un projet similaire moi-même, c'est vraiment très amusant !
1. Garder une trace des scores
La première chose que j'ai remarquée, c'est que vous gardez une trace de la somme des valeurs pour le joueur et probablement aussi pour le croupier, mais le score d'une main peut en fait changer considérablement pendant la lecture.
1.1. Totaux souples au blackjack
Le blackjack a ce concept appelé soft totaux, ce qui signifie que la somme totale peut avoir une valeur différente selon qu'il y a un as ou non. Par exemple, si un joueur a un as (1) et un 7, cela compte en fait comme 18 (11 + 7). Mais si ce même joueur tire un autre 7, son total sera de 15 (1 + 7 + 7). La valeur de l'as change au fur et à mesure que vous tirez plus de cartes, vous aurez donc plus de facilité à conserver les scores si vous gardez les cartes séparées les unes des autres. Cela peut être fait en utilisant des collections.
1.2. Collections
Les collections sont des choses comme des tableaux (que vous avez déjà utilisés), des listes et des dictionnaires. Une liste d'entiers est un bon candidat pour représenter la collection actuelle de cartes d'un joueur (ou du croupier), car ils peuvent changer de taille sans se plaindre. De plus, les listes ont des fonctions intégrées pour obtenir la somme de tous les nombres qu'elles contiennent, les valeurs minimales et maximales de la liste et bien plus encore. Vous pouvez utiliser ces fonctions intégrées à votre avantage, ainsi que le fait que vous connaissez toujours les nombres à l'intérieur de la liste pour déterminer si le total de quelqu'un est doux ou non.
2. Boucle de jeu
Le jeu de blackjack se joue avec un nombre fini de cartes dans la vraie vie, mais bien sûr, dans le code, vous n'avez pas à vous en soucier. Si un joueur (mal)chanceux continue de piocher des as, il finira toujours par toucher 21 et terminera le tour. Cependant, puisque vous ne pouvez pas prédire quand un joueur (ou le croupier) va perdre, vous pouvez utiliser ce qu'on appelle une boucle de jeu. La boucle de jeu pour le blackjack commence à exécuter toute la logique du jeu une fois qu'un joueur ou le croupier confirme qu'il veut tirer une carte, et une fois l'exécution terminée, il demandera de répéter si nécessaire.
2.1. Conditions pour choisir une autre carte
Vous remarquerez que le joueur a beaucoup de liberté au blackjack, il peut continuer à tirer des cartes jusqu'à ce qu'il obtienne 21 ou qu'il dépasse, moment auquel le tour se termine pour lui. Le concessionnaire, cependant, n'a pas cette liberté. Vous pouvez trouver plus d'informations à ce sujet en ligne.
Quoi qu'il en soit, si vous y réfléchissez, le joueur et le croupier prennent à un moment donné la décision de piocher ou de ne pas piocher une autre carte. Vous faites une vérification pour "Y"
ou "N"
lorsqu'on vous donne une entrée, ce qui est logique.
2.2. Traduction de la saisie de texte vers true
oufalse
Votre DrawChoice
méthode modifie a en bool
fonction de l'entrée du joueur, mais vous pouvez également refactoriser cette méthode afin qu'elle reçoive a string
et renvoie un bool
. De cette façon, vous pouvez directement traduire l'entrée de l'utilisateur en true
(oui, donnez-moi une autre carte) ou false
(non, je ne veux pas d'autre carte). Cela pourrait ressembler à ceci :
// One option
public static bool DrawChoice(string input)
{
if (input == "Y" || input == "y") // You could also use input.ToLower() == "y"
{
return true;
}
else // If it's not "Y" or "y", it's gonna be "N" or "n"
{
return false;
}
// else if (input == "N" || input == "n")
// {
// return false;
// }
}
// Alternative one-liner
public static bool DrawChoice2(string input) => input.ToLower() == "y";
Pour en revenir à l'idée d'une boucle de jeu, vous avez maintenant une condition qui dicte si la boucle de jeu continue ou non. Une implémentation possible serait celle-ci :
string choice = Console.ReadLine();
while (DrawChoice(choice)) // No need to write "== true" or "== false"
{
// Stuff that happens if a player or the dealer draws another card
choice = Console.ReadLine() // Ask again once the game logic has executed
}
// Stuff that happens when the loop ends
2.3. Cartes à dessiner
Le blackjack est un jeu de cartes, vous tirerez donc beaucoup de cartes, que ce soit pour un joueur ou pour le croupier. Si quelque chose arrive souvent dans le jeu, c'est généralement une bonne idée d'en faire une méthode pour ne pas avoir à écrire la même logique à différents endroits.
Votre implémentation actuelle tire une valeur aléatoire entre le minimum et le maximum de votre tableau de cartes. De la documentation, nous apprenons ce qui suit :
Next(Int32 minValue, Int32 maxValue)
Un entier signé 32 bits supérieur ou égal à
minValue
et inférieur àmaxValue
; c'est-à-dire que la plage de valeurs de retour inclutminValue
mais pasmaxValue
. SiminValue
égalmaxValue
à ,minValue
est renvoyé.
Ainsi, lorsque vous écrivez Next(1, 10)
(de min à max), vous obtiendrez au plus un 9. Un autre problème est que même si vous réglez l'implémentation sur Next(1, 11)
, vous aurez des probabilités égales d'obtenir n'importe quelle valeur de 1 à 10. Mais comme il y a plusieurs cartes dans le jeu qui ont la valeur de 10, elles devraient apparaître plus souvent que les cartes non-10.
Heureusement, votre tableau a déjà la bonne distribution de cartes, vous pouvez donc à la place générer une position aléatoire valide pour obtenir la valeur correspondante de votre tableau.
À la fin de la journée, ce que vous obtiendrez ressemblera à ceci :
public static int DrawCard()
{
int[] cards = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 };
int card;
// Implement random draw here
return card;
}
Et puis vous pourriez même faire quelque chose comme ça pour piocher des cartes à plusieurs reprises :
// You could also use a list, which is more flexible
public static int[] DrawCard(int count)
{
int[] drawn = new int[count];
for (int i = 0; i < count; i++)
{
drawn[i] = DrawCard();
}
return drawn;
}
J'espère que cela t'aides! Bonne chance et amusez-vous bien!
Quelques notes pour améliorer votre code :
int sum1 = draw1 + draw2; if (sum1 == 21) //Blackjack Ending { Console.WriteLine("Congratulations! You got " + sum1 + "!"); }
Ce ne sera jamais vrai, car
- vous n'avez nulle part dans les cartes un as signifiant avoir une valeur possible de onze.
- le
maxValue
in Random.Next(int minValue, int maxValue)est la borne supérieure exclusive du nombre aléatoire renvoyé.
Dans void drawChoice(bool contChoice)
l'argument de la méthode contChoice
est un type valeur. Vous ne pouvez pas le modifier comme vous le pensez. Après avoir quitté la méthode, que l'utilisateur ait tapé y ou n, la valeur de cont1
est toujours false
. Vous devez modifier la signature de la méthode pour qu'elle n'ait pas d'arguments mais qu'elle renvoie un bool
.
if (cont1 == true)
car cont1
est déjà un booléen, vous n'aurez pas besoin de le comparer avec un booléen. Vous pouvez simplement l'utiliser comme condition if (cont1)
et si vous auriez besoin de vérifier si une variable bool est false
que vous utiliseriez if (!cont1)
.
Je ne sais pas à quel point je peux être utile ici, mais à mon humble avis, vous devez avoir une révision complète du code avec quelqu'un qui vous parle à travers le code. Il y a un tas de "faux" ici, mais cela dit, je me demande quel est votre objectif avec C # - êtes-vous en train de rédiger un script rapide pour apprendre la syntaxe, ou voulez-vous mieux comprendre comment concevoir des choses en C #.
Si quelqu'un venait me voir avec ça dans un cadre professionnel, la première chose que je lui dirais : "Vous devez pouvoir tester ça". Je parlerais alors de TDD, et j'essaierais vraiment de montrer comment ce code est structuré pour en faire beaucoup trop. Il n'y a pas d'abstractions et tout est très procédural. Chaque classe doit faire 1 chose. Les gens, j'en suis sûr, discuteront avec moi sur ce point. Quoi qu'il en soit, le fait que vous n'ayez qu'une seule classe est mauvais.
Passé cela, pour juste des "conseils rapides de 2 minutes en C#". J'utiliserais des énumérations pour les cartes donc au lieu de 10, 10, 10, j'aurais 10, Jack, Queen, Ace. Utilisez var à la place. if (cont1 == true)
est le même que if(cont1)
. Utilisez des variables mieux nommées : en regardant simplement cont1, je n'ai aucune idée de ce que cela signifie.
JansthcirlU a également monté des collections. En regardant ce code, il ne semble pas que vous les compreniez, donc je me concentrerais vraiment ici aussi.
Continuez à coder :)