using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Windows.Forms;
using System.Threading;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml;
using ImageControls;
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>
[Serializable()]
public class Blackjack : System.Windows.Forms.Form
{
#region FormControls
private System.Windows.Forms.NumericUpDown txtNumberOfDecks;
private System.Windows.Forms.NumericUpDown txtNumberOfPlayers;
private System.Windows.Forms.StatusBarPanel CardBack;
private System.Windows.Forms.NumericUpDown txtCardBack;
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.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;
private System.Windows.Forms.Timer tmrInsurance;
private System.Windows.Forms.ContextMenu mnuPopup;
private System.Windows.Forms.MenuItem mnuStrategyWindow;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem mnuShowBank;
private System.Windows.Forms.MenuItem mnuShowCardCount;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem mnuStrategy;
private System.Windows.Forms.MenuItem mnuMethod;
private System.Windows.Forms.MenuItem mnuPlayerType;
private System.Windows.Forms.MenuItem mnuShowCardTotal;
private ImageControls.ImageButton btnDeal;
private ImageControls.ImageButton btnHit;
private ImageControls.ImageButton btnStay;
private ImageControls.ImageButton btnSplit;
private ImageControls.ImageButton btnInsurance;
private ImageControls.ImageButton btnNoInsurance;
private ImageControls.ImageButton btnDoubleDown;
private System.Windows.Forms.ImageList imlButtons;
#endregion
#region FormVariables
// 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;
// Indicates we are in insurance mode
private bool insurance = false;
// This one is used by the timer to flash the highlight
private bool showInsurance = false;
// This keeps track of how many times we've flashed the insurance highlight
private int tickCount = 0;
// 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
private int playerNumber;
// Boolean indicates end of shoe. It is set via event from the shoe
private bool endOfShoe;
// Scaling variables to make resizing faster and easier
private float scaleX = 1.0F;
private float scaleY = 1.0F;
// This form is used to display the strategy for each player;
StrategyForm strategyForm = new StrategyForm();
// This keeps track of whether we've hidden the form while minimized
private bool strategyFormMinimized;
// Preload the background image on form_load for speed. Store it here.
private Bitmap backgroundImage;
private System.Windows.Forms.Timer tmrAutoDeal;
// This tells the paint routine that we're dealing so the advice doesn't get shown
// until we know if this is an insurance round or not.
bool dealing = false;
#endregion
#region Windows Form Designer generated code
public Blackjack()
{
//
// 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);
shoe.BackChangedEvent += new Shoe.ShoeEventHandler(BackChanged);
}
/// <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();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Blackjack));
this.txtNumberOfDecks = new System.Windows.Forms.NumericUpDown();
this.txtNumberOfPlayers = new System.Windows.Forms.NumericUpDown();
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.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();
this.CardBack = new System.Windows.Forms.StatusBarPanel();
this.chkAuto = new System.Windows.Forms.CheckBox();
this.chkMute = new System.Windows.Forms.CheckBox();
this.txtCardBack = new System.Windows.Forms.NumericUpDown();
this.tmrInsurance = new System.Windows.Forms.Timer(this.components);
this.mnuPopup = new System.Windows.Forms.ContextMenu();
this.mnuStrategyWindow = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.mnuShowBank = new System.Windows.Forms.MenuItem();
this.mnuShowCardCount = new System.Windows.Forms.MenuItem();
this.mnuShowCardTotal = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
this.mnuPlayerType = new System.Windows.Forms.MenuItem();
this.mnuStrategy = new System.Windows.Forms.MenuItem();
this.mnuMethod = new System.Windows.Forms.MenuItem();
this.btnDeal = new ImageControls.ImageButton();
this.imlButtons = new System.Windows.Forms.ImageList(this.components);
this.btnHit = new ImageControls.ImageButton();
this.btnStay = new ImageControls.ImageButton();
this.btnSplit = new ImageControls.ImageButton();
this.btnDoubleDown = new ImageControls.ImageButton();
this.btnInsurance = new ImageControls.ImageButton();
this.btnNoInsurance = new ImageControls.ImageButton();
this.tmrAutoDeal = new System.Windows.Forms.Timer(this.components);
((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();
((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();
((System.ComponentModel.ISupportInitialize)(this.CardBack)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.txtCardBack)).BeginInit();
this.SuspendLayout();
//
// txtNumberOfDecks
//
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(902, 497);
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(40, 13);
this.txtNumberOfDecks.TabIndex = 2;
this.txtNumberOfDecks.TabStop = false;
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.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(902, 517);
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(40, 13);
this.txtNumberOfPlayers.TabIndex = 6;
this.txtNumberOfPlayers.TabStop = false;
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);
//
// tmrAutoPlay
//
this.tmrAutoPlay.Enabled = true;
this.tmrAutoPlay.Tick += new System.EventHandler(this.tmrAutoPlay_Tick);
//
// txtDelay
//
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(902, 538);
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(40, 13);
this.txtDelay.TabIndex = 13;
this.txtDelay.TabStop = false;
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, 561);
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.CardBack});
this.pnlStatistics.ShowPanels = true;
this.pnlStatistics.Size = new System.Drawing.Size(946, 19);
this.pnlStatistics.TabIndex = 15;
//
// Hands
//
this.Hands.MinWidth = 100;
this.Hands.Text = "Hands: 0";
//
// Shuffles
//
this.Shuffles.MinWidth = 100;
this.Shuffles.Text = "Shuffles: 0";
//
// 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.ToolTipText = "Changes the speed of play";
this.Interval.Width = 120;
//
// Mute
//
this.Mute.MinWidth = 100;
this.Mute.Text = "Mute";
this.Mute.ToolTipText = "Turns off shuffle and other sound effects";
//
// AutoDeal
//
this.AutoDeal.MinWidth = 100;
this.AutoDeal.Text = "Auto Deal";
this.AutoDeal.ToolTipText = "Automatically deals each hand without user intervention";
//
// CardBack
//
this.CardBack.MinWidth = 120;
this.CardBack.Text = "Card Back";
this.CardBack.ToolTipText = "Select different images for the back of the cards";
this.CardBack.Width = 120;
//
// chkAuto
//
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(927, 473);
this.chkAuto.Name = "chkAuto";
this.chkAuto.Size = new System.Drawing.Size(13, 14);
this.chkAuto.TabIndex = 16;
this.chkAuto.TabStop = false;
this.chkAuto.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// chkMute
//
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(927, 454);
this.chkMute.Name = "chkMute";
this.chkMute.Size = new System.Drawing.Size(13, 14);
this.chkMute.TabIndex = 17;
this.chkMute.TabStop = false;
this.chkMute.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// txtCardBack
//
this.txtCardBack.BackColor = System.Drawing.SystemColors.Control;
this.txtCardBack.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txtCardBack.CausesValidation = false;
this.txtCardBack.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.txtCardBack.ForeColor = System.Drawing.SystemColors.ControlText;
this.txtCardBack.Location = new System.Drawing.Point(720, 541);
this.txtCardBack.Maximum = new System.Decimal(new int[] {
66,
0,
0,
0});
this.txtCardBack.Minimum = new System.Decimal(new int[] {
53,
0,
0,
0});
this.txtCardBack.Name = "txtCardBack";
this.txtCardBack.ReadOnly = true;
this.txtCardBack.Size = new System.Drawing.Size(13, 13);
this.txtCardBack.TabIndex = 19;
this.txtCardBack.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtCardBack.Value = new System.Decimal(new int[] {
66,
0,
0,
0});
this.txtCardBack.ValueChanged += new System.EventHandler(this.txtCardBack_ValueChanged);
//
// tmrInsurance
//
this.tmrInsurance.Interval = 300;
this.tmrInsurance.Tick += new System.EventHandler(this.tmrInsurance_Tick);
//
// mnuPopup
//
this.mnuPopup.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuStrategyWindow,
this.menuItem1,
this.mnuShowBank,
this.mnuShowCardCount,
this.mnuShowCardTotal,
this.menuItem4,
this.mnuPlayerType,
this.mnuStrategy,
this.mnuMethod});
//
// mnuStrategyWindow
//
this.mnuStrategyWindow.Index = 0;
this.mnuStrategyWindow.Text = "Show Strategy Window";
this.mnuStrategyWindow.Click += new System.EventHandler(this.mnuShowStrategy_Click);
//
// menuItem1
//
this.menuItem1.Index = 1;
this.menuItem1.Text = "-";
//
// mnuShowBank
//
this.mnuShowBank.Index = 2;
this.mnuShowBank.Text = "Show Bank";
this.mnuShowBank.Click += new System.EventHandler(this.mnuShowBank_Click);
//
// mnuShowCardCount
//
this.mnuShowCardCount.Index = 3;
this.mnuShowCardCount.Text = "Show Card Count";
this.mnuShowCardCount.Click += new System.EventHandler(this.mnuShowCardCount_Click);
//
// mnuShowCardTotal
//
this.mnuShowCardTotal.Index = 4;
this.mnuShowCardTotal.Text = "Show Card Total";
this.mnuShowCardTotal.Click += new System.EventHandler(this.mnuShowCardTotal_Click);
//
// menuItem4
//
this.menuItem4.Index = 5;
this.menuItem4.Text = "-";
//
// mnuPlayerType
//
this.mnuPlayerType.Index = 6;
this.mnuPlayerType.Text = "Computer Player";
this.mnuPlayerType.Click += new System.EventHandler(this.mnuPlayerType_Click);
//
// mnuStrategy
//
this.mnuStrategy.Index = 7;
this.mnuStrategy.Text = "Strategy";
//
// mnuMethod
//
this.mnuMethod.Index = 8;
this.mnuMethod.Text = "Method";
//
// btnDeal
//
this.btnDeal.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnDeal.AutoSize = true;
this.btnDeal.BackColor = System.Drawing.Color.White;
this.btnDeal.ImageIndexDisabled = 3;
this.btnDeal.ImageIndexHover = 2;
this.btnDeal.ImageIndexNormal = 0;
this.btnDeal.ImageIndexPressed = 1;
this.btnDeal.ImageList = this.imlButtons;
this.btnDeal.Location = new System.Drawing.Point(198, 527);
this.btnDeal.Name = "btnDeal";
this.btnDeal.Pulse = true;
this.btnDeal.Size = new System.Drawing.Size(106, 30);
this.btnDeal.StopPulsingAfterClick = true;
this.btnDeal.TabIndex = 20;
this.btnDeal.Text = "&Deal";
this.btnDeal.Click += new System.EventHandler(this.btnDeal_Click);
//
// imlButtons
//
this.imlButtons.ImageSize = new System.Drawing.Size(106, 30);
this.imlButtons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlButtons.ImageStream")));
this.imlButtons.TransparentColor = System.Drawing.Color.Transparent;
//
// btnHit
//
this.btnHit.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnHit.AutoSize = true;
this.btnHit.BackColor = System.Drawing.Color.White;
this.btnHit.Enabled = false;
this.btnHit.ImageIndexDisabled = 7;
this.btnHit.ImageIndexHover = 6;
this.btnHit.ImageIndexNormal = 4;
this.btnHit.ImageIndexPressed = 5;
this.btnHit.ImageList = this.imlButtons;
this.btnHit.Location = new System.Drawing.Point(309, 527);
this.btnHit.Name = "btnHit";
this.btnHit.Size = new System.Drawing.Size(106, 30);
this.btnHit.StopPulsingAfterClick = true;
this.btnHit.TabIndex = 21;
this.btnHit.Text = "&Hit";
this.btnHit.Click += new System.EventHandler(this.btnHit_Click);
//
// btnStay
//
this.btnStay.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnStay.AutoSize = true;
this.btnStay.BackColor = System.Drawing.Color.White;
this.btnStay.Enabled = false;
this.btnStay.ImageIndexDisabled = 11;
this.btnStay.ImageIndexHover = 10;
this.btnStay.ImageIndexNormal = 8;
this.btnStay.ImageIndexPressed = 9;
this.btnStay.ImageList = this.imlButtons;
this.btnStay.Location = new System.Drawing.Point(420, 527);
this.btnStay.Name = "btnStay";
this.btnStay.Size = new System.Drawing.Size(106, 30);
this.btnStay.StopPulsingAfterClick = true;
this.btnStay.TabIndex = 22;
this.btnStay.Text = "&Stand";
this.btnStay.Click += new System.EventHandler(this.btnStay_Click);
//
// btnSplit
//
this.btnSplit.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnSplit.AutoSize = true;
this.btnSplit.BackColor = System.Drawing.Color.White;
this.btnSplit.Enabled = false;
this.btnSplit.ImageIndexDisabled = 15;
this.btnSplit.ImageIndexHover = 14;
this.btnSplit.ImageIndexNormal = 12;
this.btnSplit.ImageIndexPressed = 13;
this.btnSplit.ImageList = this.imlButtons;
this.btnSplit.Location = new System.Drawing.Point(531, 527);
this.btnSplit.Name = "btnSplit";
this.btnSplit.Size = new System.Drawing.Size(106, 30);
this.btnSplit.StopPulsingAfterClick = true;
this.btnSplit.TabIndex = 23;
this.btnSplit.Text = "S&plit";
this.btnSplit.Click += new System.EventHandler(this.btnSplit_Click);
//
// btnDoubleDown
//
this.btnDoubleDown.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnDoubleDown.AutoSize = true;
this.btnDoubleDown.BackColor = System.Drawing.Color.White;
this.btnDoubleDown.Enabled = false;
this.btnDoubleDown.ImageIndexDisabled = 19;
this.btnDoubleDown.ImageIndexHover = 18;
this.btnDoubleDown.ImageIndexNormal = 16;
this.btnDoubleDown.ImageIndexPressed = 17;
this.btnDoubleDown.ImageList = this.imlButtons;
this.btnDoubleDown.Location = new System.Drawing.Point(642, 527);
this.btnDoubleDown.Name = "btnDoubleDown";
this.btnDoubleDown.Size = new System.Drawing.Size(106, 30);
this.btnDoubleDown.StopPulsingAfterClick = true;
this.btnDoubleDown.TabIndex = 24;
this.btnDoubleDown.Text = "Dou&ble Down";
this.btnDoubleDown.Click += new System.EventHandler(this.btnDoubleDown_Click);
//
// btnInsurance
//
this.btnInsurance.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnInsurance.AutoSize = true;
this.btnInsurance.BackColor = System.Drawing.Color.White;
this.btnInsurance.ImageIndexDisabled = 23;
this.btnInsurance.ImageIndexHover = 22;
this.btnInsurance.ImageIndexNormal = 20;
this.btnInsurance.ImageIndexPressed = 21;
this.btnInsurance.ImageList = this.imlButtons;
this.btnInsurance.Location = new System.Drawing.Point(363, 527);
this.btnInsurance.Name = "btnInsurance";
this.btnInsurance.Size = new System.Drawing.Size(106, 30);
this.btnInsurance.StopPulsingAfterClick = true;
this.btnInsurance.TabIndex = 25;
this.btnInsurance.Text = "&Insurance";
this.btnInsurance.Visible = false;
this.btnInsurance.Click += new System.EventHandler(this.btnInsurance_Click);
//
// btnNoInsurance
//
this.btnNoInsurance.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnNoInsurance.AutoSize = true;
this.btnNoInsurance.BackColor = System.Drawing.Color.White;
this.btnNoInsurance.ImageIndexDisabled = 27;
this.btnNoInsurance.ImageIndexHover = 26;
this.btnNoInsurance.ImageIndexNormal = 24;
this.btnNoInsurance.ImageIndexPressed = 25;
this.btnNoInsurance.ImageList = this.imlButtons;
this.btnNoInsurance.Location = new System.Drawing.Point(478, 527);
this.btnNoInsurance.Name = "btnNoInsurance";
this.btnNoInsurance.Size = new System.Drawing.Size(106, 30);
this.btnNoInsurance.StopPulsingAfterClick = true;
this.btnNoInsurance.TabIndex = 26;
this.btnNoInsurance.Text = "&NoInsurance";
this.btnNoInsurance.Visible = false;
this.btnNoInsurance.Click += new System.EventHandler(this.btnNoInsurance_Click);
//
// tmrAutoDeal
//
this.tmrAutoDeal.Interval = 1000;
this.tmrAutoDeal.Tick += new System.EventHandler(this.tmrAutoDeal_Tick);
//
// Blackjack
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(946, 580);
this.Controls.Add(this.btnNoInsurance);
this.Controls.Add(this.btnInsurance);
this.Controls.Add(this.btnDoubleDown);
this.Controls.Add(this.btnHit);
this.Controls.Add(this.btnDeal);
this.Controls.Add(this.txtCardBack);
this.Controls.Add(this.chkMute);
this.Controls.Add(this.chkAuto);
this.Controls.Add(this.pnlStatistics);
this.Controls.Add(this.txtDelay);
this.Controls.Add(this.txtNumberOfPlayers);
this.Controls.Add(this.txtNumberOfDecks);
this.Controls.Add(this.btnStay);
this.Controls.Add(this.btnSplit);
this.KeyPreview = true;
this.Name = "Blackjack";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Blackjack";
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Blackjack_KeyDown);
this.Resize += new System.EventHandler(this.Blackjack_Resize);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Blackjack_MouseDown);
this.Load += new System.EventHandler(this.Blackjack_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Blackjack_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();
((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();
((System.ComponentModel.ISupportInitialize)(this.CardBack)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.txtCardBack)).EndInit();
this.ResumeLayout(false);
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Splash splashScreen = new Splash();
splashScreen.Show();
Application.Run(new Blackjack());
}
#endregion
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;
// Reset the players
foreach( Player player in players )
{
// Reset all players regardless of whether they are active
player.Reset();
}
// Reset insurance
insurance = false;
// Set the buttons in the correct state
SetButtonState( false );
// Reset the dealer
showDealerDownCard = false;
dealer.Reset();
// Reset the player pointer
currentPlayer = 0;
// 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 )
{
if( player.Active) player.GetWager();
}
// Set the label type to draw all labels
labelType = Player.LabelType.bothHands;
// 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;
dealing = true;
// Deal the cards
for( int k=0; k<2; k++ )
{
foreach( Player player in players )
{
if( player.Active )
{
// 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 );
// refresh the screen so we see each card as it is dealt.
this.Refresh();
}
dealing = false;
// If dealer has an ace showing,
// check to see if anybody wants insurance.
if( dealer.Hand[1].FaceValue == Card.CardType.Ace )
{
// Highlight the board to indicate insurance is available
insurance = true;
SetButtonState( false );
tmrInsurance.Enabled = true;
this.Refresh();
}
else 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
CountCard( dealer.Hand[0] );
// Take the money from everybody unless they have Blackjack
foreach( Player player in players )
{
if( player.Active )
{
foreach( Hand hand in player.GetHands() )
{
if( hand.IsBlackjack() )
// 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;
SetButtonState( true );
if( chkAuto.Checked )
tmrAutoDeal.Enabled = true;
}
else
{
this.Refresh();
// 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 != null );
// Tell the strategy form which player to show strategy for
if( strategyForm.Visible )
{
strategyForm.CurrentPlayer = CurrentPlayer;
if( dealer.Hand.Count > 0 )
strategyForm.DealerCard = dealer.Hand[1];
strategyForm.Refresh();
}
SetButtonState( false );
}
// 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 )
{
if( player.Active ) player.ResetCount( (int)txtNumberOfDecks.Value );
}
}
}
private void btnSplit_Click(object sender, System.EventArgs e)
{
// Make sure we're working with a player and not the dealer
// and that it's not an insurance round
if( CurrentPlayer != null && !insurance)
{
// See if the player is able to split
if( CurrentPlayer.Split() )
{
// Refresh so that the split hands show up
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
// and that it's not an insurance round
if( CurrentPlayer != null && !insurance )
{
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 != null )
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 != null );
}
}
private void btnStay_Click(object sender, System.EventArgs e)
{
int handTotal = 0;
// Make sure we're working with a player and not the dealer
// and that it's not an insurance round
if( CurrentPlayer != null && !insurance )
{
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 != null )
{
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 != null )
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 != null );
}
}
}
private void btnDoubleDown_Click(object sender, System.EventArgs e)
{
// Make sure we're working with a player and not the dealer
// and that it's not an insurance round
if( CurrentPlayer != null && !insurance )
{
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 btnInsurance_Click(object sender, System.EventArgs e)
{
// Make sure we're working with a player and not the dealer
// and that it's an insurance round
if( CurrentPlayer != null && insurance )
{
CurrentPlayer.Insurance = true;
NextPlayer();
}
}
private void btnNoInsurance_Click(object sender, System.EventArgs e)
{
// Make sure we're working with a player and not the dealer
// and that it's an insurance round
if( CurrentPlayer != null && insurance )
{
CurrentPlayer.Insurance = false;
NextPlayer();
}
}
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();
// And if the strategy form is visible, refresh it too
if( strategyForm.Visible )
strategyForm.Refresh();
// The strategy may change with each card so highlight the correct button
SetButtonState( false );
}
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();
// And refresh the strategy form to show the situation with the new hand
if( strategyForm.Visible )
strategyForm.Refresh();
// The strategy may change with each card so highlight the correct button
SetButtonState( false );
}
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 )
{
if( insurance && !dealer.Hand.IsBlackjack())
{
foreach( Player player in players )
{
if( player.Insurance )
{
player.LostInsurance();
player.Insurance = false;
}
}
// We're no longer in insurance mode
insurance = false;
currentPlayer = 0;
SetButtonState( false );
this.Refresh();
if( strategyForm.Visible )
{
strategyForm.CurrentPlayer = CurrentPlayer;
if( dealer.Hand.Count > 0 )
strategyForm.DealerCard = dealer.Hand[1];
strategyForm.Refresh();
}
}
else
{
// 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 )
{
if( player.Active )
{
foreach( Hand hand in player.GetHands() )
{
if( hand.Total() > 0 && hand.Total() <= 21 && !hand.IsBlackjack() )
{
hitToDealer = true;
break;
}
}
}
if( hitToDealer )
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 )
{
if( player.Active )
{
if( insurance && dealer.Hand.IsBlackjack() )
player.WonInsurance();
else
player.LostInsurance();
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
insurance = false;
txtNumberOfPlayers.Enabled = true;
txtNumberOfDecks.Enabled = true;
SetButtonState( true );
if( chkAuto.Checked )
tmrAutoDeal.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 )
{
if( player.Active ) player.ResetCount( (int)txtNumberOfDecks.Value );
}
}
this.Refresh();
}
}
else
{
if( strategyForm.Visible )
{
strategyForm.CurrentPlayer = CurrentPlayer;
if( dealer.Hand.Count > 0 )
strategyForm.DealerCard = dealer.Hand[1];
strategyForm.Refresh();
}
SetButtonState( false );
}
} while ( CurrentPlayer != null && CurrentPlayer.CurrentHand.Total() >= 21 && !insurance );
}
private void tmrAutoPlay_Tick(object sender, System.EventArgs e)
{
// This timer is always running, checking to see if a computer player
// is at play and clicking the approprate buttons.
Strategy.AdviceType advice = Strategy.AdviceType.None;
if( CurrentPlayer != null && CurrentPlayer.Type == Player.playerType.computer )
{
SetButtonState( false );
if( insurance )
{
// See if the computer player wants insurance
if( CurrentPlayer.GetInsuranceAdvice( int.Parse(txtNumberOfDecks.Text) ) )
btnInsurance_Click( sender, e );
else
btnNoInsurance_Click( sender, e );
}
else
{
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 SetButtonPulse()
{
// To help show the player what the 'correct' move is, we pulsate the
// appropriate button.
if( CurrentPlayer != null && CurrentPlayer.Type == Player.playerType.human )
{
if( insurance )
{
if( CurrentPlayer.CardStrategy != null )
{
btnInsurance.Pulse = CurrentPlayer.GetInsuranceAdvice( (int)txtNumberOfDecks.Value );
btnNoInsurance.Pulse = !btnInsurance.Pulse;
}
else
{
// We can't give advice if they don't have a strategy
btnInsurance.Pulse = false;
btnNoInsurance.Pulse = false;
}
}
else
{
switch( CurrentPlayer.GetAdvice(dealer.Hand[1]) )
{
case Strategy.AdviceType.Hit:
btnHit.Pulse = true;
break;
case Strategy.AdviceType.Stand:
btnStay.Pulse = true;
break;
case Strategy.AdviceType.DoubleDown:
btnDoubleDown.Pulse = true;
break;
case Strategy.AdviceType.Split:
btnSplit.Pulse = true;
break;
}
}
}
}
private void SetButtonState( bool dealEnabled )
{
// During an insurance round, only the insurance buttons are visible
if( insurance )
{
btnHit.Visible = false;
btnStay.Visible = false;
btnDoubleDown.Visible = false;
btnSplit.Visible = false;
btnDeal.Visible = false;
btnInsurance.Visible = true;
btnNoInsurance.Visible = true;
}
else
{
// The opposite is true for normal play
btnInsurance.Visible = false;
btnNoInsurance.Visible = false;
btnHit.Visible = true;
btnStay.Visible = true;
btnDoubleDown.Visible = true;
btnSplit.Visible = true;
btnDeal.Visible = true;
}
// This logic seems weird, but it says that we can only set the Deal button
// to true if AutoDeal is not checked, but we can always set it to false.
// This prevents the user from hitting the Deal button during AutoDeal.
if( !chkAuto.Checked && dealEnabled )
btnDeal.Enabled = dealEnabled;
else if( !dealEnabled )
btnDeal.Enabled = dealEnabled;
// Now enable and disable the buttons depending on whether a human or
// computer player is at play.
if( CurrentPlayer != null )
{
if( CurrentPlayer.Type == Player.playerType.computer )
{
btnHit.Enabled = false;
btnStay.Enabled = false;
btnDoubleDown.Enabled = false;
btnSplit.Enabled = false;
btnInsurance.Enabled = false;
btnNoInsurance.Enabled = false;
}
else
{
if( insurance )
{
btnInsurance.Enabled = true;
btnNoInsurance.Enabled = true;
}
else
{
btnHit.Enabled = true;
btnStay.Enabled = true;
btnDoubleDown.Enabled = CurrentPlayer.CanDouble( CurrentPlayer.CurrentHand );
btnSplit.Enabled = CurrentPlayer.CanSplit();
}
}
}
// Now make the 'correct' button pulsate.
SetButtonPulse();
}
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)
{
for (int i = 0; i < 5; i++)
{
if( i < txtNumberOfPlayers.Value )
players[i].Active = true;
else
players[i].Active = false;
}
// This line just forces the resize event to execute, moving the controls into
// the appropriate positions.
Blackjack_Resize(sender, e);
this.Refresh();
}
private void InitializePlayers(int numPlayers)
{
players = new Player[numPlayers];
for( int i = 0; i < numPlayers; i++ )
{
NumericUpDown plyrBet = null;
switch(i)
{
case 0: // PLAYER 1
plyrBet = CreateBetControl(1, new Point(955,299));
if( ConfigurationSettings.AppSettings["player1"] != null )
{
try
{
string[] playerConfig = ConfigurationSettings.AppSettings["player1"].ToString().Split(new char[]{'|'});
players[i] = CreatePlayer( new Point(961, 299), "player1_back", double.Parse(playerConfig[1]), plyrBet, playerConfig[0], playerConfig[2], playerConfig[3], (int)txtNumberOfDecks.Value );
}
catch
{
players[i] = new Player( new Point(961,299), "player1_back", 5000.00, plyrBet, Player.playerType.human, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
// Note that there must be a player 1
players[i].Active = true;
}
}
else
{
players[i] = new Player( new Point(961,299), "player1_back", 5000.00, plyrBet, Player.playerType.human, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
// Note that there must be a player 1
players[i].Active = true;
}
break;
case 1: // PLAYER 2
plyrBet = CreateBetControl(2, new Point(769,428));
if( ConfigurationSettings.AppSettings["player2"] != null )
{
try
{
string[] playerConfig = ConfigurationSettings.AppSettings["player2"].ToString().Split(new char[]{'|'});
players[i] = CreatePlayer( new Point(769,428), "player2_back", double.Parse(playerConfig[1]), plyrBet, playerConfig[0], playerConfig[2], playerConfig[3], (int)txtNumberOfDecks.Value );
}
catch
{
players[i] = new Player( new Point(769,428), "player2_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
}
else
{
players[i] = new Player( new Point(769,428), "player2_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
break;
case 2: // PLAYER 3
plyrBet = CreateBetControl(3, new Point(500,476));
if( ConfigurationSettings.AppSettings["player3"] != null )
{
try
{
string[] playerConfig = ConfigurationSettings.AppSettings["player3"].ToString().Split(new char[]{'|'});
players[i] = CreatePlayer( new Point(500,476), "player3_back", double.Parse(playerConfig[1]), plyrBet, playerConfig[0], playerConfig[2], playerConfig[3], (int)txtNumberOfDecks.Value );
}
catch
{
players[i] = new Player( new Point(500,476), "player3_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
}
else
{
players[i] = new Player( new Point(500,476), "player3_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
break;
case 3: // PLAYER 4
plyrBet = CreateBetControl(4, new Point(243,430));
if( ConfigurationSettings.AppSettings["player4"] != null )
{
try
{
string[] playerConfig = ConfigurationSettings.AppSettings["player4"].ToString().Split(new char[]{'|'});
players[i] = CreatePlayer( new Point(243,430), "player4_back", double.Parse(playerConfig[1]), plyrBet, playerConfig[0], playerConfig[2], playerConfig[3], (int)txtNumberOfDecks.Value );
}
catch
{
players[i] = new Player( new Point(243,430), "player4_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
}
else
{
players[i] = new Player( new Point(243,430), "player4_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
break;
case 4: // PLAYER 5
plyrBet = CreateBetControl(5, new Point(76,319));
if( ConfigurationSettings.AppSettings["player5"] != null )
{
try
{
string[] playerConfig = ConfigurationSettings.AppSettings["player5"].ToString().Split(new char[]{'|'});
players[i] = CreatePlayer( new Point(76,319), "player5_back", double.Parse(playerConfig[1]), plyrBet, playerConfig[0], playerConfig[2], playerConfig[3], (int)txtNumberOfDecks.Value );
}
catch
{
players[i] = new Player( new Point(76,319), "player5_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
}
else
{
players[i] = new Player( new Point(76,319), "player5_back", 5000.00, plyrBet, Player.playerType.computer, new BasicMultiDeck(), new HiLo( (int)txtNumberOfDecks.Value ) );
players[i].Active = false;
}
break;
}
}
// This line just forces the resize event to execute, moving the controls into
// the appropriate positions.
Blackjack_Resize(null, System.EventArgs.Empty);
this.Refresh();
}
private Player CreatePlayer( Point point, string background, double bank, NumericUpDown betControl, string type, string strategy, string method, int numDecks)
{
Player player = new Player( point,
background,
bank,
betControl,
type.ToLower() == "human" ? Player.playerType.human : Player.playerType.computer,
Strategy.NewStrategy( strategy ),
CountMethod.NewMethod( method, numDecks ) );
player.Active = true;
return player;
}
private void txtDelay_ValueChanged(object sender, System.EventArgs e)
{
tmrAutoPlay.Interval = (int)txtDelay.Value * 100;
tmrAutoDeal.Interval = (int)txtDelay.Value * 1000;
}
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 )
{
if( player.Active ) 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 )
{
if( player.Active ) player.ResetCount( (int)txtNumberOfDecks.Value );
}
}
private void BackChanged(object sender, EventArgs e)
{
this.Refresh();
}
private void EndOfShoe(object sender, EventArgs e)
{
endOfShoe = true;
}
private void ShuffleShoe(object sender, EventArgs e)
{
endOfShoe = false;
}
private void Blackjack_Load(object sender, System.EventArgs e)
{
// Preload the background image for speed
backgroundImage = new Bitmap(Resources.GetImage("table"));
// Load the strategies and methods into the list boxes
ArrayList strategies = Strategy.GetStrategies();
ArrayList methods = CountMethod.GetMethods();
System.Collections.IEnumerator myEnumerator = strategies.GetEnumerator();
mnuStrategy.MenuItems.Add("None", new EventHandler(mnuStrategy_Click));
while ( myEnumerator.MoveNext() )
{
mnuStrategy.MenuItems.Add( myEnumerator.Current.ToString(), new EventHandler(mnuStrategy_Click));
}
mnuMethod.MenuItems.Add( "None", new EventHandler(mnuMethod_Click));
myEnumerator = methods.GetEnumerator();
while ( myEnumerator.MoveNext() )
{
mnuMethod.MenuItems.Add( myEnumerator.Current.ToString(), new EventHandler(mnuMethod_Click));
}
// Move the controls onto the panel. This must be done at run time.
#region PanelStatistics
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;
pnlStatistics.Controls.Add( txtCardBack );
txtCardBack.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 + pnlStatistics.Panels[7].Width - txtCardBack.Width - 10 ;
txtCardBack.Top = txtNumberOfDecks.Top;
#endregion
// Create a dealer
dealer = new Dealer(new Point(530, 120));
// Initialize the shoe and the players
txtNumberOfDecks_ValueChanged(sender, e);
// txtNumberOfPlayers_ValueChanged(sender, e);
InitializePlayers(5);
txtDelay_ValueChanged(sender, e);
}
private void Blackjack_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;
// Draw smooth, anti-aliased cards. Comment out for slow machines
//drawingSurface.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Clear the screen
Rectangle realClientArea = ClientRectangle;
realClientArea.Height -= pnlStatistics.Height;
drawingSurface.DrawImage( backgroundImage, 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 && !dealing )
{
if( insurance )
CurrentPlayer.DrawBackground( drawingSurface, insurance );
else
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
if( player.Active ) 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 );
if( insurance && showInsurance )
drawingSurface.DrawImage( Resources.GetImage("insurance"), 242,241 );
drawingSurface.ResetTransform();
}
private void Blackjack_Resize(object sender, System.EventArgs e)
{
if( WindowState == FormWindowState.Minimized )
{
if( strategyForm.Visible )
{
strategyForm.Visible = false;
strategyFormMinimized = true;
}
}
else
{
Rectangle realClientArea = ClientRectangle;
realClientArea.Height -= pnlStatistics.Height;
scaleX = Math.Max(0,realClientArea.Width/1140.0F);
scaleY = Math.Max(0,realClientArea.Height/648.0F);
foreach( Player player in players )
{
player.MoveControls( scaleX, scaleY );
}
this.Refresh();
if( strategyFormMinimized )
{
strategyForm.Visible = true;
strategyFormMinimized = false;
}
}
}
private Player CurrentPlayer
{
get
{
if( currentPlayer >= 0 &&
currentPlayer <= players.GetUpperBound(0) &&
players[currentPlayer].Active )
{
return players[currentPlayer];
}
else
{
return null;
}
}
}
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 txtCardBack_ValueChanged(object sender, System.EventArgs e)
{
shoe.CardBack = (Shoe.BackTypes)(int)txtCardBack.Value;
}
private void tmrInsurance_Tick(object sender, System.EventArgs e)
{
if( tickCount > 5 )
{
tickCount = 0;
showInsurance = true;
this.Refresh();
tmrInsurance.Enabled = false;
}
else
{
showInsurance = !showInsurance;
this.Refresh();
tickCount++;
}
}
private void Blackjack_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if( e.Button == MouseButtons.Right )
{
playerNumber = -1;
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( new Point(e.X, e.Y) ))
playerNumber = 0;
else if( player2.Contains( new Point(e.X, e.Y) ) && (int)txtNumberOfPlayers.Value > 1 )
playerNumber = 1;
else if( player3.Contains( new Point(e.X, e.Y) ) && (int)txtNumberOfPlayers.Value > 2 )
playerNumber = 2;
else if( player4.Contains( new Point(e.X, e.Y) ) && (int)txtNumberOfPlayers.Value > 3 )
playerNumber = 3;
else if( player5.Contains( new Point(e.X, e.Y) ) && (int)txtNumberOfPlayers.Value > 4 )
playerNumber = 4;
if( playerNumber > -1 )
{
mnuPlayerType.Enabled = true;
mnuShowBank.Enabled = true;
mnuShowCardCount.Enabled =true;
mnuShowCardTotal.Enabled = true;
mnuMethod.Enabled = true;
mnuStrategy.Enabled = true;
foreach( MenuItem item in mnuStrategy.MenuItems )
{
item.Checked = players[playerNumber].CardStrategy != null && item.Text == players[playerNumber].CardStrategy.StrategyName;
}
if( players[playerNumber].CardStrategy == null )
mnuStrategy.MenuItems[0].Checked = true;
foreach( MenuItem item in mnuMethod.MenuItems )
{
item.Checked = players[playerNumber].Method != null && item.Text == players[playerNumber].Method.MethodName;
}
if( players[playerNumber].Method == null )
mnuMethod.MenuItems[0].Checked = true;
mnuPlayerType.Checked = players[playerNumber].Type == Player.playerType.computer;
mnuShowBank.Checked = players[playerNumber].ShowBank;
mnuShowCardCount.Checked = players[playerNumber].ShowCardCount;
mnuShowCardTotal.Checked = players[playerNumber].ShowCardTotal;
mnuPopup.Show(this, new Point(e.X, e.Y));
}
else
{
mnuPlayerType.Enabled = false;
mnuShowBank.Enabled = false;
mnuShowCardCount.Enabled =false;
mnuShowCardTotal.Enabled = false;
mnuMethod.Enabled = false;
mnuStrategy.Enabled = false;
mnuPopup.Show(this, new Point(e.X,e.Y));
}
}
}
private void mnuShowStrategy_Click(object sender, System.EventArgs e)
{
mnuStrategyWindow.Checked = !mnuStrategyWindow.Checked;
if( mnuStrategyWindow.Checked )
{
strategyForm.CurrentPlayer = CurrentPlayer;
if( dealer.Hand.Count > 0 )
strategyForm.DealerCard = dealer.Hand[1];
strategyForm.Show();
}
else
{
strategyForm.Visible = false;
}
}
private void mnuStrategy_Click(object sender, System.EventArgs e)
{
players[playerNumber].CardStrategy = Strategy.NewStrategy( ((MenuItem)sender).Text );
this.Refresh();
if( strategyForm.Visible )
strategyForm.Refresh();
}
private void mnuMethod_Click(object sender, System.EventArgs e)
{
players[playerNumber].Method = CountMethod.NewMethod( ((MenuItem)sender).Text, (int)txtNumberOfDecks.Value );
}
private void mnuPlayerType_Click(object sender, System.EventArgs e)
{
players[playerNumber].Type = !mnuPlayerType.Checked ? Player.playerType.computer : Player.playerType.human;
SetButtonState( btnDeal.Enabled );
}
private void mnuShowBank_Click(object sender, System.EventArgs e)
{
players[playerNumber].ShowBank = !mnuShowBank.Checked;
this.Refresh();
}
private void mnuShowCardCount_Click(object sender, System.EventArgs e)
{
players[playerNumber].ShowCardCount = !mnuShowCardCount.Checked;
this.Refresh();
}
private void mnuShowCardTotal_Click(object sender, System.EventArgs e)
{
players[playerNumber].ShowCardTotal = !mnuShowCardTotal.Checked;
this.Refresh();
}
private void Blackjack_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
chkMute.Focus();
}
private void tmrAutoDeal_Tick(object sender, System.EventArgs e)
{
tmrAutoDeal.Enabled = false;
btnDeal_Click(sender, e);
}
}
}