diliupg

PA6

Oct 16th, 2017
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.99 KB | None | 0 0
  1. using System.Collections.Generic;
  2.  
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Graphics;
  5. using Microsoft.Xna.Framework.Input;
  6.  
  7. using XnaCards;
  8.  
  9. namespace ProgrammingAssignment6
  10. {
  11.     /// <summary>
  12.     /// This is the main type for your game.
  13.     /// </summary>
  14.     public class Game1 : Game
  15.     {
  16.         GraphicsDeviceManager graphics;
  17.         SpriteBatch spriteBatch;
  18.  
  19.         const int WindowWidth = 800;
  20.         const int WindowHeight = 600;
  21.  
  22.         // max valid blockjuck score for a hand
  23.         const int MaxHandValue = 21;
  24.  
  25.         // deck and hands
  26.         Deck deck;
  27.         List<Card> dealerHand = new List<Card>();
  28.         List<Card> playerHand = new List<Card>();
  29.  
  30.         // hand placement
  31.         const int TopCardOffset = 100;
  32.         const int HorizontalCardOffset = 150;
  33.         const int VerticalCardSpacing = 125;
  34.  
  35.         // messages
  36.         SpriteFont messageFont;
  37.         const string ScoreMessagePrefix = "Score: ";
  38.         Message playerScoreMessage;
  39.         Message dealerScoreMessage;
  40.         Message winnerMessage;
  41.         List<Message> messages = new List<Message>();
  42.  
  43.         // message placement
  44.         const int ScoreMessageTopOffset = 25;
  45.         const int HorizontalMessageOffset = HorizontalCardOffset;
  46.         Vector2 winnerMessageLocation = new Vector2(WindowWidth / 2,
  47.             WindowHeight / 2);
  48.  
  49.         // menu buttons
  50.         Texture2D quitButtonSprite;
  51.         List<MenuButton> menuButtons = new List<MenuButton>();
  52.  
  53.         // menu button placement
  54.         const int TopMenuButtonOffset = TopCardOffset;
  55.         const int QuitMenuButtonOffset = WindowHeight - TopCardOffset;
  56.         const int HorizontalMenuButtonOffset = WindowWidth / 2;
  57.         const int VerticalMenuButtonSpacing = 125;
  58.  
  59.         // use to detect hand over when player and dealer didn't hit
  60.         bool playerHit = false;
  61.         bool dealerHit = false;
  62.  
  63.         // game state tracking. Start by setting current state to WaitingForPlayer because this input is what will
  64.         //trigger the game into action
  65.         static GameState currentState = GameState.WaitingForPlayer;
  66.  
  67.  
  68.         public Game1()
  69.         {
  70.             graphics = new GraphicsDeviceManager(this);
  71.             Content.RootDirectory = "Content";
  72.  
  73.             graphics.PreferredBackBufferWidth = WindowWidth;
  74.             graphics.PreferredBackBufferHeight = WindowHeight;
  75.  
  76.             IsMouseVisible = true;
  77.         }
  78.  
  79.         /// <summary>
  80.         /// Allows the game to perform any initialization it needs to before starting to run.
  81.         /// This is where it can query for any required services and load any non-graphic
  82.         /// related content.  Calling base.Initialize will enumerate through any components
  83.         /// and initialize them as well.
  84.         /// </summary>
  85.         protected override void Initialize()
  86.         {
  87.             // TODO: Add your initialization logic here
  88.  
  89.             base.Initialize();
  90.         }
  91.  
  92.         /// <summary>
  93.         /// LoadContent will be called once per game and is the place to load
  94.         /// all of your content.
  95.         /// </summary>
  96.         protected override void LoadContent()
  97.         {
  98.             // Create a new SpriteBatch, which can be used to draw textures.
  99.             spriteBatch = new SpriteBatch(GraphicsDevice);
  100.  
  101.             // create and shuffle deck
  102.             deck = new Deck(Content, 0, 0);
  103.             deck.Shuffle();
  104.  
  105.             // first player card
  106.             Card playerCard1 = new Card(Content, deck.TakeTopCard().Rank,
  107.                 deck.TakeTopCard().Suit, HorizontalCardOffset, TopCardOffset);
  108.             playerCard1.FlipOver();
  109.             playerHand.Add(playerCard1);
  110.  
  111.             // first dealer card
  112.             Card dealerCard1 = new Card(Content, deck.TakeTopCard().Rank,
  113.                 deck.TakeTopCard().Suit, WindowWidth - HorizontalCardOffset, TopCardOffset);
  114.             dealerHand.Add(dealerCard1);
  115.  
  116.             // second player card
  117.             Card playerCard2 = new Card(Content, deck.TakeTopCard().Rank,
  118.                 deck.TakeTopCard().Suit, HorizontalCardOffset, TopCardOffset * 2);
  119.             playerCard2.FlipOver();
  120.             playerHand.Add(playerCard2);
  121.  
  122.             // second dealer card
  123.             Card dealerCard2 = new Card(Content, deck.TakeTopCard().Rank,
  124.                 deck.TakeTopCard().Suit, WindowWidth - HorizontalCardOffset, TopCardOffset * 2);
  125.             dealerCard2.FlipOver();
  126.             dealerHand.Add(dealerCard2);
  127.  
  128.             // load sprite font, create message for player score and add to list
  129.             messageFont = Content.Load<SpriteFont>(@"fonts\Arial24");
  130.             playerScoreMessage = new Message(ScoreMessagePrefix + GetBlockjuckScore(playerHand).ToString(),
  131.                 messageFont,
  132.                 new Vector2(HorizontalMessageOffset, ScoreMessageTopOffset));
  133.             messages.Add(playerScoreMessage);
  134.  
  135.             // load quit button sprite for later use
  136.             quitButtonSprite = Content.Load<Texture2D>(@"graphics\quitbutton");
  137.  
  138.             // create hit button and add to list
  139.             Texture2D hitButtonImage = Content.Load<Texture2D>(@"graphics/hitbutton");
  140.             Vector2 center = new Vector2(WindowWidth / 2, TopCardOffset);
  141.             MenuButton hitButton = new MenuButton(hitButtonImage, center, GameState.PlayerHitting);
  142.             menuButtons.Add(hitButton);
  143.  
  144.             // create stand button and add to list
  145.             Texture2D standButtonImage = Content.Load<Texture2D>(@"graphics/standbutton");
  146.             Vector2 center2 = new Vector2(WindowWidth / 2, TopCardOffset + VerticalCardSpacing);
  147.             MenuButton standButton = new MenuButton(standButtonImage, center2, GameState.WaitingForDealer);
  148.             menuButtons.Add(standButton);
  149.         }
  150.  
  151.         /// <summary>
  152.         /// UnloadContent will be called once per game and is the place to unload
  153.         /// game-specific content.
  154.         /// </summary>
  155.         protected override void UnloadContent()
  156.         {
  157.             // TODO: Unload any non ContentManager content here
  158.         }
  159.  
  160.         /// <summary>
  161.         /// Allows the game to run logic such as updating the world,
  162.         /// checking for collisions, gathering input, and playing audio.
  163.         /// </summary>
  164.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  165.         protected override void Update(GameTime gameTime)
  166.         {
  167.             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
  168.                 Keyboard.GetState().IsKeyDown(Keys.Escape))
  169.                 Exit();
  170.             MouseState mouse = Mouse.GetState();
  171.  
  172.             // update menu buttons if WaitingForPlayer or DisplayingHandResults
  173.             if (currentState == GameState.WaitingForPlayer || currentState == GameState.DisplayingHandResults)
  174.             {
  175.                 foreach (MenuButton button in menuButtons)
  176.                 {
  177.                     button.Update(mouse);
  178.                 }
  179.             }
  180.             // ===============  game states  ===============
  181.  
  182.             //PlayerHitting
  183.             if (currentState == GameState.PlayerHitting)
  184.             {
  185.                 Card anotherCardForPlayer = new Card(Content, deck.TakeTopCard().Rank,
  186.                     deck.TakeTopCard().Suit, HorizontalCardOffset, TopCardOffset * (playerHand.Count + 1));
  187.                 anotherCardForPlayer.FlipOver();
  188.                 playerHand.Add(anotherCardForPlayer);
  189.                 playerScoreMessage.Text = ScoreMessagePrefix + GetBlockjuckScore(playerHand).ToString();
  190.                 playerHit = true;
  191.                 ChangeState(GameState.WaitingForDealer);
  192.  
  193.             }
  194.             // WaitingForDealer
  195.             else if (currentState == GameState.WaitingForDealer)
  196.             {
  197.                 if (GetBlockjuckScore(dealerHand) <= 16) // dealer can and WILL HIT
  198.                 {
  199.                     ChangeState(GameState.DealerHitting);
  200.                 }
  201.                 else
  202.                 {
  203.                     // dealer DIDN'T HIT
  204.                     ChangeState(GameState.CheckingHandOver);
  205.                 }
  206.             }
  207.             // DealerHitting
  208.             else if (currentState == GameState.DealerHitting)
  209.             {
  210.                 Card anotherCardForDealer = new Card(Content, deck.TakeTopCard().Rank,
  211.                     deck.TakeTopCard().Suit, WindowWidth - HorizontalCardOffset,
  212.                     TopCardOffset * (dealerHand.Count + 1));
  213.  
  214.                 anotherCardForDealer.FlipOver();
  215.                 dealerHand.Add(anotherCardForDealer);
  216.  
  217.                 dealerHit = true;
  218.                 ChangeState(GameState.CheckingHandOver);
  219.             }
  220.             // CheckingHandOver
  221.             else if (currentState == GameState.CheckingHandOver)
  222.             {
  223.                 // if either party goes over 21 or both decided to STAND the HAND IS OVER.
  224.  
  225.                 if ((GetBlockjuckScore(playerHand) > MaxHandValue) ||
  226.                     (GetBlockjuckScore(dealerHand) > MaxHandValue) ||
  227.                     (playerHit == false && dealerHit == false))
  228.                 {
  229.                     dealerScoreMessage = new Message(ScoreMessagePrefix +
  230.                         GetBlockjuckScore(dealerHand).ToString(),
  231.                         messageFont, new Vector2(WindowWidth -
  232.                         HorizontalMessageOffset, ScoreMessageTopOffset));
  233.  
  234.                     messages.Add(dealerScoreMessage);
  235.  
  236.                     // create quit button and add to list
  237.                     Vector2 quitButCenter = new Vector2(WindowWidth / 2,
  238.                         WindowHeight - TopCardOffset - VerticalCardSpacing);
  239.                     MenuButton quitButton = new MenuButton(quitButtonSprite, quitButCenter,
  240.                         GameState.Exiting);
  241.  
  242.                     dealerHand[0].FlipOver();
  243.                     menuButtons.RemoveRange(0, 2);
  244.                     menuButtons.Add(quitButton);
  245.                     ChangeState(GameState.DisplayingHandResults);
  246.  
  247.                     // game logic
  248.                     if (GetBlockjuckScore(dealerHand) > GetBlockjuckScore(playerHand) &&
  249.                         GetBlockjuckScore(dealerHand )<= MaxHandValue)
  250.                     {
  251.                         string message = "Dealer Wins!";
  252.                         winnerMessage = new Message(message, messageFont, winnerMessageLocation);
  253.                         messages.Add(winnerMessage);
  254.                         ChangeState(GameState.DisplayingHandResults);
  255.                     }
  256.                     else if (GetBlockjuckScore(playerHand) > GetBlockjuckScore(dealerHand) &&
  257.                         GetBlockjuckScore(playerHand) <= MaxHandValue)
  258.                     {
  259.                         string message = "Player Wins!";
  260.                         winnerMessage = new Message(message, messageFont, winnerMessageLocation);
  261.                         messages.Add(winnerMessage);
  262.                         ChangeState(GameState.DisplayingHandResults);
  263.                     }
  264.                     else if (GetBlockjuckScore(playerHand) == GetBlockjuckScore(dealerHand))
  265.                     {
  266.                         string message = "It's a TIE!";
  267.                         winnerMessage = new Message(message, messageFont, winnerMessageLocation);
  268.                         messages.Add(winnerMessage);
  269.                         ChangeState(GameState.DisplayingHandResults);
  270.                     }
  271.                     else if (GetBlockjuckScore(playerHand) > MaxHandValue &&
  272.                         GetBlockjuckScore(dealerHand) > MaxHandValue)
  273.                     {
  274.                         string message = "Both Busted!!!";
  275.                         winnerMessage = new Message(message, messageFont, winnerMessageLocation);
  276.                         messages.Add(winnerMessage);
  277.                         ChangeState(GameState.DisplayingHandResults);
  278.                     }
  279.                     else if (GetBlockjuckScore(playerHand) > MaxHandValue &&
  280.                         GetBlockjuckScore(dealerHand) <= MaxHandValue)
  281.                     {
  282.                         string message = "Dealer Wins";
  283.                         winnerMessage = new Message(message, messageFont, winnerMessageLocation);
  284.                         messages.Add(winnerMessage);
  285.                         ChangeState(GameState.DisplayingHandResults);
  286.                     }
  287.                     else if (GetBlockjuckScore(dealerHand) > MaxHandValue &&
  288.                         GetBlockjuckScore(playerHand) <= MaxHandValue)
  289.                     {
  290.                         string message = "Player Wins";
  291.                         winnerMessage = new Message(message, messageFont, winnerMessageLocation);
  292.                         messages.Add(winnerMessage);
  293.                         ChangeState(GameState.DisplayingHandResults);
  294.                     }
  295.                 }
  296.                 else
  297.                 {
  298.                     ChangeState(GameState.WaitingForPlayer);
  299.                     playerHit = false;
  300.                     dealerHit = false;
  301.                 }
  302.             }
  303.             // QUIT GAME
  304.             else if (currentState == GameState.Exiting)
  305.             {
  306.                 Exit();
  307.             }
  308.  
  309.             base.Update(gameTime);
  310.         }
  311.  
  312.         /// <summary>
  313.         /// This is called when the game should draw itself.
  314.         /// </summary>
  315.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  316.         protected override void Draw(GameTime gameTime)
  317.         {
  318.             GraphicsDevice.Clear(Color.Goldenrod);
  319.  
  320.             spriteBatch.Begin();
  321.  
  322.             // draw hands
  323.             foreach (Card card in dealerHand)
  324.             {
  325.                 card.Draw(spriteBatch);
  326.             }
  327.  
  328.             foreach (Card card in playerHand)
  329.             {
  330.                 card.Draw(spriteBatch);
  331.             }
  332.  
  333.             // draw messages
  334.             foreach (Message message in messages)
  335.             {
  336.                 message.Draw(spriteBatch);
  337.             }
  338.  
  339.             // draw menu buttons
  340.             foreach (MenuButton button in menuButtons)
  341.             {
  342.                 button.Draw(spriteBatch);
  343.             }
  344.  
  345.             spriteBatch.End();
  346.  
  347.             base.Draw(gameTime);
  348.         }
  349.  
  350.         /// <summary>
  351.         /// Calculates the Blockjuck score for the given hand
  352.         /// </summary>
  353.         /// <param name="hand">the hand</param>
  354.         /// <returns>the Blockjuck score for the hand</returns>
  355.         private int GetBlockjuckScore(List<Card> hand)
  356.         {
  357.             // add up score excluding Aces
  358.             int numAces = 0;
  359.             int score = 0;
  360.             foreach (Card card in hand)
  361.             {
  362.                 if (card.Rank != Rank.Ace)
  363.                 {
  364.                     score += GetBlockjuckCardValue(card);
  365.                 }
  366.                 else
  367.                 {
  368.                     numAces++;
  369.                 }
  370.             }
  371.  
  372.             // if more than one ace, only one should ever be counted as 11
  373.             if (numAces > 1)
  374.             {
  375.                 // make all but the first ace count as 1
  376.                 score += numAces - 1;
  377.                 numAces = 1;
  378.             }
  379.  
  380.             // if there's an Ace, score it the best way possible
  381.             if (numAces > 0)
  382.             {
  383.                 if (score + 11 <= MaxHandValue)
  384.                 {
  385.                     // counting Ace as 11 doesn't bust
  386.                     score += 11;
  387.                 }
  388.                 else
  389.                 {
  390.                     // count Ace as 1
  391.                     score++;
  392.                 }
  393.             }
  394.  
  395.             return score;
  396.         }
  397.  
  398.         /// <summary>
  399.         /// Gets the Blockjuck value for the given card
  400.         /// </summary>
  401.         /// <param name="card">the card</param>
  402.         /// <returns>the Blockjuck value for the card</returns>
  403.         private int GetBlockjuckCardValue(Card card)
  404.         {
  405.             switch (card.Rank)
  406.             {
  407.                 case Rank.Ace:
  408.                     return 11;
  409.                 case Rank.King:
  410.                 case Rank.Queen:
  411.                 case Rank.Jack:
  412.                 case Rank.Ten:
  413.                     return 10;
  414.                 case Rank.Nine:
  415.                     return 9;
  416.                 case Rank.Eight:
  417.                     return 8;
  418.                 case Rank.Seven:
  419.                     return 7;
  420.                 case Rank.Six:
  421.                     return 6;
  422.                 case Rank.Five:
  423.                     return 5;
  424.                 case Rank.Four:
  425.                     return 4;
  426.                 case Rank.Three:
  427.                     return 3;
  428.                 case Rank.Two:
  429.                     return 2;
  430.                 default:
  431.                     return 0;
  432.             }
  433.         }
  434.  
  435.         /// <summary>
  436.         /// Changes the state of the game
  437.         /// </summary>
  438.         /// <param name="newState">the new game state</param>
  439.         public static void ChangeState(GameState newState)
  440.         {
  441.             currentState = newState;
  442.         }
  443.     }
  444. }
Add Comment
Please, Sign In to add comment