12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664 |
- #region File Description
- //-----------------------------------------------------------------------------
- // BlackjackGame.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using System;
- using System.Collections.Generic;
- using System.Text;
- using CardsFramework;
- using Microsoft.Xna.Framework;
- using System.Threading;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Graphics;
- using GameStateManagement;
- using System.Reflection;
- #endregion
- namespace Blackjack
- {
- /// <summary>
- /// The various possible game states.
- /// </summary>
- public enum BlackjackGameState
- {
- Shuffling,
- Betting,
- Playing,
- Dealing,
- RoundEnd,
- GameOver,
- }
- class BlackjackCardGame : CardsGame
- {
- #region Fields and Properties
- Dictionary<Player, string> playerHandValueTexts =
- new Dictionary<Player, string>();
- Dictionary<Player, string> playerSecondHandValueTexts =
- new Dictionary<Player, string>();
- private Hand deadCards = new Hand(); // stores used cards
- private BlackjackPlayer dealerPlayer;
- bool[] turnFinishedByPlayer;
- TimeSpan dealDuration = TimeSpan.FromMilliseconds(500);
- AnimatedHandGameComponent[] animatedHands;
- // An additional list for managing hands created when performing a split.
- AnimatedHandGameComponent[] animatedSecondHands;
- BetGameComponent betGameComponent;
- AnimatedHandGameComponent dealerHandComponent;
- Dictionary<string, Button> buttons = new Dictionary<string, Button>();
- Button newGame;
- bool showInsurance;
- // An offset used for drawing the second hand which appears after a split in
- // the correct location.
- Vector2 secondHandOffset =
- new Vector2(100 * BlackjackGame.WidthScale, 25 * BlackjackGame.HeightScale);
- static Vector2 ringOffset = new Vector2(0, 110);
- #if WINDOWS_PHONE || IOS || ANDROID
- Vector2 frameSize = new Vector2(162, 162);
- #else
- Vector2 frameSize = new Vector2(180, 180);
- #endif
- public BlackjackGameState State { get; set; }
- ScreenManager screenManager;
- const int maxPlayers = 3;
- const int minPlayers = 1;
- #endregion
- #region Initializations
- /// <summary>
- /// Creates a new instance of the <see cref="BlackjackCardGame"/> class.
- /// </summary>
- /// <param name="tableBounds">The table bounds. These serves as the bounds for
- /// the game's main area.</param>
- /// <param name="dealerPosition">Position for the dealer's deck.</param>
- /// <param name="placeOrder">A method that translate a player index into the
- /// position of his deck on the game table.</param>
- /// <param name="screenManager">The games <see cref="ScreenManager"/>.</param>
- /// <param name="theme">The game's deck theme name.</param>
- public BlackjackCardGame(Rectangle tableBounds, Vector2 dealerPosition,
- Func<int, Vector2> placeOrder, ScreenManager screenManager, string theme)
- : base(6, 0, CardSuit.AllSuits, CardsFramework.CardValue.NonJokers,
- minPlayers, maxPlayers, new BlackJackTable(ringOffset, tableBounds,
- dealerPosition, maxPlayers, placeOrder, theme, screenManager.Game),
- theme, screenManager.Game)
- {
- dealerPlayer = new BlackjackPlayer("Dealer", this);
- turnFinishedByPlayer = new bool[MaximumPlayers];
- this.screenManager = screenManager;
- if (animatedHands == null)
- {
- animatedHands = new AnimatedHandGameComponent[maxPlayers];
- }
- if (animatedSecondHands == null)
- {
- animatedSecondHands = new AnimatedHandGameComponent[maxPlayers];
- }
- }
- /// <summary>
- /// Performs necessary initializations.
- /// </summary>
- public void Initialize()
- {
- base.LoadContent();
- // Initialize a new bet component
- betGameComponent =
- new BetGameComponent(players, screenManager.input, Theme, this);
- Game.Components.Add(betGameComponent);
- // Initialize the game buttons
- string[] buttonsText = { "Hit", "Stand", "Double", "Split", "Insurance" };
- for (int buttonIndex = 0; buttonIndex < buttonsText.Length; buttonIndex++)
- {
- Button button = new Button("ButtonRegular", "ButtonPressed",
- screenManager.input, this)
- {
- Text = buttonsText[buttonIndex],
- Bounds = new Rectangle(screenManager.SafeArea.Left + 10 + buttonIndex * 110,
- screenManager.SafeArea.Bottom - 60,
- 100, 50),
- Font = this.Font,
- Visible = false,
- Enabled = false
- };
- buttons.Add(buttonsText[buttonIndex], button);
- Game.Components.Add(button);
- }
- newGame = new Button("ButtonRegular", "ButtonPressed",
- screenManager.input, this)
- {
- Text = "New Hand",
- Bounds = new Rectangle(screenManager.SafeArea.Left + 10,
- screenManager.SafeArea.Bottom - 60, 200, 50),
- Font = this.Font,
- Visible = false,
- Enabled = false
- };
- // Alter the insurance button's bounds as it is considerably larger than
- // the other buttons
- Rectangle insuranceBounds = buttons["Insurance"].Bounds;
- insuranceBounds.Width = 200;
- buttons["Insurance"].Bounds = insuranceBounds;
- newGame.Click += newGame_Click;
- Game.Components.Add(newGame);
- // Register to click event
- buttons["Hit"].Click += Hit_Click;
- buttons["Stand"].Click += Stand_Click;
- buttons["Double"].Click += Double_Click;
- buttons["Split"].Click += Split_Click;
- buttons["Insurance"].Click += Insurance_Click;
- }
- #endregion
- #region Update and Render
- /// <summary>
- /// Perform the game's update logic.
- /// </summary>
- /// <param name="gameTime">Time elapsed since the last call to
- /// this method.</param>
- public void Update(GameTime gameTime)
- {
- switch (State)
- {
- case BlackjackGameState.Shuffling:
- {
- ShowShuffleAnimation();
- } break;
- case BlackjackGameState.Betting:
- {
- EnableButtons(false);
- } break;
- case BlackjackGameState.Dealing:
- {
- // Deal 2 cards and start playing
- State = BlackjackGameState.Playing;
- Deal();
- StartPlaying();
- } break;
- case BlackjackGameState.Playing:
- {
- // Calculate players' current hand values
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- ((BlackjackPlayer)players[playerIndex]).CalculateValues();
- }
- dealerPlayer.CalculateValues();
- // Make sure no animations are running
- if (!CheckForRunningAnimations<AnimatedCardsGameComponent>())
- {
- BlackjackPlayer player =
- (BlackjackPlayer)GetCurrentPlayer();
- // If the current player is an AI player, make it play
- if (player is BlackjackAIPlayer)
- {
- ((BlackjackAIPlayer)player).AIPlay();
- }
- CheckRules();
- // If all players have finished playing, the
- // current round ends
- if (State == BlackjackGameState.Playing &&
- GetCurrentPlayer() == null)
- {
- EndRound();
- }
- // Update button availability according to player options
- SetButtonAvailability();
- }
- else
- EnableButtons(false);
- } break;
- case BlackjackGameState.RoundEnd:
- {
- if (dealerHandComponent.EstimatedTimeForAnimationsCompletion() == TimeSpan.Zero)
- {
- betGameComponent.CalculateBalance(dealerPlayer);
- // Check if there is enough money to play
- // then show new game option or tell the player he has lost
- if (((BlackjackPlayer)players[0]).Balance < 5)
- {
- EndGame();
- }
- else
- {
- newGame.Enabled = true;
- newGame.Visible = true;
- }
- }
- } break;
- case BlackjackGameState.GameOver:
- {
- } break;
- default: break;
- }
- }
- /// <summary>
- /// Shows the card shuffling animation.
- /// </summary>
- private void ShowShuffleAnimation()
- {
- // Add shuffling animation
- AnimatedGameComponent animationComponent = new AnimatedGameComponent(this.Game)
- {
- CurrentPosition = GameTable.DealerPosition,
- Visible = false
- };
- Game.Components.Add(animationComponent);
- animationComponent.AddAnimation(
- new FramesetGameComponentAnimation(cardsAssets["shuffle_" + Theme], 32, 11, frameSize)
- {
- Duration = TimeSpan.FromSeconds(1.5f),
- PerformBeforeStart = ShowComponent,
- PerformBeforSartArgs = animationComponent,
- PerformWhenDone = PlayShuffleAndRemoveComponent,
- PerformWhenDoneArgs = animationComponent
- });
- State = BlackjackGameState.Betting;
- }
- /// <summary>
- /// Helper method to show component
- /// </summary>
- /// <param name="obj"></param>
- void ShowComponent(object obj)
- {
- ((AnimatedGameComponent)obj).Visible = true;
- }
- /// <summary>
- /// Helper method to play shuffle sound and remove component
- /// </summary>
- /// <param name="obj"></param>
- void PlayShuffleAndRemoveComponent(object obj)
- {
- AudioManager.PlaySound("Shuffle");
- Game.Components.Remove((AnimatedGameComponent)obj);
- }
- /// <summary>
- /// Renders the visual elements for which the game itself is responsible.
- /// </summary>
- /// <param name="gameTime">Time passed since the last call to
- /// this method.</param>
- public void Draw(GameTime gameTime)
- {
- SpriteBatch.Begin();
- switch (State)
- {
- case BlackjackGameState.Playing:
- {
- ShowPlayerValues();
- } break;
- case BlackjackGameState.GameOver:
- {
- } break;
- case BlackjackGameState.RoundEnd:
- {
- if (dealerHandComponent.EstimatedTimeForAnimationsCompletion() == TimeSpan.Zero)
- {
- ShowDealerValue();
- }
- ShowPlayerValues();
- } break;
- default: break;
- }
- SpriteBatch.End();
- }
- /// <summary>
- /// Draws the dealer's hand value on the screen.
- /// </summary>
- private void ShowDealerValue()
- {
- // Calculate the value to display
- string dealerValue = dealerPlayer.FirstValue.ToString();
- if (dealerPlayer.FirstValueConsiderAce)
- {
- if (dealerPlayer.FirstValue + 10 == 21)
- {
- dealerValue = "21";
- }
- else
- {
- dealerValue += @"\" + (dealerPlayer.FirstValue + 10).ToString();
- }
- }
- // Draw the value
- Vector2 measure = Font.MeasureString(dealerValue);
- Vector2 position = GameTable.DealerPosition - new Vector2(measure.X + 20, 0);
- SpriteBatch.Draw(screenManager.BlankTexture,
- new Rectangle((int)position.X - 4, (int)position.Y,
- (int)measure.X + 8, (int)measure.Y), Color.Black);
- SpriteBatch.DrawString(Font, dealerValue,
- position, Color.White);
- }
- /// <summary>
- /// Draws the players' hand value on the screen.
- /// </summary>
- private void ShowPlayerValues()
- {
- Color color = Color.Black;
- Player currentPlayer = GetCurrentPlayer();
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- BlackjackPlayer player = (BlackjackPlayer)players[playerIndex];
- // The current player's hand value will be red to serve as a visual
- // prompt for who the active player is
- if (player == currentPlayer)
- {
- color = Color.Red;
- }
- else
- {
- color = Color.White;
- }
- // Calculate the values to draw
- string playerHandValueText;
- string playerSecondHandValueText = null;
- if (!animatedHands[playerIndex].IsAnimating)
- {
- if (player.FirstValue > 0)
- {
- playerHandValueText = player.FirstValue.ToString();
- // Take the fact that an ace is wither 1 or 11 into
- // consideration when calculating the value to display
- // Since the ace already counts as 1, we add 10 to get
- // the alternate value
- if (player.FirstValueConsiderAce)
- {
- if (player.FirstValue + 10 == 21)
- {
- playerHandValueText = "21";
- }
- else
- {
- playerHandValueText += @"\" +
- (player.FirstValue + 10).ToString();
- }
- }
- playerHandValueTexts[player] = playerHandValueText;
- }
- else
- {
- playerHandValueText = null;
- }
- if (player.IsSplit)
- {
- // If the player has performed a split, he has an additional
- // hand with its own value
- if (player.SecondValue > 0)
- {
- playerSecondHandValueText = player.SecondValue.ToString();
- if (player.SecondValueConsiderAce)
- {
- if (player.SecondValue + 10 == 21)
- {
- playerSecondHandValueText = "21";
- }
- else
- {
- playerSecondHandValueText +=
- @"\" + (player.SecondValue + 10).ToString();
- }
- }
- playerSecondHandValueTexts[player] =
- playerSecondHandValueText;
- }
- else
- {
- playerSecondHandValueText = null;
- }
- }
- }
- else
- {
- playerHandValueTexts.TryGetValue(player, out playerHandValueText);
- playerSecondHandValueTexts.TryGetValue(
- player, out playerSecondHandValueText);
- }
- if (player.IsSplit)
- {
- // If the player has performed a split, mark the active hand alone
- // with a red value
- color = player.CurrentHandType == HandTypes.First &&
- player == currentPlayer ? Color.Red : Color.White;
- if (playerHandValueText != null)
- {
- DrawValue(animatedHands[playerIndex], playerIndex, playerHandValueText, color);
- }
- color = player.CurrentHandType == HandTypes.Second &&
- player == currentPlayer ? Color.Red : Color.White;
- if (playerSecondHandValueText != null)
- {
- DrawValue(animatedSecondHands[playerIndex], playerIndex, playerSecondHandValueText,
- color);
- }
- }
- else
- {
- // If there is a value to draw, draw it
- if (playerHandValueText != null)
- {
- DrawValue(animatedHands[playerIndex], playerIndex, playerHandValueText, color);
- }
- }
- }
- }
- /// <summary>
- /// Draws the value of a player's hand above his top card.
- /// The value will be drawn over a black background.
- /// </summary>
- /// <param name="animatedHand">The player's hand.</param>
- /// <param name="place">A number representing the player's position on the
- /// game table.</param>
- /// <param name="value">The value to draw.</param>
- /// <param name="valueColor">The color in which to draw the value.</param>
- private void DrawValue(AnimatedHandGameComponent animatedHand, int place,
- string value, Color valueColor)
- {
- Hand hand = animatedHand.Hand;
- Vector2 position = GameTable.PlaceOrder(place) +
- animatedHand.GetCardRelativePosition(hand.Count - 1);
- Vector2 measure = Font.MeasureString(value);
- position.X += (cardsAssets["CardBack_" + Theme].Bounds.Width - measure.X) / 2;
- position.Y -= measure.Y + 5;
- SpriteBatch.Draw(screenManager.BlankTexture,
- new Rectangle((int)position.X - 4, (int)position.Y,
- (int)measure.X + 8, (int)measure.Y), Color.Black);
- SpriteBatch.DrawString(Font, value, position, valueColor);
- }
- #endregion
- #region Override Methods
- /// <summary>
- /// Adds a player to the game.
- /// </summary>
- /// <param name="player">The player to add.</param>
- public override void AddPlayer(Player player)
- {
- if (player is BlackjackPlayer && players.Count < MaximumPlayers)
- {
- players.Add(player);
- }
- }
- /// <summary>
- /// Gets the active player.
- /// </summary>
- /// <returns>The first payer who has placed a bet and has not
- /// finish playing.</returns>
- public override Player GetCurrentPlayer()
- {
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- if (((BlackjackPlayer)players[playerIndex]).MadeBet && turnFinishedByPlayer[playerIndex] == false)
- {
- return players[playerIndex];
- }
- }
- return null;
- }
- /// <summary>
- /// Calculate the value of a blackjack card.
- /// </summary>
- /// <param name="card">The card to calculate the value for.</param>
- /// <returns>The card's value. All card values are equal to their face number,
- /// except for jack/queen/king which value at 10.</returns>
- /// <remarks>An ace's value will be 1. Game logic will treat it as 11 where
- /// appropriate.</remarks>
- public override int CardValue(TraditionalCard card)
- {
- return Math.Min(base.CardValue(card), 10);
- }
- /// <summary>
- /// Deals 2 cards to each player including the dealer and adds the appropriate
- /// animations.
- /// </summary>
- public override void Deal()
- {
- if (State == BlackjackGameState.Playing)
- {
- TraditionalCard card;
- for (int dealIndex = 0; dealIndex < 2; dealIndex++)
- {
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- if (((BlackjackPlayer)players[playerIndex]).MadeBet)
- {
- // Deal a card to one of the players
- card = dealer.DealCardToHand(players[playerIndex].Hand);
- AddDealAnimation(card, animatedHands[playerIndex], true, dealDuration,
- DateTime.Now + TimeSpan.FromSeconds(
- dealDuration.TotalSeconds * (dealIndex * players.Count + playerIndex)));
- }
- }
- // Deal a card to the dealer
- card = dealer.DealCardToHand(dealerPlayer.Hand);
- AddDealAnimation(card, dealerHandComponent, dealIndex == 0, dealDuration, DateTime.Now);
- }
- }
- }
- /// <summary>
- /// Performs necessary initializations needed after dealing the cards in order
- /// to start playing.
- /// </summary>
- public override void StartPlaying()
- {
- // Check that there are enough players to start playing
- if ((MinimumPlayers <= players.Count && players.Count <= MaximumPlayers))
- {
- // Set up and register to gameplay events
- GameRule gameRule = new BustRule(players);
- rules.Add(gameRule);
- gameRule.RuleMatch += BustGameRule;
- gameRule = new BlackJackRule(players);
- rules.Add(gameRule);
- gameRule.RuleMatch += BlackJackGameRule;
- gameRule = new InsuranceRule(dealerPlayer.Hand);
- rules.Add(gameRule);
- gameRule.RuleMatch += InsuranceGameRule;
- // Display the hands participating in the game
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- if (((BlackjackPlayer)players[playerIndex]).MadeBet)
- {
- animatedHands[playerIndex].Visible = false;
- }
- else
- {
- animatedHands[playerIndex].Visible = true;
- }
- }
- }
- }
- #endregion
- #region Helper Methods
- /// <summary>
- /// Display an animation when a card is dealt.
- /// </summary>
- /// <param name="card">The card being dealt.</param>
- /// <param name="animatedHand">The animated hand into which the card
- /// is dealt.</param>
- /// <param name="flipCard">Should the card be flipped after dealing it.</param>
- /// <param name="duration">The animations desired duration.</param>
- /// <param name="startTime">The time at which the animation should
- /// start.</param>
- public void AddDealAnimation(TraditionalCard card, AnimatedHandGameComponent
- animatedHand, bool flipCard, TimeSpan duration, DateTime startTime)
- {
- // Get the card location and card component
- int cardLocationInHand = animatedHand.GetCardLocationInHand(card);
- AnimatedCardsGameComponent cardComponent = animatedHand.GetCardGameComponent(cardLocationInHand);
- // Add the transition animation
- cardComponent.AddAnimation(
- new TransitionGameComponentAnimation(GameTable.DealerPosition,
- animatedHand.CurrentPosition +
- animatedHand.GetCardRelativePosition(cardLocationInHand))
- {
- StartTime = startTime,
- PerformBeforeStart = ShowComponent,
- PerformBeforSartArgs = cardComponent,
- PerformWhenDone = PlayDealSound
- });
- if (flipCard)
- {
- // Add the flip animation
- cardComponent.AddAnimation(new FlipGameComponentAnimation
- {
- IsFromFaceDownToFaceUp = true,
- Duration = duration,
- StartTime = startTime + duration,
- PerformWhenDone = PlayFlipSound
- });
- }
- }
- /// <summary>
- /// Helper method to play deal sound
- /// </summary>
- /// <param name="obj"></param>
- void PlayDealSound(object obj)
- {
- AudioManager.PlaySound("Deal");
- }
- /// <summary>
- /// Helper method to play flip sound
- /// </summary>
- /// <param name="obj"></param>
- void PlayFlipSound(object obj)
- {
- AudioManager.PlaySound("Flip");
- }
- /// <summary>
- /// Adds an animation which displays an asset over a player's hand. The asset
- /// will appear above the hand and appear to "fall" on top of it.
- /// </summary>
- /// <param name="player">The player over the hand of which to place the
- /// animation.</param>
- /// <param name="assetName">Name of the asset to display above the hand.</param>
- /// <param name="animationHand">Which hand to put cue over.</param>
- /// <param name="waitForHand">Start the cue animation when the animation
- /// of this hand over null of the animation of the currentHand</param>
- void CueOverPlayerHand(BlackjackPlayer player, string assetName,
- HandTypes animationHand, AnimatedHandGameComponent waitForHand)
- {
- // Get the position of the relevant hand
- int playerIndex = players.IndexOf(player);
- AnimatedHandGameComponent currentAnimatedHand;
- Vector2 currentPosition;
- if (playerIndex >= 0)
- {
- switch (animationHand)
- {
- case HandTypes.First:
- currentAnimatedHand = animatedHands[playerIndex];
- currentPosition = currentAnimatedHand.CurrentPosition;
- break;
- case HandTypes.Second:
- currentAnimatedHand = animatedSecondHands[playerIndex];
- currentPosition = currentAnimatedHand.CurrentPosition +
- secondHandOffset;
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- }
- else
- {
- currentAnimatedHand = dealerHandComponent;
- currentPosition = currentAnimatedHand.CurrentPosition;
- }
- // Add the animation component
- AnimatedGameComponent animationComponent =
- new AnimatedGameComponent(this, cardsAssets[assetName])
- {
- CurrentPosition = currentPosition,
- Visible = false
- };
- Game.Components.Add(animationComponent);
- // Calculate when to start the animation. The animation will only begin
- // after all hand cards finish animating
- TimeSpan estimatedTimeToCompleteAnimations;
- if (waitForHand != null)
- {
- estimatedTimeToCompleteAnimations = waitForHand.EstimatedTimeForAnimationsCompletion();
- }
- else
- {
- estimatedTimeToCompleteAnimations = currentAnimatedHand.EstimatedTimeForAnimationsCompletion();
- }
- // Add a scale effect animation
- animationComponent.AddAnimation(new ScaleGameComponentAnimation(2.0f, 1.0f)
- {
- StartTime =
- DateTime.Now + estimatedTimeToCompleteAnimations,
- Duration = TimeSpan.FromSeconds(1f),
- PerformBeforeStart = ShowComponent,
- PerformBeforSartArgs = animationComponent
- });
- }
- /// <summary>
- /// Ends the current round.
- /// </summary>
- private void EndRound()
- {
- RevealDealerFirstCard();
- DealerAI();
- ShowResults();
- State = BlackjackGameState.RoundEnd;
- }
- /// <summary>
- /// Causes the dealer's hand to be displayed.
- /// </summary>
- private void ShowDealerHand()
- {
- dealerHandComponent =
- new BlackjackAnimatedDealerHandComponent(-1, dealerPlayer.Hand, this);
- Game.Components.Add(dealerHandComponent);
- }
- /// <summary>
- /// Reveal's the dealer's hidden card.
- /// </summary>
- private void RevealDealerFirstCard()
- {
- // Iterate over all dealer cards expect for the last
- AnimatedCardsGameComponent cardComponent = dealerHandComponent.GetCardGameComponent(1);
- cardComponent.AddAnimation(new FlipGameComponentAnimation()
- {
- Duration = TimeSpan.FromSeconds(0.5),
- StartTime = DateTime.Now
- });
- }
- /// <summary>
- /// Present visual indication as to how the players fared in the current round.
- /// </summary>
- private void ShowResults()
- {
- // Calculate the dealer's hand value
- int dealerValue = dealerPlayer.FirstValue;
- if (dealerPlayer.FirstValueConsiderAce)
- {
- dealerValue += 10;
- }
- // Show each player's result
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- ShowResultForPlayer((BlackjackPlayer)players[playerIndex], dealerValue, HandTypes.First);
- if (((BlackjackPlayer)players[playerIndex]).IsSplit)
- {
- ShowResultForPlayer((BlackjackPlayer)players[playerIndex], dealerValue, HandTypes.Second);
- }
- }
- }
- /// <summary>
- /// Display's a player's status after the turn has ended.
- /// </summary>
- /// <param name="player">The player for which to display the status.</param>
- /// <param name="dealerValue">The dealer's hand value.</param>
- /// <param name="currentHandType">The player's hand to take into
- /// account.</param>
- private void ShowResultForPlayer(BlackjackPlayer player, int dealerValue,
- HandTypes currentHandType)
- {
- // Calculate the player's hand value and check his state (blackjack/bust)
- bool blackjack, bust;
- int playerValue;
- switch (currentHandType)
- {
- case HandTypes.First:
- blackjack = player.BlackJack;
- bust = player.Bust;
- playerValue = player.FirstValue;
- if (player.FirstValueConsiderAce)
- {
- playerValue += 10;
- }
- break;
- case HandTypes.Second:
- blackjack = player.SecondBlackJack;
- bust = player.SecondBust;
- playerValue = player.SecondValue;
- if (player.SecondValueConsiderAce)
- {
- playerValue += 10;
- }
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- // The bust or blackjack state are animated independently of this method,
- // so only trigger different outcome indications
- if (player.MadeBet &&
- (!blackjack || (dealerPlayer.BlackJack && blackjack)) && !bust)
- {
- string assetName = GetResultAsset(player, dealerValue, playerValue);
- CueOverPlayerHand(player, assetName, currentHandType, dealerHandComponent);
- }
- }
- /// <summary>
- /// Return the asset name according to the result.
- /// </summary>
- /// <param name="player">The player for which to return the asset name.</param>
- /// <param name="dealerValue">The dealer's hand value.</param>
- /// <param name="playerValue">The player's hand value.</param>
- /// <returns>The asset name</returns>
- private string GetResultAsset(BlackjackPlayer player, int dealerValue, int playerValue)
- {
- string assetName;
- if (dealerPlayer.Bust)
- {
- assetName = "win";
- }
- else if (dealerPlayer.BlackJack)
- {
- if (player.BlackJack)
- {
- assetName = "push";
- }
- else
- {
- assetName = "lose";
- }
- }
- else if (playerValue < dealerValue)
- {
- assetName = "lose";
- }
- else if (playerValue > dealerValue)
- {
- assetName = "win";
- }
- else
- {
- assetName = "push";
- }
- return assetName;
- }
- /// <summary>
- /// Have the dealer play. The dealer hits until reaching 17+ and then
- /// stands.
- /// </summary>
- private void DealerAI()
- {
- // The dealer may have not need to draw additional cards after his first
- // two. Check if this is the case and if so end the dealer's play.
- dealerPlayer.CalculateValues();
- int dealerValue = dealerPlayer.FirstValue;
- if (dealerPlayer.FirstValueConsiderAce)
- {
- dealerValue += 10;
- }
- if (dealerValue > 21)
- {
- dealerPlayer.Bust = true;
- CueOverPlayerHand(dealerPlayer, "bust", HandTypes.First, dealerHandComponent);
- }
- else if (dealerValue == 21)
- {
- dealerPlayer.BlackJack = true;
- CueOverPlayerHand(dealerPlayer, "blackjack", HandTypes.First, dealerHandComponent);
- }
- if (dealerPlayer.BlackJack || dealerPlayer.Bust)
- {
- return;
- }
- // Draw cards until 17 is reached, or the dealer gets a blackjack or busts
- int cardsDealed = 0;
- while (dealerValue <= 17)
- {
- TraditionalCard card = dealer.DealCardToHand(dealerPlayer.Hand);
- AddDealAnimation(card, dealerHandComponent, true, dealDuration,
- DateTime.Now.AddMilliseconds(1000 * (cardsDealed + 1)));
- cardsDealed++;
- dealerPlayer.CalculateValues();
- dealerValue = dealerPlayer.FirstValue;
- if (dealerPlayer.FirstValueConsiderAce)
- {
- dealerValue += 10;
- }
- if (dealerValue > 21)
- {
- dealerPlayer.Bust = true;
- CueOverPlayerHand(dealerPlayer, "bust", HandTypes.First, dealerHandComponent);
- }
- }
- }
- /// <summary>
- /// Displays the hands currently in play.
- /// </summary>
- private void DisplayPlayingHands()
- {
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- AnimatedHandGameComponent animatedHandGameComponent =
- new BlackjackAnimatedPlayerHandComponent(playerIndex, players[playerIndex].Hand, this);
- Game.Components.Add(animatedHandGameComponent);
- animatedHands[playerIndex] = animatedHandGameComponent;
- }
- ShowDealerHand();
- }
- /// <summary>
- /// Starts a new game round.
- /// </summary>
- public void StartRound()
- {
- playerHandValueTexts.Clear();
- AudioManager.PlaySound("Shuffle");
- dealer.Shuffle();
- DisplayPlayingHands();
- State = BlackjackGameState.Shuffling;
- }
- /// <summary>
- /// Sets the button availability according to the options available to the
- /// current player.
- /// </summary>
- private void SetButtonAvailability()
- {
- BlackjackPlayer player = (BlackjackPlayer)GetCurrentPlayer();
- // Hide all buttons if no player is in play or the player is an AI player
- if (player == null || player is BlackjackAIPlayer)
- {
- EnableButtons(false);
- ChangeButtonsVisiblility(false);
- return;
- }
- // Show all buttons
- EnableButtons(true);
- ChangeButtonsVisiblility(true);
- // Set insurance button availability
- buttons["Insurance"].Visible = showInsurance;
- buttons["Insurance"].Enabled = showInsurance;
- if (player.IsSplit == false)
- {
- // Remember that the bet amount was already reduced from the balance,
- // so we only need to check if the player has more money than the
- // current bet when trying to double/split
- // Set double button availability
- if (player.BetAmount > player.Balance || player.Hand.Count != 2)
- {
- buttons["Double"].Visible = false;
- buttons["Double"].Enabled = false;
- }
- if (player.Hand.Count != 2 ||
- player.Hand[0].Value != player.Hand[1].Value ||
- player.BetAmount > player.Balance)
- {
- buttons["Split"].Visible = false;
- buttons["Split"].Enabled = false;
- }
- }
- else
- {
- // We've performed a split. Get the initial bet amount to check whether
- // or not we can double the current bet.
- float initialBet = player.BetAmount /
- ((player.Double ? 2f : 1f) + (player.SecondDouble ? 2f : 1f));
- // Set double button availability.
- if (initialBet > player.Balance || player.CurrentHand.Count != 2)
- {
- buttons["Double"].Visible = false;
- buttons["Double"].Enabled = false;
- }
- // Once you've split, you can't split again
- buttons["Split"].Visible = false;
- buttons["Split"].Enabled = false;
- }
- }
- /// <summary>
- /// Checks for running animations.
- /// </summary>
- /// <typeparam name="T">The type of animation to look for.</typeparam>
- /// <returns>True if a running animation of the desired type is found and
- /// false otherwise.</returns>
- internal bool CheckForRunningAnimations<T>() where T : AnimatedGameComponent
- {
- T animationComponent;
- for (int componentIndex = 0; componentIndex < Game.Components.Count; componentIndex++)
- {
- animationComponent = Game.Components[componentIndex] as T;
- if (animationComponent != null)
- {
- if (animationComponent.IsAnimating)
- return true;
- }
- }
- return false;
- }
- /// <summary>
- /// Ends the game.
- /// </summary>
- private void EndGame()
- {
- // Calculate the estimated time for all playing animations to end
- long estimatedTime = 0;
- AnimatedGameComponent animationComponent;
- for (int componentIndex = 0; componentIndex < Game.Components.Count; componentIndex++)
- {
- animationComponent = Game.Components[componentIndex] as AnimatedGameComponent;
- if (animationComponent != null)
- {
- estimatedTime = Math.Max(estimatedTime,
- animationComponent.EstimatedTimeForAnimationsCompletion().Ticks);
- }
- }
- // Add a component for an empty stalling animation. This actually acts
- // as a timer.
- Texture2D texture = this.Game.Content.Load<Texture2D>(@"Images\youlose");
- animationComponent = new AnimatedGameComponent(this, texture)
- {
- CurrentPosition = new Vector2(
- this.Game.GraphicsDevice.Viewport.Bounds.Center.X - texture.Width / 2,
- this.Game.GraphicsDevice.Viewport.Bounds.Center.Y - texture.Height / 2),
- Visible = false
- };
- this.Game.Components.Add(animationComponent);
- // Add a button to return to the main menu
- Rectangle bounds = this.Game.GraphicsDevice.Viewport.Bounds;
- Vector2 center = new Vector2(bounds.Center.X, bounds.Center.Y);
- Button backButton = new Button("ButtonRegular", "ButtonPressed",
- screenManager.input, this)
- {
- Bounds = new Rectangle((int)center.X - 100, (int)center.Y + 80, 200, 50),
- Font = this.Font,
- Text = "Main Menu",
- Visible = false,
- Enabled = true,
- };
- backButton.Click += backButton_Click;
- // Add stalling animation
- animationComponent.AddAnimation(new AnimatedGameComponentAnimation()
- {
- Duration = TimeSpan.FromTicks(estimatedTime) + TimeSpan.FromSeconds(1),
- PerformWhenDone = ResetGame,
- PerformWhenDoneArgs = new object[] { animationComponent, backButton }
- });
- Game.Components.Add(backButton);
- }
- /// <summary>
- /// Helper method to reset the game
- /// </summary>
- /// <param name="obj"></param>
- void ResetGame(object obj)
- {
- object[] arr = (object[])obj;
- State = BlackjackGameState.GameOver;
- ((AnimatedGameComponent)arr[0]).Visible = true;
- ((Button)arr[1]).Visible = true;
- // Remove all unnecessary game components
- for (int compontneIndex = 0; compontneIndex < Game.Components.Count; )
- {
- if ((Game.Components[compontneIndex] != ((AnimatedGameComponent)arr[0]) &&
- Game.Components[compontneIndex] != ((Button)arr[1])) &&
- (Game.Components[compontneIndex] is BetGameComponent ||
- Game.Components[compontneIndex] is AnimatedGameComponent ||
- Game.Components[compontneIndex] is Button))
- {
- Game.Components.RemoveAt(compontneIndex);
- }
- else
- compontneIndex++;
- }
- }
- /// <summary>
- /// Finishes the current turn.
- /// </summary>
- private void FinishTurn()
- {
- // Remove all unnecessary components
- for (int componentIndex = 0; componentIndex < Game.Components.Count; componentIndex++)
- {
- if (!(Game.Components[componentIndex] is GameTable ||
- Game.Components[componentIndex] is BlackjackCardGame ||
- Game.Components[componentIndex] is BetGameComponent ||
- Game.Components[componentIndex] is Button ||
- Game.Components[componentIndex] is ScreenManager ||
- Game.Components[componentIndex] is InputHelper))
- {
- if (Game.Components[componentIndex] is AnimatedCardsGameComponent)
- {
- AnimatedCardsGameComponent animatedCard =
- (Game.Components[componentIndex] as AnimatedCardsGameComponent);
- animatedCard.AddAnimation(
- new TransitionGameComponentAnimation(animatedCard.CurrentPosition,
- new Vector2(animatedCard.CurrentPosition.X, this.Game.GraphicsDevice.Viewport.Height))
- {
- Duration = TimeSpan.FromSeconds(0.40),
- PerformWhenDone = RemoveComponent,
- PerformWhenDoneArgs = animatedCard
- });
- }
- else
- {
- Game.Components.RemoveAt(componentIndex);
- componentIndex--;
- }
- }
- }
- // Reset player values
- for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
- {
- (players[playerIndex] as BlackjackPlayer).ResetValues();
- players[playerIndex].Hand.DealCardsToHand(deadCards, players[playerIndex].Hand.Count);
- turnFinishedByPlayer[playerIndex] = false;
- animatedHands[playerIndex] = null;
- animatedSecondHands[playerIndex] = null;
- }
- // Reset the bet component
- betGameComponent.Reset();
- betGameComponent.Enabled = true;
- // Reset dealer
- dealerPlayer.Hand.DealCardsToHand(deadCards, dealerPlayer.Hand.Count);
- dealerPlayer.ResetValues();
- // Reset rules
- rules.Clear();
- }
- /// <summary>
- /// Helper method to remove component
- /// </summary>
- /// <param name="obj"></param>
- void RemoveComponent(object obj)
- {
- Game.Components.Remove((AnimatedGameComponent)obj);
- }
- /// <summary>
- /// Performs the "Stand" move for the current player.
- /// </summary>
- public void Stand()
- {
- BlackjackPlayer player = (BlackjackPlayer)GetCurrentPlayer();
- if (player == null)
- return;
- // If the player only has one hand, his turn ends. Otherwise, he now plays
- // using his next hand
- if (player.IsSplit == false)
- {
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- }
- else
- {
- switch (player.CurrentHandType)
- {
- case HandTypes.First:
- if (player.SecondBlackJack)
- {
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- }
- else
- {
- player.CurrentHandType = HandTypes.Second;
- }
- break;
- case HandTypes.Second:
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- }
- }
- /// <summary>
- /// Performs the "Split" move for the current player.
- /// This includes adding the animations which shows the first hand splitting
- /// into two.
- /// </summary>
- public void Split()
- {
- BlackjackPlayer player = (BlackjackPlayer)GetCurrentPlayer();
- int playerIndex = players.IndexOf(player);
- player.InitializeSecondHand();
- Vector2 sourcePosition = animatedHands[playerIndex].GetCardGameComponent(1).CurrentPosition;
- Vector2 targetPosition = animatedHands[playerIndex].GetCardGameComponent(0).CurrentPosition +
- secondHandOffset;
- // Create an animation moving the top card to the second hand location
- AnimatedGameComponentAnimation animation = new TransitionGameComponentAnimation(sourcePosition,
- targetPosition)
- {
- StartTime = DateTime.Now,
- Duration = TimeSpan.FromSeconds(0.5f)
- };
- // Actually perform the split
- player.SplitHand();
- // Add additional chip stack for the second hand
- betGameComponent.AddChips(playerIndex, player.BetAmount,
- false, true);
- // Initialize visual representation of the second hand
- animatedSecondHands[playerIndex] =
- new BlackjackAnimatedPlayerHandComponent(playerIndex, secondHandOffset,
- player.SecondHand, this);
- Game.Components.Add(animatedSecondHands[playerIndex]);
- AnimatedCardsGameComponent animatedGameComponet = animatedSecondHands[playerIndex].GetCardGameComponent(0);
- animatedGameComponet.IsFaceDown = false;
- animatedGameComponet.AddAnimation(animation);
- // Deal an additional cards to each of the new hands
- TraditionalCard card = dealer.DealCardToHand(player.Hand);
- AddDealAnimation(card, animatedHands[playerIndex], true, dealDuration,
- DateTime.Now + animation.EstimatedTimeForAnimationCompletion);
- card = dealer.DealCardToHand(player.SecondHand);
- AddDealAnimation(card, animatedSecondHands[playerIndex], true, dealDuration,
- DateTime.Now + animation.EstimatedTimeForAnimationCompletion +
- dealDuration);
- }
- /// <summary>
- /// Performs the "Double" move for the current player.
- /// </summary>
- public void Double()
- {
- BlackjackPlayer player = (BlackjackPlayer)GetCurrentPlayer();
- int playerIndex = players.IndexOf(player);
- switch (player.CurrentHandType)
- {
- case HandTypes.First:
- player.Double = true;
- float betAmount = player.BetAmount;
- if (player.IsSplit)
- {
- betAmount /= 2f;
- }
- betGameComponent.AddChips(playerIndex, betAmount, false, false);
- break;
- case HandTypes.Second:
- player.SecondDouble = true;
- if (player.Double == false)
- {
- // The bet is evenly spread between both hands, add one half
- betGameComponent.AddChips(playerIndex, player.BetAmount / 2f,
- false, true);
- }
- else
- {
- // The first hand's bet is double, add one third of the total
- betGameComponent.AddChips(playerIndex, player.BetAmount / 3f,
- false, true);
- }
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- Hit();
- Stand();
- }
- /// <summary>
- /// Performs the "Hit" move for the current player.
- /// </summary>
- public void Hit()
- {
- BlackjackPlayer player = (BlackjackPlayer)GetCurrentPlayer();
- if (player == null)
- return;
- int playerIndex = players.IndexOf(player);
- // Draw a card to the appropriate hand
- switch (player.CurrentHandType)
- {
- case HandTypes.First:
- TraditionalCard card = dealer.DealCardToHand(player.Hand);
- AddDealAnimation(card, animatedHands[playerIndex], true,
- dealDuration, DateTime.Now);
- break;
- case HandTypes.Second:
- card = dealer.DealCardToHand(player.SecondHand);
- AddDealAnimation(card, animatedSecondHands[playerIndex], true,
- dealDuration, DateTime.Now);
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- }
- /// <summary>
- /// Changes the visiblility of most game buttons.
- /// </summary>
- /// <param name="visible">True to make the buttons visible, false to make
- /// them invisible.</param>
- void ChangeButtonsVisiblility(bool visible)
- {
- buttons["Hit"].Visible = visible;
- buttons["Stand"].Visible = visible;
- buttons["Double"].Visible = visible;
- buttons["Split"].Visible = visible;
- buttons["Insurance"].Visible = visible;
- }
- /// <summary>
- /// Enables or disable most game buttons.
- /// </summary>
- /// <param name="enabled">True to enable the buttons , false to
- /// disable them.</param>
- void EnableButtons(bool enabled)
- {
- buttons["Hit"].Enabled = enabled;
- buttons["Stand"].Enabled = enabled;
- buttons["Double"].Enabled = enabled;
- buttons["Split"].Enabled = enabled;
- buttons["Insurance"].Enabled = enabled;
- }
- /// <summary>
- /// Add an indication that the player has passed on the current round.
- /// </summary>
- /// <param name="indexPlayer">The player's index.</param>
- public void ShowPlayerPass(int indexPlayer)
- {
- // Add animation component
- AnimatedGameComponent passComponent = new AnimatedGameComponent(this, cardsAssets["pass"])
- {
- CurrentPosition = GameTable.PlaceOrder(indexPlayer),
- Visible = false
- };
- Game.Components.Add(passComponent);
- // Hide insurance button only when the first payer passes
- Action<object> performWhenDone = null;
- if (indexPlayer == 0)
- {
- performWhenDone = HideInshurance;
- }
- // Add scale animation for the pass "card"
- passComponent.AddAnimation(new ScaleGameComponentAnimation(2.0f, 1.0f)
- {
- AnimationCycles = 1,
- PerformBeforeStart = ShowComponent,
- PerformBeforSartArgs = passComponent,
- StartTime = DateTime.Now,
- Duration = TimeSpan.FromSeconds(1),
- PerformWhenDone = performWhenDone
- });
- }
- /// <summary>
- /// Helper method to hide insurance
- /// </summary>
- /// <param name="obj"></param>
- void HideInshurance(object obj)
- {
- showInsurance = false;
- }
- #endregion
- #region Event Handlers
- /// <summary>
- /// Shows the insurance button if the first player can afford insurance.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing
- /// the event data.</param>
- void InsuranceGameRule(object sender, EventArgs e)
- {
- BlackjackPlayer player = (BlackjackPlayer)players[0];
- if (player.Balance >= player.BetAmount / 2)
- {
- showInsurance = true;
- }
- }
- /// <summary>
- /// Shows the bust visual cue after the bust rule has been matched.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing
- /// the event data.</param>
- void BustGameRule(object sender, EventArgs e)
- {
- showInsurance = false;
- BlackjackGameEventArgs args = (e as BlackjackGameEventArgs);
- BlackjackPlayer player = (BlackjackPlayer)args.Player;
- CueOverPlayerHand(player, "bust", args.Hand, null);
- switch (args.Hand)
- {
- case HandTypes.First:
- player.Bust = true;
- if (player.IsSplit && !player.SecondBlackJack)
- {
- player.CurrentHandType = HandTypes.Second;
- }
- else
- {
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- }
- break;
- case HandTypes.Second:
- player.SecondBust = true;
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- }
- /// <summary>
- /// Shows the blackjack visual cue after the blackjack rule has been matched.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing
- /// the event data.</param>
- void BlackJackGameRule(object sender, EventArgs e)
- {
- showInsurance = false;
- BlackjackGameEventArgs args = (e as BlackjackGameEventArgs);
- BlackjackPlayer player = (BlackjackPlayer)args.Player;
- CueOverPlayerHand(player, "blackjack", args.Hand, null);
- switch (args.Hand)
- {
- case HandTypes.First:
- player.BlackJack = true;
- if (player.IsSplit)
- {
- player.CurrentHandType = HandTypes.Second;
- }
- else
- {
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- }
- break;
- case HandTypes.Second:
- player.SecondBlackJack = true;
- if (player.CurrentHandType == HandTypes.Second)
- {
- turnFinishedByPlayer[players.IndexOf(player)] = true;
- }
- break;
- default:
- throw new Exception(
- "Player has an unsupported hand type.");
- }
- }
- /// <summary>
- /// Handles the Click event of the insurance button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void Insurance_Click(object sender, EventArgs e)
- {
- BlackjackPlayer player = (BlackjackPlayer)GetCurrentPlayer();
- if (player == null)
- return;
- player.IsInsurance = true;
- player.Balance -= player.BetAmount / 2f;
- betGameComponent.AddChips(players.IndexOf(player), player.BetAmount / 2, true, false);
- showInsurance = false;
- }
- /// <summary>
- /// Handles the Click event of the new game button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void newGame_Click(object sender, EventArgs e)
- {
- FinishTurn();
- StartRound();
- newGame.Enabled = false;
- newGame.Visible = false;
- }
- /// <summary>
- /// Handles the Click event of the hit button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void Hit_Click(object sender, EventArgs e)
- {
- Hit();
- showInsurance = false;
- }
- /// <summary>
- /// Handles the Click event of the stand button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void Stand_Click(object sender, EventArgs e)
- {
- Stand();
- showInsurance = false;
- }
- /// <summary>
- /// Handles the Click event of the double button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void Double_Click(object sender, EventArgs e)
- {
- Double();
- showInsurance = false;
- }
- /// <summary>
- /// Handles the Click event of the split button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void Split_Click(object sender, EventArgs e)
- {
- Split();
- showInsurance = false;
- }
- /// <summary>
- /// Handles the Click event of the back button.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">>The
- /// <see cref="System.EventArgs"/> instance containing the event data.</param>
- void backButton_Click(object sender, EventArgs e)
- {
- // Remove all unnecessary components
- for (int componentIndex = 0; componentIndex < Game.Components.Count; componentIndex++)
- {
- if (!(Game.Components[componentIndex] is ScreenManager))
- {
- Game.Components.RemoveAt(componentIndex);
- componentIndex--;
- }
- }
- foreach (GameScreen screen in screenManager.GetScreens())
- screen.ExitScreen();
- screenManager.AddScreen(new BackgroundScreen(), null);
- screenManager.AddScreen(new MainMenuScreen(), null);
- }
- #endregion
- }
- }
|