I'm a C# beginner and this is my try at making a command line Blackjack. I'm aware that the Dealer logic is still far from done, but I wanted to post my code for review.
I want to make the code as efficient as possible. Also, I want it to be readable, so that working with it after pauses is easier. I think it's quite readable already, but I know some of you can give me hints to make it better.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CliBlackjackV2
{
class Program
{
private static Random randomizer = new Random();
private static bool gameLoop = true;
private static bool cardDraw = true;
enum cardColor
{
Spades,
Hearths,
Clubs,
Diamonds,
};
enum cardFace
{
Ace,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Quen,
King,
};
static void Main(string[] args)
{
while (gameLoop)
{
game();
Console.Write("\n Play again? [Y/N]: ");
string choice = Console.ReadLine().ToLower();
switch (choice)
{
case "n":
gameLoop = false;
break;
default:
break;
}
}
}
static void game()
{
//isl is the shortform for integer string list
//since im treating the Faces as ints and the Collors as String (at least in my head)
List<KeyValuePair<cardFace, cardColor>> islPlayerHand = new List<KeyValuePair<cardFace, cardColor>>();
List<KeyValuePair<cardFace, cardColor>> islDealerHand = new List<KeyValuePair<cardFace, cardColor>>();
islPlayerHand = getCards(islPlayerHand);
islPlayerHand = getCards(islPlayerHand);
islDealerHand = getCards(islDealerHand);
islDealerHand = getCards(islDealerHand);
renderBoard(islPlayerHand, islDealerHand);
cardDraw = true;
while (cardDraw)
{
cardDraw = playerCardDraw(islPlayerHand);
renderBoard(islPlayerHand, islDealerHand);
checkHand("Player", islPlayerHand);
}
while (true)
{
int dealerTotal = calcHandTotal(islDealerHand);
while (dealerTotal < 16)
{
islDealerHand = getCards(islDealerHand);
renderBoard(islPlayerHand, islDealerHand);
checkHand("dealer", islDealerHand);
dealerTotal = calcHandTotal(islDealerHand);
}
if (dealerTotal >= 16)
{
break;
}
}
renderBoard(islPlayerHand, islDealerHand);
checkHand("Player", islPlayerHand);
checkHand("dealer", islDealerHand);
decideWinner(islPlayerHand, islDealerHand);
}
static void checkHand(string player, List<KeyValuePair<cardFace, cardColor>> hand)
{
int total = calcHandTotal(hand);
if (total == 21)
{
Console.WriteLine($"\n {player} got a Blackjack!\n");
cardDraw = false;
}
else if (total > 21)
{
Console.WriteLine($"\n {player} Busted!\n");
cardDraw = false;
}
}
static bool playerCardDraw(List<KeyValuePair<cardFace, cardColor>> playerHand)
{
bool cardDraw = true;
Console.Write(" Would you like to (H)it or to (S)tand: ");
string choice = Console.ReadLine().ToLower();
switch (choice)
{
case "h":
playerHand = getCards(playerHand);
break;
case "s":
cardDraw = false;
break;
default:
break;
}
return cardDraw;
}
static int calcHandTotal(List<KeyValuePair<cardFace, cardColor>> hand)
{
int handTotal = 0;
int aceCount = 0;
foreach (KeyValuePair<cardFace, cardColor> card in hand)
{
if ((int)card.Key >= 10)
{
handTotal += 10;
}
else if (card.Key == cardFace.Ace)
{
aceCount++;
}
else
{
handTotal += (int)card.Key + 1;
}
}
//calculating the ace's Values properly
if (aceCount > 0)
{
if (handTotal <= (11 - aceCount))
{
handTotal += (aceCount - 1) + 11;
}
else
{
handTotal += aceCount;
}
}
return handTotal;
}
static void decideWinner(List<KeyValuePair<cardFace, cardColor>> playerHand, List<KeyValuePair<cardFace, cardColor>> dealerHand)
{
int hand1Total=calcHandTotal(playerHand);
int hand2Total=calcHandTotal(dealerHand);
if ((hand1Total > 21) && (hand2Total > 21))
{
Console.WriteLine(" Both busted!");
}
else if (hand1Total > 21)
{
Console.WriteLine(" Dealer Wins!");
}
else if (hand2Total > 21)
{
Console.WriteLine(" Player Wins!");
}
else if (hand1Total > hand2Total)
{
Console.WriteLine(" Player Wins!");
}
else if (hand2Total > hand1Total)
{
Console.WriteLine(" Dealer Wins!");
}
else
{
Console.WriteLine(" It's a tie!");
}
}
static void renderBoard(List<KeyValuePair<cardFace, cardColor>> playerHand, List<KeyValuePair<cardFace, cardColor>> dealerHand)
{
Console.Clear();
Console.WriteLine("***********************\n" +
"* PlayerHand *\n" +
"***********************\n");
printCards(playerHand);
Console.WriteLine($" Total: {calcHandTotal(playerHand)}\n");
Console.WriteLine("***********************\n" +
"* DealerHand *\n" +
"***********************\n");
printCards(dealerHand);
Console.WriteLine($" Total: {calcHandTotal(dealerHand)}\n");
}
static void printCards(List<KeyValuePair<cardFace, cardColor>> hand)
{
int cardCount = 1;
foreach (var card in hand)
{
Console.WriteLine($" #{cardCount} {card.Key} of {card.Value}");
cardCount++;
}
Console.WriteLine("");
}
static List<KeyValuePair<cardFace, cardColor>> getCards(List<KeyValuePair<cardFace, cardColor>> hand)
{
hand.Add(new KeyValuePair<cardFace, cardColor>((cardFace)randomizer.Next(0, 12), (cardColor)randomizer.Next(0, 3)));
return hand;
}
}
}