From c7ed7df2b8b74f64f80be99c427b64e11910c9d8 Mon Sep 17 00:00:00 2001
From: bionic85 <144353436+bionic85@users.noreply.github.com>
Date: Wed, 18 Dec 2024 17:59:27 +0100
Subject: [PATCH] Blackjack is donee

---
 PuzzlePlayer/BlackJack.cs | 148 ++++++++++++++++++++++++--------------
 1 file changed, 93 insertions(+), 55 deletions(-)

diff --git a/PuzzlePlayer/BlackJack.cs b/PuzzlePlayer/BlackJack.cs
index 7c39545..d0235b7 100644
--- a/PuzzlePlayer/BlackJack.cs
+++ b/PuzzlePlayer/BlackJack.cs
@@ -48,7 +48,7 @@ namespace PuzzlePlayer_Namespace
         // visibility depends on game state
         Panel SetupPanel;
         Panel GamePanel;
-        Panel ResultPanel;
+        Button RestartButton;
 
         List<Card> cardsLeft;
         List<Card> playerCards = new();
@@ -65,15 +65,13 @@ namespace PuzzlePlayer_Namespace
 
             defaultFontSize = screen.Width / 50;
 
-            Paint += BlackJack_Paint;
-
             money = ReadMoney();
             cardsLeft = getAllCards();
 
             SetupUI();
         }
 
-        List<Card> getAllCards()
+        List<Card> getAllCards() // returns a list with all the 52 classic cards
         {
             List<Card> cards = new List<Card>();
             string[] numbers = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "ace", "jack", "king", "queen" };
@@ -86,10 +84,8 @@ namespace PuzzlePlayer_Namespace
                     int val;
                     if (num == "jack" || num == "king" || num == "queen")
                         val = 10;
-                    else if (num == "ace") // if it is an ace the player can chose between 1 or 11
-                    {
+                    else if (num == "ace") // an ace is worth either 1 or 11, the logic for this is handled in GetValue()
                         val = 11;
-                    }
                     else
                         val = int.Parse(num);
                     cards.Add(new Card(num + "_of_" + kind,val));
@@ -133,7 +129,7 @@ namespace PuzzlePlayer_Namespace
                     b.BackColor = chip.Item3;
                     b.Font = new Font(BJFont, b.Size.Width / 5);
 
-                    b.Click += moneyButtonClick;
+                    b.Click += MoneyButtonClick;
 
                     SetupPanel.Controls.Add(b);
                     goofyIndex++;
@@ -146,7 +142,7 @@ namespace PuzzlePlayer_Namespace
             dealButton.Location = new Point(SetupPanel.Width /2 - dealButton.Width/2, SetupPanel.Height /4);
             dealButton.Font = new Font(BJFont, dealButton.Size.Width / 5);
             dealButton.BackColor = Color.DodgerBlue;
-            dealButton.Click += dealButtonClick;
+            dealButton.Click += DealButtonClick;
             SetupPanel.Controls.Add(dealButton);
 
             Controls.Add(SetupPanel);
@@ -183,30 +179,28 @@ namespace PuzzlePlayer_Namespace
             StandButton.Text = "STAND";
             StandButton.Click += (object sender, EventArgs e) => EndGame();
             StandButton.BackColor = Color.Blue;
-            StandButton.Size = new Size(GamePanel.Width / 5, GamePanel.Height / 5);
-            StandButton.Location = new Point(GamePanel.Width - GamePanel.Width/4 - StandButton.Width/2, GamePanel.Height / 2 - StandButton.Size.Height / 2);
-            StandButton.Font = new Font(BJFont, StandButton.Size.Width / 6,FontStyle.Bold);
+            StandButton.Size = HitButton.Size;
+            StandButton.Location = new Point(GamePanel.Width - GamePanel.Width/4 - StandButton.Width/2, HitButton.Location.Y);
+            StandButton.Font = new Font(BJFont, StandButton.Width / 6,FontStyle.Bold);
 
             GamePanel.Controls.Add(StandButton);
 
+            RestartButton = new Button();
+            RestartButton.Text = "Next Round";
+            RestartButton.Click += RestartButtonClick;
+            RestartButton.BackColor = Color.DarkCyan;
+            RestartButton.Size = HitButton.Size;
+            RestartButton.Location = new Point(GamePanel.Width / 2 - RestartButton.Width / 2, HitButton.Location.Y);
+            RestartButton.Font = new Font(BJFont, RestartButton.Width / 6, FontStyle.Bold);
+            RestartButton.Hide(); // hide until game state is reached
+            GamePanel.Controls.Add(RestartButton);
+
             GamePanel.Hide(); //Hide until the game state is reached
             Controls.Add(GamePanel);
             #endregion
-
-            //result
-            #region ResultPanel
-            ResultPanel = new Panel();
-            ResultPanel.Hide(); //Hide until the result state is reached
-            ResultPanel.BackColor = Color.Transparent;
-            ResultPanel.Size = screen;
-
-            //ResultPanel.Paint += Result_Paint;
-
-            Controls.Add(ResultPanel);
-            #endregion
         }
         //button logic
-        private void moneyButtonClick(object sender, EventArgs e)
+        private void MoneyButtonClick(object sender, EventArgs e)
         {
             Button b = (Button) sender;
             (int, string, Color) chip = chipInfo[int.Parse(b.Name)];
@@ -219,7 +213,7 @@ namespace PuzzlePlayer_Namespace
             Invalidate(true);
         }
 
-        private void dealButtonClick(object sender, EventArgs e)
+        private void DealButtonClick(object sender, EventArgs e)
         {
             if (deployedMoney == 0)
                 return;
@@ -233,9 +227,26 @@ namespace PuzzlePlayer_Namespace
             GamePanel.Show();
             result = BJRESULTS.Won;
         }
+
+        private void RestartButtonClick(object sender, EventArgs e) //reset everything
+        {
+            result = BJRESULTS.Lost;
+            deployedMoney = 0;
+            roundFinished = false;
+            resultReady = false;
+
+            playerCards.Clear();
+            dealerCards.Clear();
+            RestartButton.Hide();
+
+            GamePanel.Hide();
+            SetupPanel.Show();
+        }
         // end of the game, fancy async methode
         private async void EndGame()
         {
+            if(roundFinished)
+                return; //only run it once
             roundFinished = true;
 
             // check for blackjack or bust (above 21 so player loses)
@@ -247,6 +258,21 @@ namespace PuzzlePlayer_Namespace
             else // if the player scored below 21 then the dealer must draw cards
                  await DealerAnimation(); // fancy Asynchronous animation function
 
+            switch (result)
+            {
+                case BJRESULTS.Lost:
+                    break;
+                case BJRESULTS.Won:
+                case BJRESULTS.Blackjack:
+                    money += deployedMoney * 2;
+                    break;
+                case BJRESULTS.Draw:
+                    money += deployedMoney;
+                    break;
+            }
+
+            RestartButton.Show();
+
             resultReady = true;
             Invalidate(true);
         }
@@ -266,10 +292,11 @@ namespace PuzzlePlayer_Namespace
                 int playerScore = getValue(playerCards);
                 int dealerScore = getValue(getVisableDealerCards());
 
-                // let the dealer hit until it has above 17 points (dealer will hit on soft 17 type shit)
+                // the dealer must hit until it has 17 or more points
+                // if the dealer has 17 points and a ace in hand then the dealer must also hit (dealer will hit on soft 17 type shit)
                 // also if the dealer has a higher score then the player then the dealer won, so no need to push the luck and draw more cards
                 // if the dealer has the same score then it is a draw and the dealer will not draw more cards
-                while (dealerScore <= 17 && dealerScore < playerScore)
+                while ((dealerScore < 17 && dealerScore < playerScore) || DealerHasSoft17())
                 {
                     dealerCards.Add((PopCard(), true));
                     dealerScore = getValue(getVisableDealerCards()); // update dealer score
@@ -291,18 +318,24 @@ namespace PuzzlePlayer_Namespace
             });
         }
 
-        // paint events for all the different states
-        private void BlackJack_Paint(object sender, PaintEventArgs e) //this will always get drawn
+        private bool DealerHasSoft17()  // fancy blackjack rule
         {
-            Graphics g = e.Graphics;
+            List<Card> cards = getVisableDealerCards();
+            if (getValue(cards) != 17)
+                return false;
+            foreach (Card card in cards)
+            {
+                if(card.value == 11) // check if the dealer has a ace
+                    return true;
+            }
 
-            Font moneyFont = new Font(BJFont, defaultFontSize, FontStyle.Bold);
-            //g.DrawString("Money: $" + money.ToString(), moneyFont, Brushes.Black, new PointF(0,0));
+            return false;
         }
+
+        // paint events for all the different states
         private void Setup_Paint(object sender, PaintEventArgs e)
         {
             Graphics g = e.Graphics;
-
             DrawMoney(g);
 
             // draw deployd money
@@ -355,17 +388,14 @@ namespace PuzzlePlayer_Namespace
             g.DrawString(dealerString, f, Brushes.Black, dealerStrPos);
 
             //draw deployed money
-            string deployedString = $"${deployedMoney}";
+            string deployedString = $"Playing for ${deployedMoney}";
             SizeF deployedSF = g.MeasureString(deployedString, f);
             PointF deployedStrPos = new PointF(GamePanel.Width/2 - deployedSF.Width / 2,GamePanel.Height/2 - deployedSF.Height/2);
             g.DrawString(deployedString,f, Brushes.Black, deployedStrPos);
 
-
             // draw result text when ready
             if (resultReady)
                 Result_Paint(g);
-            
-
         }
 
         private void DrawMoney(Graphics g)
@@ -377,42 +407,49 @@ namespace PuzzlePlayer_Namespace
         private void Result_Paint(Graphics g)
         {
             string resultText = "";
-            Font f = new Font(BJFont, screen.Width / 10,FontStyle.Bold);
+            string moneyText = "";
+            Color c = Color.Red;
+            Font resFont = new Font(BJFont, screen.Width / 10,FontStyle.Bold);
+            Font moneyFont = new Font(BJFont, screen.Width / 20, FontStyle.Underline);
 
             switch (result)
             {
                 case BJRESULTS.Lost:
                     resultText = "YOU LOSE";
+                    moneyText = $"You lost -${deployedMoney}";
                     break;
                 case BJRESULTS.Won:
                     resultText = "YOU WINNN";
+                    moneyText = $"You won ${deployedMoney * 2}";
+                    c = Color.LimeGreen;
                     break;
                 case BJRESULTS.Blackjack:
                     resultText = "!BLACKJACK!";
+                    moneyText = $"You won ${deployedMoney * 2}";
+                    c = Color.Gold;
                     break;
                 case BJRESULTS.Draw:
-                    resultText = "draw";
+                    resultText = "Draw";
+                    moneyText = $"You got your ${deployedMoney} back";
+                    c = Color.Gray;
                     break;
             }
 
-            SizeF size = g.MeasureString(resultText, f);
-            Point pos = new Point(GamePanel.Width / 2 - (int)(size.Width / 2), GamePanel.Height / 4 - (int)(size.Height / 2));
+            SizeF resSize = g.MeasureString(resultText, resFont);
+            Point resPos = new Point(GamePanel.Width / 2 - (int)(resSize.Width / 2), GamePanel.Height / 5 - (int)(resSize.Height / 2));
+            SizeF moneySize = g.MeasureString (moneyText, moneyFont);
+            Point moneyPos = new Point(GamePanel.Width / 2 - (int)(moneySize.Width / 2), GamePanel.Height / 3 - (int)(moneySize.Height /2));
 
+            //crazy outline
             GraphicsPath p = new GraphicsPath();
-            p.AddString(
-                resultText,             // text to draw
-                BJFont,  // or any other font family
-                (int)FontStyle.Bold,      // font style (bold, italic, etc.)
-                g.DpiY * screen.Width / 10 / 72,       // em size
-                pos,              // location where to draw text
-                new StringFormat());          // set options here (e.g. center alignment)
-            Pen pen = new Pen(Color.Black, screen.Width / 50);
-            
+            p.AddString(resultText, BJFont, (int)FontStyle.Bold, g.DpiY * screen.Width / 10 / 72, resPos, new StringFormat());
+            Pen pen = new Pen(Color.Black, screen.Width / 60);
             g.DrawPath(pen, p);
 
-
-            
-            g.DrawString(resultText,f,Brushes.Red, pos);
+            //actual text
+            SolidBrush brush = new SolidBrush(c);
+            g.DrawString(resultText,resFont,brush, resPos);
+            g.DrawString(moneyText,moneyFont,brush, moneyPos);
         }
         // some draw thingies
         private void DrawChip(Graphics g, Color c, int r, Point pos, string value)
@@ -445,7 +482,8 @@ namespace PuzzlePlayer_Namespace
             Image img = SettingForm.GetEmbeddedImage("BlackJack.cards." + cardName + ".png");
             g.DrawImage(img, pos.X, pos.Y, width, (float)(width * cardMultply)); //img is 500x726
         }
-        // interact with the cards methodes
+        
+        // methodes for interacting with the cards 
         private Card PopCard()
         {
             if (cardsLeft.Count == 0)
-- 
GitLab