Click here to Skip to main content
15,885,278 members
Articles / Programming Languages / C#

Blackjack - a real world OOD example

Rate me:
Please Sign up or sign in to vote.
4.87/5 (47 votes)
18 Jul 20076 min read 236K   9.6K   153  
Learn OOD in .NET by examining a Blackjack game
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Configuration;
using System.Globalization;

namespace BlackJack
{
	/// <summary>
	/// This is an almost full-functioned Blackjack game with strategy advice
	/// and human/computer controlled players.  The rules are the common Blackjack
	/// rules used in most casinos except the player is limited to two hands (split).
	/// </summary>
	public class frmBlackjack : System.Windows.Forms.Form
	{
		#region FormControls


		private System.Windows.Forms.NumericUpDown txtNumberOfDecks;
		private System.Windows.Forms.NumericUpDown txtNumberOfPlayers;

		private System.Windows.Forms.Button btnDeal;
		private System.Windows.Forms.Button btnSplit;
		private System.Windows.Forms.Button btnHit;
		private System.Windows.Forms.Button btnStay;
		private System.Windows.Forms.Button btnDoubleDown;
		private System.Windows.Forms.Timer tmrAutoPlay;
		private System.Windows.Forms.NumericUpDown txtDelay;
		private System.ComponentModel.IContainer components;
		private System.Windows.Forms.StatusBarPanel Hands;
		private System.Windows.Forms.StatusBarPanel Shuffles;
		private System.Windows.Forms.CheckBox chkAuto;
		private System.Windows.Forms.StatusBar pnlStatistics;
		private System.Windows.Forms.CheckBox chkMute;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.ComboBox cboMethod;
		private System.Windows.Forms.ComboBox cboStrategy;
		private System.Windows.Forms.ComboBox cboPlayerType;
		private System.Windows.Forms.Label lblPlayer;
		private System.Windows.Forms.Panel pnlPlayerControls;
		private System.Windows.Forms.Button btnCancelControls;
		private System.Windows.Forms.Button btnOKControls;
		#endregion

		// mainScreen is a Graphics surface to draw on
		//private Screen mainScreen;
		// The one and only Shoe object
		private Shoe shoe = new Shoe();
		// An array of player objects
		private Player[] players = new Player[0];
		// The one and only dealer object
		private Dealer dealer;
		// Whether or not the dealer's down card is visible
		private bool showDealerDownCard;
		// currentPlayer keeps track of which player is active
		// currentPlayer > the number of Players (or -1) means the dealer is active
		private int currentPlayer = -1;
		// Determines what kind of label is drawn to the upper left of each player hand
		// Normally display the card total, but after a hand, display the outcome
		private Player.LabelType labelType = Player.LabelType.bothHands;
		// Statistics variables
		private int deals = 0;
		private int shuffles = 0;
		// variables to keep track of which player we are changing 
		protected int playerNumber;
		// So we know if the player double clicks on the bet area to bring up the controls
		protected Point mouseLocation;
		// Boolean indicates end of shoe.  It is set via event from the shoe
		private bool endOfShoe;
		// Scaling variables to make resizing faster and easier
		float scaleX = 1.0F;
		private System.Windows.Forms.StatusBarPanel NumberDecks;
		private System.Windows.Forms.StatusBarPanel NumberPlayers;
		private System.Windows.Forms.StatusBarPanel Interval;
		private System.Windows.Forms.StatusBarPanel Mute;
		private System.Windows.Forms.StatusBarPanel AutoDeal;
		float scaleY = 1.0F;


		#region Windows Form Designer generated code
		public frmBlackjack()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
			this.SetStyle(ControlStyles.UserPaint, true);
			this.SetStyle(ControlStyles.DoubleBuffer, true);

			shoe.EndOfShoeEvent += new Shoe.ShoeEventHandler(EndOfShoe);
			shoe.ShuffleEvent += new Shoe.ShoeEventHandler(ShuffleShoe);

		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.txtNumberOfDecks = new System.Windows.Forms.NumericUpDown();
			this.txtNumberOfPlayers = new System.Windows.Forms.NumericUpDown();
			this.btnDeal = new System.Windows.Forms.Button();
			this.btnSplit = new System.Windows.Forms.Button();
			this.btnHit = new System.Windows.Forms.Button();
			this.btnStay = new System.Windows.Forms.Button();
			this.btnDoubleDown = new System.Windows.Forms.Button();
			this.tmrAutoPlay = new System.Windows.Forms.Timer(this.components);
			this.txtDelay = new System.Windows.Forms.NumericUpDown();
			this.pnlStatistics = new System.Windows.Forms.StatusBar();
			this.Hands = new System.Windows.Forms.StatusBarPanel();
			this.Shuffles = new System.Windows.Forms.StatusBarPanel();
			this.chkAuto = new System.Windows.Forms.CheckBox();
			this.chkMute = new System.Windows.Forms.CheckBox();
			this.btnOKControls = new System.Windows.Forms.Button();
			this.label5 = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.cboMethod = new System.Windows.Forms.ComboBox();
			this.cboStrategy = new System.Windows.Forms.ComboBox();
			this.cboPlayerType = new System.Windows.Forms.ComboBox();
			this.lblPlayer = new System.Windows.Forms.Label();
			this.pnlPlayerControls = new System.Windows.Forms.Panel();
			this.btnCancelControls = new System.Windows.Forms.Button();
			this.NumberDecks = new System.Windows.Forms.StatusBarPanel();
			this.NumberPlayers = new System.Windows.Forms.StatusBarPanel();
			this.Interval = new System.Windows.Forms.StatusBarPanel();
			this.Mute = new System.Windows.Forms.StatusBarPanel();
			this.AutoDeal = new System.Windows.Forms.StatusBarPanel();
			((System.ComponentModel.ISupportInitialize)(this.txtNumberOfDecks)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.txtNumberOfPlayers)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.txtDelay)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.Hands)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.Shuffles)).BeginInit();
			this.pnlPlayerControls.SuspendLayout();
			((System.ComponentModel.ISupportInitialize)(this.NumberDecks)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.NumberPlayers)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.Interval)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.Mute)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.AutoDeal)).BeginInit();
			this.SuspendLayout();
			// 
			// txtNumberOfDecks
			// 
			this.txtNumberOfDecks.Anchor = System.Windows.Forms.AnchorStyles.Top;
			this.txtNumberOfDecks.BackColor = System.Drawing.SystemColors.Control;
			this.txtNumberOfDecks.BorderStyle = System.Windows.Forms.BorderStyle.None;
			this.txtNumberOfDecks.CausesValidation = false;
			this.txtNumberOfDecks.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.txtNumberOfDecks.ForeColor = System.Drawing.SystemColors.ControlText;
			this.txtNumberOfDecks.Location = new System.Drawing.Point(1083, 573);
			this.txtNumberOfDecks.Maximum = new System.Decimal(new int[] {
																			 10,
																			 0,
																			 0,
																			 0});
			this.txtNumberOfDecks.Minimum = new System.Decimal(new int[] {
																			 1,
																			 0,
																			 0,
																			 0});
			this.txtNumberOfDecks.Name = "txtNumberOfDecks";
			this.txtNumberOfDecks.ReadOnly = true;
			this.txtNumberOfDecks.Size = new System.Drawing.Size(48, 16);
			this.txtNumberOfDecks.TabIndex = 2;
			this.txtNumberOfDecks.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
			this.txtNumberOfDecks.Value = new System.Decimal(new int[] {
																		   6,
																		   0,
																		   0,
																		   0});
			this.txtNumberOfDecks.ValueChanged += new System.EventHandler(this.txtNumberOfDecks_ValueChanged);
			// 
			// txtNumberOfPlayers
			// 
			this.txtNumberOfPlayers.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
			this.txtNumberOfPlayers.BackColor = System.Drawing.SystemColors.Control;
			this.txtNumberOfPlayers.BorderStyle = System.Windows.Forms.BorderStyle.None;
			this.txtNumberOfPlayers.CausesValidation = false;
			this.txtNumberOfPlayers.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.txtNumberOfPlayers.ForeColor = System.Drawing.SystemColors.ControlText;
			this.txtNumberOfPlayers.Location = new System.Drawing.Point(1083, 597);
			this.txtNumberOfPlayers.Maximum = new System.Decimal(new int[] {
																			   5,
																			   0,
																			   0,
																			   0});
			this.txtNumberOfPlayers.Minimum = new System.Decimal(new int[] {
																			   1,
																			   0,
																			   0,
																			   0});
			this.txtNumberOfPlayers.Name = "txtNumberOfPlayers";
			this.txtNumberOfPlayers.ReadOnly = true;
			this.txtNumberOfPlayers.Size = new System.Drawing.Size(48, 16);
			this.txtNumberOfPlayers.TabIndex = 6;
			this.txtNumberOfPlayers.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
			this.txtNumberOfPlayers.Value = new System.Decimal(new int[] {
																			 5,
																			 0,
																			 0,
																			 0});
			this.txtNumberOfPlayers.ValueChanged += new System.EventHandler(this.txtNumberOfPlayers_ValueChanged);
			// 
			// btnDeal
			// 
			this.btnDeal.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
			this.btnDeal.BackColor = System.Drawing.Color.Gainsboro;
			this.btnDeal.Cursor = System.Windows.Forms.Cursors.Hand;
			this.btnDeal.Font = new System.Drawing.Font("Arial", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.btnDeal.ForeColor = System.Drawing.Color.Black;
			this.btnDeal.Location = new System.Drawing.Point(326, 620);
			this.btnDeal.Name = "btnDeal";
			this.btnDeal.Size = new System.Drawing.Size(79, 23);
			this.btnDeal.TabIndex = 8;
			this.btnDeal.Text = "Deal";
			this.btnDeal.Click += new System.EventHandler(this.btnDeal_Click);
			// 
			// btnSplit
			// 
			this.btnSplit.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
			this.btnSplit.BackColor = System.Drawing.Color.MediumSlateBlue;
			this.btnSplit.Cursor = System.Windows.Forms.Cursors.Hand;
			this.btnSplit.Font = new System.Drawing.Font("Arial", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.btnSplit.ForeColor = System.Drawing.Color.Black;
			this.btnSplit.Location = new System.Drawing.Point(629, 620);
			this.btnSplit.Name = "btnSplit";
			this.btnSplit.Size = new System.Drawing.Size(79, 23);
			this.btnSplit.TabIndex = 9;
			this.btnSplit.Text = "Split";
			this.btnSplit.Click += new System.EventHandler(this.btnSplit_Click);
			// 
			// btnHit
			// 
			this.btnHit.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
			this.btnHit.BackColor = System.Drawing.Color.Gold;
			this.btnHit.Cursor = System.Windows.Forms.Cursors.Hand;
			this.btnHit.Font = new System.Drawing.Font("Arial", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.btnHit.ForeColor = System.Drawing.Color.Black;
			this.btnHit.Location = new System.Drawing.Point(429, 620);
			this.btnHit.Name = "btnHit";
			this.btnHit.Size = new System.Drawing.Size(76, 23);
			this.btnHit.TabIndex = 10;
			this.btnHit.Text = "Hit";
			this.btnHit.Click += new System.EventHandler(this.btnHit_Click);
			// 
			// btnStay
			// 
			this.btnStay.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
			this.btnStay.BackColor = System.Drawing.Color.Crimson;
			this.btnStay.Cursor = System.Windows.Forms.Cursors.Hand;
			this.btnStay.Font = new System.Drawing.Font("Arial", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.btnStay.ForeColor = System.Drawing.Color.Black;
			this.btnStay.Location = new System.Drawing.Point(529, 620);
			this.btnStay.Name = "btnStay";
			this.btnStay.Size = new System.Drawing.Size(76, 23);
			this.btnStay.TabIndex = 11;
			this.btnStay.Text = "Stay";
			this.btnStay.Click += new System.EventHandler(this.btnStay_Click);
			// 
			// btnDoubleDown
			// 
			this.btnDoubleDown.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
			this.btnDoubleDown.BackColor = System.Drawing.Color.LimeGreen;
			this.btnDoubleDown.Cursor = System.Windows.Forms.Cursors.Hand;
			this.btnDoubleDown.Font = new System.Drawing.Font("Arial", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.btnDoubleDown.ForeColor = System.Drawing.Color.Black;
			this.btnDoubleDown.Location = new System.Drawing.Point(732, 620);
			this.btnDoubleDown.Name = "btnDoubleDown";
			this.btnDoubleDown.Size = new System.Drawing.Size(79, 23);
			this.btnDoubleDown.TabIndex = 12;
			this.btnDoubleDown.Text = "Dbl Down";
			this.btnDoubleDown.Click += new System.EventHandler(this.btnDoubleDown_Click);
			// 
			// tmrAutoPlay
			// 
			this.tmrAutoPlay.Tick += new System.EventHandler(this.tmrAutoPlay_Tick);
			// 
			// txtDelay
			// 
			this.txtDelay.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
			this.txtDelay.BackColor = System.Drawing.SystemColors.Control;
			this.txtDelay.BorderStyle = System.Windows.Forms.BorderStyle.None;
			this.txtDelay.CausesValidation = false;
			this.txtDelay.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.txtDelay.ForeColor = System.Drawing.SystemColors.ControlText;
			this.txtDelay.Location = new System.Drawing.Point(1083, 621);
			this.txtDelay.Minimum = new System.Decimal(new int[] {
																	 1,
																	 0,
																	 0,
																	 0});
			this.txtDelay.Name = "txtDelay";
			this.txtDelay.ReadOnly = true;
			this.txtDelay.Size = new System.Drawing.Size(48, 16);
			this.txtDelay.TabIndex = 13;
			this.txtDelay.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
			this.txtDelay.Value = new System.Decimal(new int[] {
																   1,
																   0,
																   0,
																   0});
			this.txtDelay.ValueChanged += new System.EventHandler(this.txtDelay_ValueChanged);
			// 
			// pnlStatistics
			// 
			this.pnlStatistics.Location = new System.Drawing.Point(0, 648);
			this.pnlStatistics.Name = "pnlStatistics";
			this.pnlStatistics.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
																							 this.Hands,
																							 this.Shuffles,
																							 this.NumberDecks,
																							 this.NumberPlayers,
																							 this.Interval,
																							 this.Mute,
																							 this.AutoDeal});
			this.pnlStatistics.ShowPanels = true;
			this.pnlStatistics.Size = new System.Drawing.Size(1136, 22);
			this.pnlStatistics.TabIndex = 15;
			// 
			// Hands
			// 
			this.Hands.Text = "Hands: 0";
			// 
			// Shuffles
			// 
			this.Shuffles.Text = "Shuffles: 0";
			// 
			// chkAuto
			// 
			this.chkAuto.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
			this.chkAuto.BackColor = System.Drawing.SystemColors.Control;
			this.chkAuto.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
			this.chkAuto.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.chkAuto.ForeColor = System.Drawing.Color.LemonChiffon;
			this.chkAuto.Location = new System.Drawing.Point(1112, 546);
			this.chkAuto.Name = "chkAuto";
			this.chkAuto.Size = new System.Drawing.Size(16, 16);
			this.chkAuto.TabIndex = 16;
			this.chkAuto.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// chkMute
			// 
			this.chkMute.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
			this.chkMute.BackColor = System.Drawing.SystemColors.Control;
			this.chkMute.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
			this.chkMute.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.chkMute.ForeColor = System.Drawing.Color.LemonChiffon;
			this.chkMute.Location = new System.Drawing.Point(1112, 524);
			this.chkMute.Name = "chkMute";
			this.chkMute.Size = new System.Drawing.Size(16, 16);
			this.chkMute.TabIndex = 17;
			this.chkMute.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// btnOKControls
			// 
			this.btnOKControls.BackColor = System.Drawing.Color.DarkSlateGray;
			this.btnOKControls.ForeColor = System.Drawing.Color.Gainsboro;
			this.btnOKControls.Location = new System.Drawing.Point(214, 128);
			this.btnOKControls.Name = "btnOKControls";
			this.btnOKControls.Size = new System.Drawing.Size(67, 21);
			this.btnOKControls.TabIndex = 7;
			this.btnOKControls.Text = "Ok";
			this.btnOKControls.Click += new System.EventHandler(this.btnOKControls_Click);
			// 
			// label5
			// 
			this.label5.BackColor = System.Drawing.Color.DarkSlateGray;
			this.label5.Font = new System.Drawing.Font("Caesar", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label5.ForeColor = System.Drawing.Color.Gainsboro;
			this.label5.Location = new System.Drawing.Point(9, 96);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(72, 23);
			this.label5.TabIndex = 6;
			this.label5.Text = "Method";
			this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label3
			// 
			this.label3.BackColor = System.Drawing.Color.DarkSlateGray;
			this.label3.Font = new System.Drawing.Font("Caesar", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label3.ForeColor = System.Drawing.Color.Gainsboro;
			this.label3.Location = new System.Drawing.Point(9, 64);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(72, 23);
			this.label3.TabIndex = 5;
			this.label3.Text = "Strategy";
			this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label4
			// 
			this.label4.BackColor = System.Drawing.Color.DarkSlateGray;
			this.label4.Font = new System.Drawing.Font("Caesar", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.label4.ForeColor = System.Drawing.Color.Gainsboro;
			this.label4.Location = new System.Drawing.Point(26, 32);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(56, 23);
			this.label4.TabIndex = 4;
			this.label4.Text = "Type";
			this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// cboMethod
			// 
			this.cboMethod.BackColor = System.Drawing.Color.DarkSlateGray;
			this.cboMethod.Font = new System.Drawing.Font("Caesar", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.cboMethod.ForeColor = System.Drawing.Color.Gainsboro;
			this.cboMethod.ItemHeight = 14;
			this.cboMethod.Location = new System.Drawing.Point(89, 96);
			this.cboMethod.Name = "cboMethod";
			this.cboMethod.Size = new System.Drawing.Size(195, 22);
			this.cboMethod.TabIndex = 3;
			this.cboMethod.Text = "None";
			// 
			// cboStrategy
			// 
			this.cboStrategy.BackColor = System.Drawing.Color.DarkSlateGray;
			this.cboStrategy.Font = new System.Drawing.Font("Caesar", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.cboStrategy.ForeColor = System.Drawing.Color.Gainsboro;
			this.cboStrategy.ItemHeight = 14;
			this.cboStrategy.Location = new System.Drawing.Point(89, 64);
			this.cboStrategy.Name = "cboStrategy";
			this.cboStrategy.Size = new System.Drawing.Size(195, 22);
			this.cboStrategy.TabIndex = 2;
			this.cboStrategy.Text = "None";
			// 
			// cboPlayerType
			// 
			this.cboPlayerType.BackColor = System.Drawing.Color.DarkSlateGray;
			this.cboPlayerType.Font = new System.Drawing.Font("Caesar", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.cboPlayerType.ForeColor = System.Drawing.Color.Gainsboro;
			this.cboPlayerType.ItemHeight = 14;
			this.cboPlayerType.Items.AddRange(new object[] {
															   "Human",
															   "Computer"});
			this.cboPlayerType.Location = new System.Drawing.Point(89, 32);
			this.cboPlayerType.MaxDropDownItems = 2;
			this.cboPlayerType.Name = "cboPlayerType";
			this.cboPlayerType.Size = new System.Drawing.Size(195, 22);
			this.cboPlayerType.TabIndex = 1;
			this.cboPlayerType.Text = "Human";
			// 
			// lblPlayer
			// 
			this.lblPlayer.BackColor = System.Drawing.Color.DarkSlateGray;
			this.lblPlayer.Dock = System.Windows.Forms.DockStyle.Top;
			this.lblPlayer.Font = new System.Drawing.Font("Caesar", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.lblPlayer.ForeColor = System.Drawing.Color.Gold;
			this.lblPlayer.Name = "lblPlayer";
			this.lblPlayer.Size = new System.Drawing.Size(292, 27);
			this.lblPlayer.TabIndex = 0;
			this.lblPlayer.Text = "Player 1";
			this.lblPlayer.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
			// 
			// pnlPlayerControls
			// 
			this.pnlPlayerControls.BackColor = System.Drawing.Color.DarkSlateGray;
			this.pnlPlayerControls.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.pnlPlayerControls.Controls.AddRange(new System.Windows.Forms.Control[] {
																							this.btnCancelControls,
																							this.btnOKControls,
																							this.label5,
																							this.label3,
																							this.label4,
																							this.cboMethod,
																							this.cboStrategy,
																							this.cboPlayerType,
																							this.lblPlayer});
			this.pnlPlayerControls.Location = new System.Drawing.Point(24, 8);
			this.pnlPlayerControls.Name = "pnlPlayerControls";
			this.pnlPlayerControls.Size = new System.Drawing.Size(296, 160);
			this.pnlPlayerControls.TabIndex = 18;
			this.pnlPlayerControls.Visible = false;
			// 
			// btnCancelControls
			// 
			this.btnCancelControls.BackColor = System.Drawing.Color.DarkSlateGray;
			this.btnCancelControls.ForeColor = System.Drawing.Color.Gainsboro;
			this.btnCancelControls.Location = new System.Drawing.Point(142, 128);
			this.btnCancelControls.Name = "btnCancelControls";
			this.btnCancelControls.Size = new System.Drawing.Size(67, 21);
			this.btnCancelControls.TabIndex = 8;
			this.btnCancelControls.Text = "Cancel";
			this.btnCancelControls.Click += new System.EventHandler(this.btnCancelControls_Click);
			// 
			// NumberDecks
			// 
			this.NumberDecks.MinWidth = 120;
			this.NumberDecks.Text = "Decks:";
			this.NumberDecks.Width = 120;
			// 
			// NumberPlayers
			// 
			this.NumberPlayers.MinWidth = 120;
			this.NumberPlayers.Text = "Players:";
			this.NumberPlayers.Width = 120;
			// 
			// Interval
			// 
			this.Interval.MinWidth = 120;
			this.Interval.Text = "Delay:";
			this.Interval.Width = 120;
			// 
			// Mute
			// 
			this.Mute.Text = "Mute";
			// 
			// AutoDeal
			// 
			this.AutoDeal.Text = "Auto Deal";
			// 
			// frmBlackjack
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
			this.ClientSize = new System.Drawing.Size(1136, 670);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.pnlPlayerControls,
																		  this.chkMute,
																		  this.chkAuto,
																		  this.pnlStatistics,
																		  this.txtDelay,
																		  this.btnDoubleDown,
																		  this.btnStay,
																		  this.btnHit,
																		  this.btnSplit,
																		  this.btnDeal,
																		  this.txtNumberOfPlayers,
																		  this.txtNumberOfDecks});
			this.KeyPreview = true;
			this.Name = "frmBlackjack";
			this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "Blackjack";
			this.Resize += new System.EventHandler(this.frmBlackjack_Resize);
			this.Click += new System.EventHandler(this.frmBlackjack_Click);
			this.Load += new System.EventHandler(this.frmBlackjack_Load);
			this.DoubleClick += new System.EventHandler(this.frmBlackjack_DoubleClick);
			this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.frmBlackjack_MouseUp);
			this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.frmBlackjack_KeyUp);
			this.Paint += new System.Windows.Forms.PaintEventHandler(this.frmBlackjack_Paint);
			((System.ComponentModel.ISupportInitialize)(this.txtNumberOfDecks)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.txtNumberOfPlayers)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.txtDelay)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.Hands)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.Shuffles)).EndInit();
			this.pnlPlayerControls.ResumeLayout(false);
			((System.ComponentModel.ISupportInitialize)(this.NumberDecks)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.NumberPlayers)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.Interval)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.Mute)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.AutoDeal)).EndInit();
			this.ResumeLayout(false);

		}

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new frmBlackjack());
		}
		#endregion

		private Player CurrentPlayer
		{
			get
			{ 
				if( currentPlayer >= 0 && currentPlayer <= players.GetUpperBound(0) )
					return players[currentPlayer];
				else
					return null;
			}
		}

		private void EndOfShoe(object sender, EventArgs e)
		{
			endOfShoe = true;
			//this.Refresh();
		}

		private void frmBlackjack_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			// Get the drawing surface
			Graphics drawingSurface = e.Graphics;
			// Draw smooth, anti-aliased cards.  Comment out for slow machines
			drawingSurface.SmoothingMode = SmoothingMode.AntiAlias;
			drawingSurface.InterpolationMode = InterpolationMode.HighQualityBicubic;

			// Clear the screen 
			Rectangle realClientArea = ClientRectangle;
			realClientArea.Height -= pnlStatistics.Height;
			drawingSurface.DrawImage( Resources.GetImage("table"), realClientArea );

			drawingSurface.ScaleTransform(realClientArea.Width/1140.0F, realClientArea.Height/648.0F);

			// Draw the background for the active player
			if( CurrentPlayer != null && dealer.Hand.Count > 0 )
				CurrentPlayer.DrawBackground( drawingSurface, dealer.Hand[1] );

			// If the form has been initialized, there will be a shoe
			if( shoe != null )
			{
				// Draw the dealer's hand
				dealer.DrawHand( drawingSurface, showDealerDownCard );

				foreach( Player player in players )
				{
					// Draw the player's hand
					player.DrawHands( drawingSurface, labelType, dealer.Hand, player==CurrentPlayer );
				}
			}

			// Draw the marker to indicate the next hand will be preceded with a shuffle
			if( endOfShoe )
				drawingSurface.DrawImage( Resources.GetImage("marker"), 840, 24);

			drawingSurface.ResetTransform();
		}

		private void btnDeal_Click(object sender, System.EventArgs e)
		{
			// Keep track of statistics
			deals++;

			// Reset the form for play
			txtNumberOfPlayers.Enabled = false;
			txtNumberOfDecks.Enabled = false;
			btnDeal.Enabled = false;

			// Reset the players
			foreach( Player player in players )
			{
				player.Reset();
			}
			
			// Reset the dealer
			showDealerDownCard = false;
			dealer.Reset();

			// Shuffle if we need to
			if( shoe.Eod )
			{
				endOfShoe = false;

				// This clears the screen so it looks like the dealer picked up all the cards
				this.Refresh();

				// Then shuffle the deck
				Shuffle( true );
			}

			// Get the recommended wager from the counting system
			foreach( Player player in players )
			{
				player.GetWager();
			}

			// Set the label type to draw all labels
			labelType = Player.LabelType.bothHands;

			// Clear the screen
			currentPlayer = 0;

			// Update statistics
			pnlStatistics.Panels[0].Text = "Hands: " + deals.ToString(CultureInfo.InvariantCulture);
			pnlStatistics.Panels[1].Text = "Shuffles: " + shuffles.ToString(CultureInfo.InvariantCulture);

			Card newCard = null;
			Card dealerCard = null;

			// Deal the cards
			for( int k=0; k<2; k++ )
			{
				foreach( Player player in players )
				{
					// Get a card
					newCard = shoe.Next();
					// Put it in the player's hand
					player.GetHands()[0].Add( newCard );
					// And give all players the opportunity to count it
					CountCard( newCard );
					// Then update the screen so the new card shows up
					this.Refresh();
				}
				// Now give the dealer a card
				dealerCard = shoe.Next();
				dealer.Hand.Add( dealerCard );
				// And if it is the up card, give the players the opportunity to count it
				if( k == 1 )
					CountCard( newCard );
				this.Refresh();
			}
 
			// If dealer has Blackjack, everybody loses unless they also have Blackjack
			if( dealer.Hand.IsBlackjack() )
			{
				// Dealer blackjack
				labelType = Player.LabelType.outcome;
				currentPlayer = players.GetUpperBound(0) + 1;

				// Show down card
				showDealerDownCard = true;
				// Let everyone count it
				this.Refresh();

				// Let the players count it if they want to
				CountCard( dealer.Hand[0] );

				// Take the money from everybody unless they have Blackjack
				foreach( Player player in players )
				{
					foreach( Hand hand in player.GetHands() )
					{
						if( hand.Count > 0 && hand.Total() == 21 )
							// If the player also had Blackjack, Push
							player.Push( hand );
					}
					player.Bet.Visible = true;
				}
				this.Refresh();

				// Reset the form for entry
				txtNumberOfPlayers.Enabled = true;
				txtNumberOfDecks.Enabled = true;
				btnDeal.Enabled = true;

				// For auto deal, just click the deal button for them
				if( chkAuto.Checked )
					btnDeal_Click( sender, e );
			}
			else
			{
				// Loop through the players until we find one that doesn't have 21
				int handTotal = 0;
				do
				{
					handTotal = CurrentPlayer.CurrentHand.Total();
					if( handTotal == 21 )
						NextPlayer();
				} while ( handTotal == 21 && currentPlayer <= players.GetUpperBound(0) );
			
				// Turn on the timer for the computer controlled players
				tmrAutoPlay.Enabled = true;
			}
								
			// The next deal will begin with a shuffle, tell the players
			// to reset their card count now so the suggested bet for human
			// players is accurate.
			if( shoe.Eod )
			{
				foreach( Player player in players )
				{
					player.ResetCount( (int)txtNumberOfDecks.Value );
				}
			}

		}

		private void ShuffleShoe(object sender, EventArgs e)
		{
			endOfShoe = false;
		}

		private void btnSplit_Click(object sender, System.EventArgs e)
		{
			// Make sure we're working with a player and not the dealer
			if( currentPlayer >=0 && currentPlayer <= players.GetUpperBound(0) )
			{
				// See if the player is able to split
				if( CurrentPlayer.Split() )
				{
					// Invalidate everything so that the split hands show up clean
					this.Refresh();

					// Splitting aces is a special case...
					if( CurrentPlayer.CurrentHand[0].FaceValue == Card.CardType.Ace )
					{
						// Player only gets one more card for each hand
						NextCard();
						NextHand();

						// Then move on to the next player
						NextPlayer();
					}
					else
					{
						// Normal split, deal another card to the current hand
						labelType = Player.LabelType.drawToHand;
						NextCard();

						// If they hit 21, move to the next hand automatically
						if( CurrentPlayer.CurrentHand.Total() == 21 )
						{
							NextHand();

							// And if that hand has 21, move to the next player
							if( CurrentPlayer.CurrentHand.Total() == 21 )
								NextPlayer();
						}
					}
				}
			}
		}

		private void btnHit_Click(object sender, System.EventArgs e)
		{
			// Make sure we're working with a player and not the dealer
			if( currentPlayer >=0 && currentPlayer <= players.GetUpperBound(0) )
			{
				int handTotal = 0;

				// Give them another card
				NextCard();
				
				do
				{
					// Now loop until we find a player that hasn't busted or dealt 21
					handTotal = CurrentPlayer.CurrentHand.Total();
					if( handTotal >= 21 )
					{						
						if( CurrentPlayer.LastHand() )
						{
							// Move to the next player
							NextPlayer();

							// and get their total so the loop can continue if need be
							if( currentPlayer <= players.GetUpperBound(0) )
								handTotal = CurrentPlayer.CurrentHand.Total();
						}
						else
						{
							// The player has split, move to the next hand
							NextHand();

							// Get the hand total so the loop can continue if need be
							handTotal = CurrentPlayer.CurrentHand.Total();
						}
					}
				} while ( handTotal >= 21 && currentPlayer <= players.GetUpperBound(0) );
			}
		}

		private void btnStay_Click(object sender, System.EventArgs e)
		{
			int handTotal = 0;

			// Make sure we're working with a player and not the dealer
			if( currentPlayer >=0 && currentPlayer <= players.GetUpperBound(0) )
			{
				if( CurrentPlayer.LastHand() )
					NextPlayer();
				else
					// If the player has split, move to the next hand...
					NextHand();

				// Make sure we didn't skip past the last player above
				if( currentPlayer <= players.GetUpperBound(0) )
				{
					do
					{
						// Now loop until we find a player that hasn't busted or dealt 21
						handTotal = CurrentPlayer.CurrentHand.Total();
						if( handTotal >= 21 )
						{						
							if( CurrentPlayer.LastHand() )
							{
								// Move to the next player
								NextPlayer();

								// and get their total so the loop can continue if need be
								if( currentPlayer <= players.GetUpperBound(0) )
									handTotal = CurrentPlayer.CurrentHand.Total();
							}
							else
							{
								// The player has split, move to the next hand
								NextHand();

								// Get the hand total so the loop can continue if need be
								handTotal = CurrentPlayer.CurrentHand.Total();
							}
						}
					} while ( handTotal >= 21 && currentPlayer <= players.GetUpperBound(0) );
				}
			}
		}

		private void frmBlackjack_Load(object sender, System.EventArgs e)
		{
			// Load the strategies and methods into the list boxes
			ArrayList strategies = Strategy.GetStrategies();
			ArrayList methods = CountMethod.GetMethods();

			System.Collections.IEnumerator myEnumerator = strategies.GetEnumerator();
			cboStrategy.Items.Add( "None" );
			while ( myEnumerator.MoveNext() )
			{
				cboStrategy.Items.Add( myEnumerator.Current );
			}

			cboMethod.Items.Add( "None" );
			myEnumerator = methods.GetEnumerator();
			while ( myEnumerator.MoveNext() )
			{
				cboMethod.Items.Add( myEnumerator.Current );
			}

			// Move the controls onto the panel.  This must be done at run time.
			pnlStatistics.Controls.Add( txtNumberOfDecks );
			txtNumberOfDecks.Left = pnlStatistics.Panels[0].Width + pnlStatistics.Panels[1].Width + pnlStatistics.Panels[2].Width - txtNumberOfDecks.Width - 10  ;
			txtNumberOfDecks.Top = (pnlStatistics.Height - txtNumberOfDecks.Height)/2;
			pnlStatistics.Controls.Add( txtNumberOfPlayers );
			txtNumberOfPlayers.Left = pnlStatistics.Panels[0].Width + pnlStatistics.Panels[1].Width + pnlStatistics.Panels[2].Width + pnlStatistics.Panels[3].Width - txtNumberOfPlayers.Width - 10  ;
			txtNumberOfPlayers.Top = txtNumberOfDecks.Top;
			pnlStatistics.Controls.Add( txtDelay );
			txtDelay.Left = pnlStatistics.Panels[0].Width + pnlStatistics.Panels[1].Width + pnlStatistics.Panels[2].Width + pnlStatistics.Panels[3].Width + pnlStatistics.Panels[4].Width - txtDelay.Width - 10  ;
			txtDelay.Top = txtNumberOfDecks.Top;
			pnlStatistics.Controls.Add( chkMute );
			chkMute.Left = pnlStatistics.Panels[0].Width + pnlStatistics.Panels[1].Width + pnlStatistics.Panels[2].Width + pnlStatistics.Panels[3].Width + pnlStatistics.Panels[4].Width + pnlStatistics.Panels[5].Width - chkMute.Width - 10  ;
			chkMute.Top = (pnlStatistics.Height - chkMute.Height)/2;
			pnlStatistics.Controls.Add( chkAuto );
			chkAuto.Left = pnlStatistics.Panels[0].Width + pnlStatistics.Panels[1].Width + pnlStatistics.Panels[2].Width + pnlStatistics.Panels[3].Width + pnlStatistics.Panels[4].Width + pnlStatistics.Panels[5].Width + pnlStatistics.Panels[6].Width - chkAuto.Width - 10  ;
			chkAuto.Top = chkMute.Top;

			// Create a dealer
			dealer = new Dealer(new Point(530, 120));
			
			// Initialize the shoe and the players
			txtNumberOfDecks_ValueChanged(sender, e);
			txtNumberOfPlayers_ValueChanged(sender, e);
			txtDelay_ValueChanged(sender, e);
		}

		private void txtNumberOfDecks_ValueChanged(object sender, System.EventArgs e)
		{
			// Initialize the shoe
			shoe.NumberOfDecks = (int)txtNumberOfDecks.Value;
			shoe.Init();
			Shuffle( false );
		}

		private void txtNumberOfPlayers_ValueChanged(object sender, System.EventArgs e)
		{
			players = new Player[(int)txtNumberOfPlayers.Value];
			GC.Collect();

			for( int i = 0; i < (int)txtNumberOfPlayers.Value; i++ )
			{
				NumericUpDown plyrBet = null;
				switch(i)
				{
					case 0:  // PLAYER 1
						plyrBet = CreateBetControl(1, new Point(955,299));
						players[i] = new Player( new Point(961,299), "player1_back", 5000.00, plyrBet, Player.playerType.human, new HighLowMultiDeck(), new HighLow( (int)txtNumberOfDecks.Value ) );
						break;
					case 1:  // PLAYER 2
						plyrBet = CreateBetControl(2, new Point(769,428));
						players[i] = new Player( new Point(769,428), "player2_back", 5000.00, plyrBet, Player.playerType.computer, new HighLowMultiDeck(), new HighLow( (int)txtNumberOfDecks.Value ) );
						break;
					case 2:  // PLAYER 3
						plyrBet = CreateBetControl(3, new Point(500,476));
						players[i] = new Player( new Point(500,476), "player3_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new CanfieldExpert( (int)txtNumberOfDecks.Value ) );
						break;
					case 3:  // PLAYER 4
						plyrBet = CreateBetControl(4, new Point(243,430));
						players[i] = new Player( new Point(243,430), "player4_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new CanfieldMaster( (int)txtNumberOfDecks.Value ) );
						break;
					case 4:  // PLAYER 5
						plyrBet = CreateBetControl(5, new Point(76,319));
						players[i] = new Player( new Point(76,319), "player5_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new KO( (int)txtNumberOfDecks.Value ) );
						break;
				}
			}
			this.Refresh();
		}

		private NumericUpDown CreateBetControl( int playerNumber, Point location )
		{
			NumericUpDown playerBet = new NumericUpDown();
			playerBet.Maximum = 50000;
			playerBet.Increment = 10;
			playerBet.Text = "100";
			playerBet.BorderStyle = BorderStyle.None;
			playerBet.ForeColor = Color.DarkKhaki;
			playerBet.BackColor = Color.FromArgb(2,98,87);
			playerBet.Font = new Font("Arial",8,FontStyle.Bold);
			playerBet.Size = new Size(56,22);
			playerBet.Left = location.X + 110;
			playerBet.Top = location.Y - 20;
			playerBet.Name = "Player" + playerNumber.ToString(CultureInfo.InvariantCulture) + "Bet";
			this.Controls.Add( playerBet );

			return playerBet;
		}

		private void btnDoubleDown_Click(object sender, System.EventArgs e)
		{
			// Make sure we're working with a player and not the dealer
			if( currentPlayer >=0 && currentPlayer <= players.GetUpperBound(0) )
			{
				if( CurrentPlayer.DoubleDown( CurrentPlayer.CurrentHand ))
				{
					// Deal one more card
					NextCard();
	
					if( CurrentPlayer.LastHand() )
						// Move to the next player...
						NextPlayer();
					else
						// or next hand if the player split
						NextHand();
				}
			}
		}

		private void NextCard()
		{
			// Get the next card
			Card newCard = shoe.Next();

			// Tell each of the players what the card is 
			CountCard( newCard );

			// Add a card to the player's hand
			CurrentPlayer.CurrentHand.Add(newCard);

			// and show it.
			this.Refresh();
		}

		private void NextHand()
		{
			// Advance to the player's next hand (for splits only)
			CurrentPlayer.NextHand();

			// They always get another card on a new, split hand
			NextCard();
		}

		private void NextPlayer()
		{
			// Make sure both of the current players hands are visible and have labels
			labelType = Player.LabelType.bothHands;

			do
			{
				currentPlayer++;
				this.Refresh();

				// Dealer's turn
				if( CurrentPlayer == null )
				{
					// Shut off the timer
					tmrAutoPlay.Enabled = false;

					// Tell the dealer to show his down card
					showDealerDownCard = true;

					// Update the screen so we can see it
					this.Refresh();

					// Let the players count it if they want to
					CountCard( dealer.Hand[0] );

					// Only hit to the dealer if someone didn't bust
					bool hitToDealer = false;

					foreach( Player player in players )
					{
						foreach( Hand hand in player.GetHands() )
						{
							if( hand.Total() > 0 && hand.Total() <= 21 && !hand.IsBlackjack() )
							{
								hitToDealer = true;
								break;
							}
						}
					}

					if( hitToDealer )
					{
						while( dealer.Total() < 17)
						{
							Card dealerCard = shoe.Next();
							dealer.AddCard( dealerCard );
							this.Refresh();

							// Give each player the opportunity to count the card
							CountCard( dealerCard );
						}
					}

					labelType = Player.LabelType.outcome;

					foreach( Player player in players )
					{
						foreach( Hand hand in player.GetHands() )
						{
							switch( hand.Outcome( dealer.Hand, player.NumberOfHands ))
							{
								case Hand.OutcomeType.Won:
									player.Won( hand );
									break;
								case Hand.OutcomeType.Lost:
									// Do nothing, the money was taken at the beginning of play
									break;
								case Hand.OutcomeType.Push:
									player.Push( hand );
									break;
								case Hand.OutcomeType.Blackjack:
									player.Blackjack( hand );
									break;
								default:
									// Hand not in play
									break;
							}
						}
						player.Bet.Visible = true;
					}

					// Reset the form for entry
					txtNumberOfPlayers.Enabled = true;
					txtNumberOfDecks.Enabled = true;
					btnDeal.Enabled = true;
					
					// The next deal will begin with a shuffle, tell the players
					// to reset their card count now so the suggested bet for human
					// players is accurate.
					if( shoe.Eod )
					{
						foreach( Player player in players )
						{
							player.ResetCount( (int)txtNumberOfDecks.Value );
						}
					}

					this.Refresh();

					if( chkAuto.Checked )
						btnDeal_Click( null, null );
				}

			} while ( currentPlayer <= players.GetUpperBound(0) && CurrentPlayer.CurrentHand.Total() >= 21 );

		}

		private void tmrAutoPlay_Tick(object sender, System.EventArgs e)
		{
			Strategy.AdviceType advice = Strategy.AdviceType.None;

			if( currentPlayer <= players.GetUpperBound(0) )
			{
				if( CurrentPlayer.Type == Player.playerType.computer )
				{
					advice = CurrentPlayer.GetAdvice( dealer.Hand[1] );
					switch( advice )
					{
						case Strategy.AdviceType.Hit:
							btnHit_Click( sender, e );
							break;
						case Strategy.AdviceType.DoubleDown:
							btnDoubleDown_Click( sender, e);
							break;
						case Strategy.AdviceType.Split:
							btnSplit_Click( sender, e );
							break;
						case Strategy.AdviceType.Stand:
							btnStay_Click( sender, e );
							break;
						default:
							break;
					}
				}
			}
		}

		private void txtDelay_ValueChanged(object sender, System.EventArgs e)
		{
			tmrAutoPlay.Interval = (int)txtDelay.Value * 100;
		}

		private void CountCard( Card newCard )
		{
			// Tell each of the players what the new card is
			// so they can count it if they want to.
			foreach( Player player in players )
			{
				player.CountCard( newCard );
			}
		}

		private void Shuffle( bool playSound )
		{
			// Play a shuffle sound
			if( playSound && !chkMute.Checked )
				Sound.PlayAudioSync("shuffle.wav");

			shoe.Shuffle();
			shuffles++;

			// We need to tell each of the players we are shuffling in 
			// case they are counting cards.
			foreach( Player player in players )
			{
				player.ResetCount( (int)txtNumberOfDecks.Value );
			}

		}

		private void btnOKControls_Click(object sender, System.EventArgs e)
		{
			players[playerNumber].Method = CountMethod.NewMethod( cboMethod.Text, (int)txtNumberOfDecks.Value );
			players[playerNumber].CardStrategy = Strategy.NewStrategy( cboStrategy.Text );
			players[playerNumber].Type = cboPlayerType.Text == "Computer" ? Player.playerType.computer : Player.playerType.human;
			pnlPlayerControls.Visible = false;
		}

		private void btnCancelControls_Click(object sender, System.EventArgs e)
		{
			pnlPlayerControls.Visible = false;
		}

		private void frmBlackjack_DoubleClick(object sender, System.EventArgs e)
		{
			Size clickArea = new Size((int)(88*scaleX),(int)(64*scaleY));

			Rectangle player1 = new Rectangle(new Point((int)(984*scaleX),(int)(320*scaleY)), clickArea);
			Rectangle player2 = new Rectangle(new Point((int)(795*scaleX),(int)(450*scaleY)), clickArea);
			Rectangle player3 = new Rectangle(new Point((int)(520*scaleX),(int)(504*scaleY)), clickArea);
			Rectangle player4 = new Rectangle(new Point((int)(264*scaleX),(int)(456*scaleY)), clickArea);
			Rectangle player5 = new Rectangle(new Point((int)(104*scaleX),(int)(336*scaleY)), clickArea);

			if( player1.Contains( mouseLocation ))
			{
				lblPlayer.Text = "Player 1";
				pnlPlayerControls.Top = mouseLocation.Y - pnlPlayerControls.Height;
				pnlPlayerControls.Left = mouseLocation.X - pnlPlayerControls.Width;
				cboStrategy.Text = players[0].CardStrategy != null ? players[0].CardStrategy.StrategyName : "None";
				cboMethod.Text = players[0].Method != null ? players[0].Method.MethodName : "None";
				cboPlayerType.Text = players[0].Type == Player.playerType.computer ? "Computer" : "Human";
				playerNumber = 0;
				pnlPlayerControls.Visible = true;
			}
			else if( player2.Contains( mouseLocation ) && (int)txtNumberOfPlayers.Value > 1 )
			{
				lblPlayer.Text = "Player 2";
				pnlPlayerControls.Top = mouseLocation.Y - pnlPlayerControls.Height;
				pnlPlayerControls.Left = mouseLocation.X - pnlPlayerControls.Width;
				cboStrategy.Text = players[1].CardStrategy != null ? players[1].CardStrategy.StrategyName : "None";
				cboMethod.Text = players[1].Method != null ? players[1].Method.MethodName : "None";
				cboPlayerType.Text = players[1].Type == Player.playerType.computer ? "Computer" : "Human";
				playerNumber = 1;
				pnlPlayerControls.Visible = true;
			}
			else if( player3.Contains( mouseLocation ) && (int)txtNumberOfPlayers.Value > 2 )
			{
				lblPlayer.Text = "Player 3";
				pnlPlayerControls.Top = mouseLocation.Y - pnlPlayerControls.Height;
				pnlPlayerControls.Left = mouseLocation.X - pnlPlayerControls.Width/2;
				cboStrategy.Text = players[2].CardStrategy != null ? players[2].CardStrategy.StrategyName : "None";
				cboMethod.Text = players[2].Method != null ? players[2].Method.MethodName : "None";
				cboPlayerType.Text = players[2].Type == Player.playerType.computer ? "Computer" : "Human";
				playerNumber = 2;
				pnlPlayerControls.Visible = true;
			}
			else if( player4.Contains( mouseLocation ) && (int)txtNumberOfPlayers.Value > 3 )
			{
				lblPlayer.Text = "Player 4";
				pnlPlayerControls.Top = mouseLocation.Y - pnlPlayerControls.Height;
				pnlPlayerControls.Left = mouseLocation.X;
				cboStrategy.Text = players[3].CardStrategy != null ? players[3].CardStrategy.StrategyName : "None";
				cboMethod.Text = players[3].Method != null ? players[3].Method.MethodName : "None";
				cboPlayerType.Text = players[3].Type == Player.playerType.computer ? "Computer" : "Human";
				playerNumber = 3;
				pnlPlayerControls.Visible = true;
			}
			else if( player5.Contains( mouseLocation ) && (int)txtNumberOfPlayers.Value > 4 )
			{
				lblPlayer.Text = "Player 5";
				pnlPlayerControls.Top = mouseLocation.Y - pnlPlayerControls.Height;
				pnlPlayerControls.Left = mouseLocation.X;
				cboStrategy.Text = players[4].CardStrategy != null ? players[4].CardStrategy.StrategyName : "None";
				cboMethod.Text = players[4].Method != null ? players[4].Method.MethodName : "None";
				cboPlayerType.Text = players[4].Type == Player.playerType.computer ? "Computer" : "Human";
				playerNumber = 4;
				pnlPlayerControls.Visible = true;
			}
		}

		private void frmBlackjack_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			mouseLocation.X = e.X;
			mouseLocation.Y = e.Y;
		}

		private void frmBlackjack_Click(object sender, System.EventArgs e)
		{
			pnlPlayerControls.Visible = false;
		}

		private void frmBlackjack_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			this.Focus();

			switch( e.KeyCode )
			{
				case Keys.D:
					if( btnDeal.Enabled )
						btnDeal_Click(sender, e);
					break;
				case Keys.S:
					if( btnStay.Enabled )
						btnStay_Click(sender, e);
					break;
				case Keys.H:
					if( btnHit.Enabled )
						btnHit_Click(sender, e);
					break;
				case Keys.B:
					if( btnDoubleDown.Enabled )
						btnDoubleDown_Click(sender,
							e);
					break;
				case Keys.P:
					if( btnSplit.Enabled )
						btnSplit_Click(sender, e);
					break;
			}
		}

		private void frmBlackjack_Resize(object sender, System.EventArgs e)
		{
			Rectangle realClientArea = ClientRectangle;
			realClientArea.Height -= pnlStatistics.Height;
			scaleX = realClientArea.Width/1140.0F;
			scaleY = realClientArea.Height/648.0F;

			foreach( Player player in players )
			{
				player.MoveControls( scaleX, scaleY );
			}

			this.Refresh();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I'm a software engineer and consultant working in San Diego, California. I began using .NET during the early alpha releases since I worked for a Microsoft subsidiary then, and now I've focused my career on .NET technologies.

There are a lot of .NET sites out there now, but The Code Project is still top of the heap.

Comments and Discussions