From a44022e03c1177830ced3f7f0cf043c985cf7d0a Mon Sep 17 00:00:00 2001 From: bionic85 <144353436+bionic85@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:16:27 +0100 Subject: [PATCH] Almost finished blackjack --- PuzzlePlayer/BlackJack.cs | 183 +++++++++++++++++++++++++++++++------- 1 file changed, 153 insertions(+), 30 deletions(-) diff --git a/PuzzlePlayer/BlackJack.cs b/PuzzlePlayer/BlackJack.cs index 36cd126..7c39545 100644 --- a/PuzzlePlayer/BlackJack.cs +++ b/PuzzlePlayer/BlackJack.cs @@ -1,15 +1,20 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; +using System.Drawing.Drawing2D; +using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; namespace PuzzlePlayer_Namespace { - enum BJSTATE // the different states the game can be in + enum BJRESULTS // the different results after a round { - Setup, // choose how much money the player deploys - Game, // play the game - Result, // see te result and then restart + Lost, + Won, + Blackjack, // player scored 21 points + Draw // same score } struct Card @@ -26,7 +31,9 @@ namespace PuzzlePlayer_Namespace internal class BlackJack : Form { - BJSTATE state; + BJRESULTS result; + bool roundFinished = false; + bool resultReady = false; int money; int deployedMoney = 0; readonly FontFamily BJFont = FontFamily.GenericSansSerif; @@ -51,7 +58,7 @@ namespace PuzzlePlayer_Namespace public BlackJack() { - state = BJSTATE.Setup; + result = BJRESULTS.Lost; //init WindowState = FormWindowState.Maximized; DoubleBuffered = true; BackColor = Color.DarkGreen; @@ -100,23 +107,25 @@ namespace PuzzlePlayer_Namespace private void SetupUI() { - //Setup + //setup #region SetupPanel SetupPanel = new Panel(); - SetupPanel.Size = new Size(screen.Width/2,screen.Height); - SetupPanel.Location = new Point(screen.Width / 4, 0); + SetupPanel.Size = screen; //SetupPanel.Size = new Size(screen.Width/2,screen.Height); + SetupPanel.Location = new Point(0, 0); //SetupPanel.Location = new Point(screen.Width / 4, 0); //DefaultPanel.BackColor = Color.Blue; //DEBUG SetupPanel.Paint += Setup_Paint; //money buttons int goofyIndex = 0; //dw - for(int j = 1; j <= 2; j++) - for(int i = 0; i < 4; i++) + const int rows = 4; + const int cols = 2; + for(int j = 1; j <= cols; j++) + for(int i = 0; i < rows; i++) { Button b = new Button(); - b.Size = new Size(SetupPanel.Width / 4, SetupPanel.Height / 6); // /2 - b.Location = new Point(i * b.Size.Width, SetupPanel.Height - b.Size.Height*j); + b.Size = new Size(SetupPanel.Width / 8, SetupPanel.Height / 6); // w/8 + b.Location = new Point(i * b.Size.Width + rows / 2 * b.Size.Width, SetupPanel.Height - b.Size.Height * j); b.Name = goofyIndex.ToString(); // for getting the index for chipInfo later (int, string, Color) chip = chipInfo[goofyIndex]; @@ -143,12 +152,12 @@ namespace PuzzlePlayer_Namespace Controls.Add(SetupPanel); #endregion - //Game + //game #region GamePanel GamePanel = new Panel(); GamePanel.Paint += Game_Paint; - GamePanel.Size = new Size((int)(screen.Width / 1.5), screen.Height); - GamePanel.Location = new Point((screen.Width - GamePanel.Size.Width)/2, 0); + GamePanel.Size = screen; //GamePanel.Size = new Size((int)(screen.Width / 1.5), screen.Height); + GamePanel.Location = new Point(0, 0); //GamePanel.Location = new Point((screen.Width - GamePanel.Size.Width)/2, 0); //GamePanel.BackColor = Color.Red; //DEBUG //buttons @@ -156,22 +165,26 @@ namespace PuzzlePlayer_Namespace HitButton.Text = "HIT"; HitButton.Click += (object sender, EventArgs e) => { + if (roundFinished) // don't let the player draw cards when the round is already finished + return; playerCards.Add(PopCard()); Invalidate(true); + if (getValue(playerCards) >= BLACKJACK) //if it is a bust or blackjack the game is automaticly over + EndGame(); }; HitButton.BackColor = Color.Red; HitButton.Size = new Size(GamePanel.Width/5, GamePanel.Height/5); - HitButton.Location = new Point(0, GamePanel.Height / 2 - HitButton.Size.Height / 2); + HitButton.Location = new Point(GamePanel.Width/4 - HitButton.Width/2, GamePanel.Height / 2 - HitButton.Size.Height / 2); HitButton.Font = new Font(BJFont, HitButton.Size.Width/3, FontStyle.Bold); GamePanel.Controls.Add(HitButton); - + // stand button Button StandButton = new Button(); StandButton.Text = "STAND"; - StandButton.Click += standButtonClick; + 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-StandButton.Width, GamePanel.Height / 2 - StandButton.Size.Height / 2); + 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); GamePanel.Controls.Add(StandButton); @@ -180,14 +193,19 @@ namespace PuzzlePlayer_Namespace Controls.Add(GamePanel); #endregion - //Result + //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) { Button b = (Button) sender; @@ -213,29 +231,84 @@ namespace PuzzlePlayer_Namespace dealerCards.Add((PopCard(), true)); //visable card GamePanel.Show(); - state = BJSTATE.Game; + result = BJRESULTS.Won; + } + // end of the game, fancy async methode + private async void EndGame() + { + roundFinished = true; + + // check for blackjack or bust (above 21 so player loses) + int playerScore = getValue(playerCards); + if (playerScore == BLACKJACK) + result = BJRESULTS.Blackjack; + else if (playerScore > BLACKJACK) + result = BJRESULTS.Lost; + else // if the player scored below 21 then the dealer must draw cards + await DealerAnimation(); // fancy Asynchronous animation function + + resultReady = true; + Invalidate(true); } - private void standButtonClick(object sender, EventArgs e) + private Task DealerAnimation() { + return Task.Factory.StartNew(() => + { + + Thread.Sleep(200); //wait 0.2 sec for the fun + for (int i = 0; i < dealerCards.Count; i++) // flip all the cards that where invisable + if (!dealerCards[i].Item2) + dealerCards[i] = (dealerCards[i].Item1, true); + Invalidate(true); + + Thread.Sleep(1000); // just a little more + 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) + // 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) + { + dealerCards.Add((PopCard(), true)); + dealerScore = getValue(getVisableDealerCards()); // update dealer score + Invalidate(true); + Thread.Sleep(1000); + } + Thread.Sleep(500); + + if (dealerScore > BLACKJACK) // dealer bust + result = BJRESULTS.Won; + else if (dealerScore > playerScore) // dealer has higher score then player + result = BJRESULTS.Lost; + else if (dealerScore == playerScore) + result = BJRESULTS.Draw; + else + result = BJRESULTS.Won; + + }); } + // paint events for all the different states private void BlackJack_Paint(object sender, PaintEventArgs e) //this will always get drawn { Graphics g = e.Graphics; Font moneyFont = new Font(BJFont, defaultFontSize, FontStyle.Bold); - g.DrawString("Money: $" + money.ToString(), moneyFont, Brushes.Black, new PointF(0,0)); + //g.DrawString("Money: $" + money.ToString(), moneyFont, Brushes.Black, new PointF(0,0)); } private void Setup_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; + DrawMoney(g); + // draw deployd money // Might update this to butiful chipss TODO - string s = "Deployd Money: $" + deployedMoney.ToString(); - Font deplMoneyFont = new Font(BJFont, SetupPanel.Width / 20, FontStyle.Bold); + string s = "Deployed Money: $" + deployedMoney.ToString(); + Font deplMoneyFont = new Font(BJFont, SetupPanel.Width / 40, FontStyle.Bold); SizeF pf = g.MeasureString(s, deplMoneyFont); PointF p = new PointF(SetupPanel.Width / 2 - pf.Width / 2, SetupPanel.Height / 2); g.DrawString(s, deplMoneyFont, Brushes.Black, p); @@ -244,7 +317,9 @@ namespace PuzzlePlayer_Namespace private void Game_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; - int cardWidth = 250; + DrawMoney(g); + + int cardWidth = screen.Width/8; //lucky number int cardHeight = (int)(cardWidth * cardMultply); // draw cards for player and dealer for(int i = 0; i < playerCards.Count; i++) @@ -285,13 +360,61 @@ namespace PuzzlePlayer_Namespace 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) + { + Font moneyFont = new Font(BJFont, defaultFontSize, FontStyle.Bold); + g.DrawString("Money: $" + money.ToString(), moneyFont, Brushes.Black, new PointF(0, 0)); } private void Result_Paint(Graphics g) { + string resultText = ""; + Font f = new Font(BJFont, screen.Width / 10,FontStyle.Bold); - } + switch (result) + { + case BJRESULTS.Lost: + resultText = "YOU LOSE"; + break; + case BJRESULTS.Won: + resultText = "YOU WINNN"; + break; + case BJRESULTS.Blackjack: + resultText = "!BLACKJACK!"; + break; + case BJRESULTS.Draw: + resultText = "draw"; + 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)); + + 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); + + g.DrawPath(pen, p); + + + g.DrawString(resultText,f,Brushes.Red, pos); + } + // some draw thingies private void DrawChip(Graphics g, Color c, int r, Point pos, string value) { // Chip @@ -322,7 +445,7 @@ 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 private Card PopCard() { if (cardsLeft.Count == 0) -- GitLab