Click here to Skip to main content
15,896,915 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 236.7K   9.6K   153  
Learn OOD in .NET by examining a Blackjack game
using System;
using System.Drawing;
using System.Collections;
using System.Globalization;

namespace BlackJack
{
	/// <summary>
	/// Summary description for Strategy.
	/// </summary>
	[Serializable()]
	public abstract class Strategy
	{
		public const int S = 100;		// Stand
		public const int H = 200;		// Hit
		public const int D = 300;		// Double Down
		public const int P = 400;		// Split
		public const int N = -100;		// None
		public const int L = -200;		// Null

		public enum AdviceType
		{
			None = N,
			Hit = H,
			Stand = S,
			DoubleDown = D,
			Split = P,
			Null = L
		}

		//protected string name = "";
		protected int fontSize = 8;
		protected string fontName = "Arial";
		[NonSerialized]
		protected int[,] Pairs;
		[NonSerialized]
		protected string[] PairsLabels;
		[NonSerialized]
		protected int[,] Aces;
		[NonSerialized]
		protected string[] DoubleLabels;
		[NonSerialized]
		protected int[,] DoubleH;
		[NonSerialized]
		protected int[,] DoubleS;
		[NonSerialized]
		protected string[] AcesLabels;
		[NonSerialized]
		protected int[,] Hand;
		[NonSerialized]
		protected string[] HandLabels;

		protected Strategy() {}
		public abstract AdviceType GetAdvice( Hand h, Card c, bool b, double cc );
		public abstract bool GetInsuranceAdvice( double count, double cardCount, int decks );
		public virtual string StrategyName{ get{ return ""; }}
		public virtual void Draw( Graphics drawingSurface, Rectangle size, Hand hand, Card card, double count )
		{
			Draw( drawingSurface, new Point(0,0), size, new Rectangle(0,0,1,1), hand, card, count);
		}

		public virtual void Draw( Graphics drawingSurface, Point origin, Rectangle size, Rectangle space, Hand currentHand, Card dealerCard, double count )
		{
			SizeF labelSize;
			bool highlight = false;

			// Get largest string and move the table over to make room for the labels
			try
			{
				labelSize = drawingSurface.MeasureString("Seven",new Font(fontName,fontSize));
			}
			catch
			{
				labelSize = drawingSurface.MeasureString("Seven",new Font("Arial",fontSize));
			}

			StringFormat myFormat = new StringFormat();
			myFormat.Alignment = StringAlignment.Center;

			// Draw the Dealer's header row
			int dealerRowHeight = (int)labelSize.Height;
			drawingSurface.DrawString("Dealer's up card", new Font(fontName,fontSize),Brushes.Black, origin.X + labelSize.Width + (size.Width*10 + space.Width*10)/2, origin.Y, myFormat);

			// Draw the Dealer's up card labels
			for(int k=0; k<10; k++)
			{
				drawingSurface.DrawString(((Card.CardType)k).ToString(CultureInfo.InvariantCulture), new Font(fontName,fontSize), Brushes.Black, origin.X + k*space.Width + k*size.Width + (int)labelSize.Width + size.Width/2, origin.Y + dealerRowHeight, myFormat);
			}

			// Draw the Player's header column
			//			StringFormat myVerticalFormat = new StringFormat();
			//			myVerticalFormat.FormatFlags = StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
			//			myVerticalFormat.Alignment = StringAlignment.Center;
			//			g.DrawString("Player's Hand",new Font(fontName,fontSize),Brushes.Black,origin.X + (int)labelSize.Width+ (int)labelSize.Height + size.Width*10 + space.Width*10,origin.Y + dealerRowHeight + (size.Height*10 + space.Height*10)/2,myVerticalFormat);
			
			// Draw the actual Advice values, Total | Aces | Pairs
			myFormat.Alignment = StringAlignment.Center;
			myFormat.LineAlignment = StringAlignment.Center;

			// Draw the strategies for a hard hand
			for(int j=0; j<=Hand.GetUpperBound(0); j++)
			{
				drawingSurface.DrawString(HandLabels[j].ToString(CultureInfo.InvariantCulture), new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<=Hand.GetUpperBound(1); i++)
				{
					highlight = false;
					if( currentHand != null && dealerCard != null && !currentHand.IsPair && currentHand.Total() - 3 == j && dealerCard.TrueValue == i && (!currentHand.IsSoft || currentHand.Count > 2) )
						highlight = true;

					DrawSquare( drawingSurface, (AdviceType)Hand[j,i], highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}

			origin.Y += size.Height * (Hand.GetUpperBound(0)+1) + space.Height * (Hand.GetUpperBound(0)+1);

			// Draw the 17+ row
			drawingSurface.DrawString("17+", new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat );
			for(int j=0; j<10; j++)
			{
				highlight = false;
				if( currentHand != null && dealerCard != null && !currentHand.IsPair && currentHand.Total() >= 17 && dealerCard.TrueValue == j && (!currentHand.IsSoft || currentHand.Count > 2))
					highlight = true;

				DrawSquare( drawingSurface, AdviceType.Stand, highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + j*space.Width + j*size.Width + (int)labelSize.Width, origin.Y + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
			}

			origin.Y += size.Height + space.Height;

			// Draw the strategies for soft hands
			for(int j=0; j<=Aces.GetUpperBound(0); j++)
			{
				drawingSurface.DrawString(AcesLabels[j], new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<=Aces.GetUpperBound(1); i++)
				{
					highlight = false;
					if( currentHand != null && dealerCard != null && !currentHand.IsPair && currentHand.IsSoft && currentHand.Count == 2 )
					{
						if( currentHand[0].FaceValue == Card.CardType.Ace && currentHand[1].TrueValue - 1 == j && dealerCard.TrueValue == i )
							highlight = true;
						else if( currentHand[1].FaceValue == Card.CardType.Ace && currentHand[0].TrueValue - 1 == j && dealerCard.TrueValue == i )
							highlight = true;
					}
					DrawSquare( drawingSurface, (AdviceType)Aces[j,i], highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}

			origin.Y += size.Height * (Aces.GetUpperBound(0)+1) + space.Height * (Aces.GetUpperBound(0)+1);

			// Draw the strategies for pairs
			for(int j=0; j<=Pairs.GetUpperBound(0); j++)
			{
				drawingSurface.DrawString(PairsLabels[j], new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<=Pairs.GetUpperBound(1); i++)
				{
					highlight = false;
					if( currentHand != null && dealerCard != null && currentHand.IsPair )
					{
						if( currentHand[0].TrueValue == j && dealerCard.TrueValue == i )
							highlight = true;
					}
					DrawSquare( drawingSurface, (AdviceType)Pairs[j,i], highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}
		}

		protected void DrawSquare( Graphics drawingSurface, Strategy.AdviceType advice, bool highlight, bool newDeal, Rectangle square )
		{
			string legend = "";
			Brush paintBrush = null;

			switch( advice )
			{
				case Strategy.AdviceType.DoubleDown:
					if( newDeal )
					{
						legend = "D";
						paintBrush = Brushes.LimeGreen;
					}
					else
					{
						legend = "H";
						paintBrush = Brushes.Yellow;
					}
					break;
				case Strategy.AdviceType.Hit:
					legend = "H";
					paintBrush = Brushes.Yellow;
					break;
				case Strategy.AdviceType.Split:
					legend = "SP";
					paintBrush = Brushes.CornflowerBlue;
					break;
				case Strategy.AdviceType.Stand:
					legend = "S";
					paintBrush = Brushes.Crimson;
					break;
				default:
					legend = "";
					paintBrush = Brushes.White;
					break;
			}
			StringFormat myFormat = new StringFormat();
			myFormat.Alignment = StringAlignment.Center;
			myFormat.LineAlignment = StringAlignment.Center;
			if( highlight )
			{
				drawingSurface.FillRectangle( Brushes.Black, square );
				square.Inflate(-2,-2);
				drawingSurface.FillRectangle( paintBrush, square );
			}
			else
			{
				drawingSurface.FillRectangle( paintBrush, square );
			}
			drawingSurface.DrawString( legend, new Font(fontName, fontSize), Brushes.Black, square, myFormat );
		}

		public static ArrayList GetStrategies()
		{
			ArrayList strategies = new ArrayList();

			strategies.Add( "Basic Single Deck" );
			strategies.Add( "Basic Multi Deck" );
			strategies.Add( "Aggressive Multi Deck" );
			strategies.Add( "Smart Multi Deck" );
			strategies.Add( "High Low Multi Deck" );

			return strategies;
		}
		public static Strategy NewStrategy( string strategyName )
		{
			Strategy returnValue = null;

			switch( strategyName.ToLower() )
			{
				case "basic single deck":
					returnValue = new BasicSingleDeck();
					break;
				case "basic multi deck":
					returnValue = new BasicMultiDeck();
					break;
				case "aggressive multi deck":
					returnValue = new AggresiveMultiDeck();
					break;
				case "smart multi deck":
					returnValue = new SmartMultiDeck();
					break;
				case "high low multi deck":
					returnValue = new HighLowMultiDeck();
					break;
				default:
					returnValue = null;
					break;
			}
			return returnValue;
		}
	}

	[Serializable()]
	public class BasicSingleDeck : Strategy
	{
		public BasicSingleDeck()
		{
			// Player has a pair of cards
			//			Dealer Card	 A,2,3,4,5,6,7,8,9,10
			Pairs = new int[10,10] {{P,P,P,P,P,P,P,P,P,P}, // A   P
									{H,H,P,P,P,P,P,H,H,H}, // 2   l
									{H,H,H,P,P,P,P,H,H,H}, // 3   a
									{H,H,H,H,D,D,H,H,H,H}, // 4   y
									{H,D,D,D,D,D,D,D,D,H}, // 5   e
									{H,P,P,P,P,P,H,H,H,H}, // 6   r
									{H,P,P,P,P,P,P,H,H,H}, // 7   P
									{P,P,P,P,P,P,P,P,P,P}, // 8   a
									{S,P,P,P,P,P,S,P,P,S}, // 9   i
									{S,S,S,S,S,S,S,S,S,S}};// 10  r

			PairsLabels = new string[10] 
				{"A-A","2-2","3-3","4-4","5-5","6-6","7-7","8-8","9-9","10-10"};

			// Player has an ace and something else
			//		Dealer Card	     A,2,3,4,5,6,7,8,9,10
			Aces  = new int[9,10]  {{H,H,H,D,D,D,H,H,H,H}, // 2   P
									{H,H,H,D,D,D,H,H,H,H}, // 3   l
									{H,H,H,D,D,D,H,H,H,H}, // 4   a
									{H,H,H,D,D,D,H,H,H,H}, // 5   y
									{H,D,D,D,D,D,H,H,H,H}, // 6   e
									{S,D,D,D,D,S,S,H,H,H}, // 7   r
									{S,S,S,S,S,S,S,S,S,S}, // 8   
									{S,S,S,S,S,S,S,S,S,S}, // 9   
									{S,S,S,S,S,S,S,S,S,S}};// 10   

			AcesLabels = new string[9]
				{"A2","A3","A4","A5","A6","A7","A8","A9","A10"};

			// Player has a hard hand without an ace
			//      Dealer Card	     A,2,3,4,5,6,7,8,9,10
			Hand  = new int[14,10] {{H,H,H,H,H,H,H,H,H,H}, // 3   P
									{H,H,H,H,H,H,H,H,H,H}, // 4   l
									{H,H,H,H,H,H,H,H,H,H}, // 5   a
									{H,H,H,H,H,H,H,H,H,H}, // 6   y
									{H,H,H,H,H,H,H,H,H,H}, // 7   e
									{H,H,H,H,H,H,H,H,H,H}, // 8   r
									{H,D,D,D,D,D,H,H,H,H}, // 9   s
									{H,D,D,D,D,D,D,D,D,H}, // 10   
									{D,D,D,D,D,D,D,D,D,D}, // 11  T 
									{H,H,H,S,S,S,H,H,H,H}, // 12  o
									{H,S,S,S,S,S,H,H,H,H}, // 13  t
									{H,S,S,S,S,S,H,H,H,H}, // 14  a
									{H,S,S,S,S,S,H,H,H,H}, // 15  l
									{H,S,S,S,S,S,H,H,H,H}};// 16

			HandLabels = new string[14]
				{"3","4","5","6","7","8","9","10","11","12","13","14","15","16"};
		}

		private string name = "Basic Single Deck";
		public override string StrategyName{ get{ return name; }}
		public override bool GetInsuranceAdvice( double count, double cardCount, int decks )
		{
			return cardCount >= 3;
		}
		public override AdviceType GetAdvice( Hand playerHand, Card dealerCard, bool allowSplit, double cardCount )
		{
			AdviceType Advice = AdviceType.Null;

			try
			{
				if( dealerCard != null  && playerHand.Count > 0 )
				{
					if( playerHand.Count == 2 && allowSplit )
					{
						if( playerHand[0].FaceValue == playerHand[1].FaceValue )
						{
							Advice = (AdviceType)Pairs[ (int)playerHand[0].TrueValue, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[0].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[1].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[1].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[0].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand.Total() >= 17 )
						{
							Advice = AdviceType.Stand;
						}
						else
						{
							Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						}
					}
					else if( playerHand.Total() >= 17 )
					{
						Advice = AdviceType.Stand;
					}
					else
					{
						Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						if( Advice == AdviceType.DoubleDown )
							Advice = AdviceType.Hit;
					}
				}
			}
			catch (Exception Ex)
			{
				string foo = Ex.Message;
			}

			return Advice;
		}
	}

	[Serializable()]
	public class BasicMultiDeck : Strategy
	{
		public BasicMultiDeck()
		{
			// Player has a pair of cards
			//		Dealer Card	     A,2,3,4,5,6,7,8,9,10
			Pairs = new int[10,10] {{P,P,P,P,P,P,P,P,P,P}, // A   P
									{H,H,H,P,P,P,P,H,H,H}, // 2   l
									{H,H,H,P,P,P,P,H,H,H}, // 3   a
									{H,H,H,H,H,H,H,H,H,H}, // 4   y
									{H,D,D,D,D,D,D,D,D,H}, // 5   e
									{H,H,P,P,P,P,H,H,H,H}, // 6   r
									{H,P,P,P,P,P,P,H,H,H}, // 7   P
									{P,P,P,P,P,P,P,P,P,P}, // 8   a
									{S,P,P,P,P,P,S,P,P,S}, // 9   i
									{S,S,S,S,S,S,S,S,S,S}};// 10  r

			PairsLabels = new string[10] 
				{"A-A","2-2","3-3","4-4","5-5","6-6","7-7","8-8","9-9","10-10"};

			// Player has an ace and something else
			//		Dealer Card	     A,2,3,4,5,6,7,8,9,10
			Aces  = new int[9,10]  {{H,H,H,H,D,D,H,H,H,H}, // 2   P
									{H,H,H,H,D,D,H,H,H,H}, // 3   l
									{H,H,H,D,D,D,H,H,H,H}, // 4   a
									{H,H,H,D,D,D,H,H,H,H}, // 5   y
									{H,H,D,D,D,D,H,H,H,H}, // 6   e
									{H,S,D,D,D,D,S,S,H,H}, // 7   r
									{S,S,S,S,S,S,S,S,S,S}, // 8   
									{S,S,S,S,S,S,S,S,S,S}, // 9   
									{S,S,S,S,S,S,S,S,S,S}};// 10  
 
			AcesLabels = new string[9]
				{"A2","A3","A4","A5","A6","A7","A8","A9","A10"};

			// Player has a hard hand without an ace
			//      Dealer Card	     A,2,3,4,5,6,7,8,9,10
			Hand  = new int[14,10] {{H,H,H,H,H,H,H,H,H,H}, // 3   P
									{H,H,H,H,H,H,H,H,H,H}, // 4   l
									{H,H,H,H,H,H,H,H,H,H}, // 5   a
									{H,H,H,H,H,H,H,H,H,H}, // 6   y
									{H,H,H,H,H,H,H,H,H,H}, // 7   e
									{H,H,H,H,H,H,H,H,H,H}, // 8   r
									{H,H,D,D,D,D,H,H,H,H}, // 9   s
									{H,D,D,D,D,D,D,D,D,H}, // 10   
									{H,D,D,D,D,D,D,D,D,D}, // 11  T 
									{H,H,H,S,S,S,H,H,H,H}, // 12  o
									{H,S,S,S,S,S,H,H,H,H}, // 13  t
									{H,S,S,S,S,S,H,H,H,H}, // 14  a
									{H,S,S,S,S,S,H,H,H,H}, // 15  l
									{H,S,S,S,S,S,H,H,H,H}};// 16

			HandLabels = new string[14]
				{"3","4","5","6","7","8","9","10","11","12","13","14","15","16"};
		}

		private string name = "Basic Multi Deck";
		public override string StrategyName{ get{ return name; }}
		public override bool GetInsuranceAdvice( double count, double cardCount, int decks )
		{
			return cardCount >= 3;
		}
		public override AdviceType GetAdvice( Hand playerHand, Card dealerCard, bool allowSplit, double cardCount )
		{
			AdviceType Advice = AdviceType.Null;

			try
			{
				if( dealerCard != null  && playerHand.Count > 0 )
				{
					if( playerHand.Count == 2 && allowSplit )
					{
						if( playerHand[0].FaceValue == playerHand[1].FaceValue )
						{
							Advice = (AdviceType)Pairs[ (int)playerHand[0].TrueValue, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[0].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[1].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[1].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[0].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand.Total() >= 17 )
						{
							Advice = AdviceType.Stand;
						}
						else
						{
							Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						}
					}
					else if( playerHand.Total() >= 17 )
					{
						Advice = AdviceType.Stand;
					}
					else
					{
						Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						if( Advice == AdviceType.DoubleDown )
							Advice = AdviceType.Hit;
					}
				}
			}
			catch (Exception Ex)
			{
				string foo = Ex.Message;
			}

			return Advice;
		}
	}

	[Serializable()]
	public class AggresiveMultiDeck : Strategy
	{
		public AggresiveMultiDeck()
		{
			// Player has a pair of cards
			//			Dealer Card	 A,2,3,4,5,6,7,8,9,10
			Pairs = new int[10,10] {{P,P,P,P,P,P,P,P,P,P}, // A   P
									{P,P,P,P,P,P,P,P,P,P}, // 2   l
									{P,P,P,P,P,P,P,P,P,P}, // 3   a
									{H,H,P,P,P,P,H,H,H,H}, // 4   y
									{H,D,D,D,D,D,D,D,D,H}, // 5   e
									{H,P,P,P,P,P,H,H,H,H}, // 6   r
									{H,P,P,P,P,P,P,H,H,H}, // 7   P
									{P,P,P,P,P,P,P,P,P,P}, // 8   a
									{P,P,P,P,P,P,P,P,P,S}, // 9   i
									{P,P,P,P,P,P,P,P,P,S}};// 10  r

			PairsLabels = new string[10] 
			{"A-A","2-2","3-3","4-4","5-5","6-6","7-7","8-8","9-9","10-10"};

			// Player has an ace and something else
			//			Dealer Card	 A,2,3,4,5,6,7,8,9,10
			Aces  = new int[9,10]  {{H,H,H,H,D,D,H,H,H,H}, // 2   P
									{H,H,H,H,D,D,H,H,H,H}, // 3   l
									{H,H,H,D,D,D,H,H,H,H}, // 4   a
									{H,H,H,D,D,D,H,H,H,H}, // 5   y
									{H,H,D,D,D,D,H,H,H,H}, // 6   e
									{H,D,D,D,D,D,S,S,H,H}, // 7   r
									{S,D,D,D,D,D,S,S,S,S}, // 8   
									{S,D,D,D,D,D,S,S,S,S}, // 9   
									{S,D,D,D,D,D,S,S,S,S}};// 10  
 
			AcesLabels = new string[9]
				{"A2","A3","A4","A5","A6","A7","A8","A9","A10"};

			// Player has a hard hand without an ace
			//         Dealer Card	 A,2,3,4,5,6,7,8,9,10
			Hand  = new int[14,10] {{H,H,H,H,H,H,H,H,H,H}, // 3   P
									{H,H,H,H,H,H,H,H,H,H}, // 4   l
									{H,H,H,H,H,H,H,H,H,H}, // 5   a
									{H,H,H,H,H,H,H,H,H,H}, // 6   y
									{H,H,H,H,H,H,H,H,H,H}, // 7   e
									{H,H,H,H,H,H,H,H,H,H}, // 8   r
									{D,D,D,D,D,D,D,D,D,H}, // 9   s
									{D,D,D,D,D,D,D,D,D,D}, // 10   
									{D,D,D,D,D,D,D,D,D,D}, // 11  T 
									{H,H,H,S,S,S,H,H,H,H}, // 12  o
									{H,S,S,S,S,S,H,H,H,H}, // 13  t
									{H,S,S,S,S,S,H,H,H,H}, // 14  a
									{H,S,S,S,S,S,H,H,H,H}, // 15  l
									{H,S,S,S,S,S,H,H,H,H}};// 16

			HandLabels = new string[14]
				{"3","4","5","6","7","8","9","10","11","12","13","14","15","16"};
		}

		private string name = "Aggressive Multi Deck";
		public override string StrategyName{ get{ return name; }}
		public override bool GetInsuranceAdvice( double count, double cardCount, int decks )
		{
			return cardCount >= 3;
		}
		public override AdviceType GetAdvice( Hand playerHand, Card dealerCard, bool allowSplit, double cardCount )
		{
			AdviceType Advice = AdviceType.Null;

			try
			{
				if( dealerCard != null  && playerHand.Count > 0 )
				{
					if( playerHand.Count == 2 && allowSplit )
					{
						if( playerHand[0].FaceValue == playerHand[1].FaceValue )
						{
							Advice = (AdviceType)Pairs[ (int)playerHand[0].TrueValue, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[0].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[1].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[1].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[0].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand.Total() >= 17 )
						{
							Advice = AdviceType.Stand;
						}
						else
						{
							Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						}
					}
					else if( playerHand.Total() >= 17 )
					{
						Advice = AdviceType.Stand;
					}
					else
					{
						Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						if( Advice == AdviceType.DoubleDown )
							Advice = AdviceType.Hit;
					}
				}
			}
			catch (Exception Ex)
			{
				string foo = Ex.Message;
			}

			return Advice;
		}
	}

	[Serializable()]
	public class SmartMultiDeck : Strategy
	{
		public SmartMultiDeck()
		{
			// Player has a pair of cards
			//		Dealer Card	      A,2,3,4,5,6,7,8,9,10
			Pairs = new int[10,10]  {{P,P,P,P,P,P,P,P,P,P}, // A   P
									 {H,H,H,P,P,P,P,H,H,H}, // 2   l
									 {H,H,H,P,P,P,P,H,H,H}, // 3   a
									 {H,H,H,H,H,H,H,H,H,H}, // 4   y
									 {H,D,D,D,D,D,D,D,D,H}, // 5   e
									 {H,H,P,P,P,P,H,H,H,H}, // 6   r
									 {H,P,P,P,P,P,P,H,H,H}, // 7   P
									 {P,P,P,P,P,P,P,P,P,P}, // 8   a
									 {S,P,P,P,P,P,S,P,P,S}, // 9   i
									 {S,P,P,P,P,P,P,S,S,S}};// 10  r

			PairsLabels = new string[10] 
				{"A-A","2-2","3-3","4-4","5-5","6-6","7-7","8-8","9-9","10-10"};

			// Player has an ace and something else
			//		Dealer Card	      A,2,3,4,5,6,7,8,9,10
			Aces  = new int[9,10]   {{H,H,H,H,D,D,H,H,H,H}, // 2   P
									 {H,H,H,H,D,D,H,H,H,H}, // 3   l
									 {H,H,H,D,D,D,H,H,H,H}, // 4   a
									 {H,H,H,D,D,D,H,H,H,H}, // 5   y
									 {H,H,D,D,D,D,H,H,H,H}, // 6   e
									 {H,S,D,D,D,D,S,S,H,H}, // 7   r
									 {S,S,S,S,S,S,S,S,S,S}, // 8   
									 {S,S,S,S,S,S,S,S,S,S}, // 9   
									 {S,S,S,S,S,S,S,S,S,S}};// 10   

			AcesLabels = new string[9]
				{"A2","A3","A4","A5","A6","A7","A8","A9","A10"};

			// Player has a hard hand without an ace
			//      Dealer Card	      A,2,3,4,5,6,7,8,9,10
			Hand  = new int[14,10]  {{H,H,H,H,H,H,H,H,H,H}, // 3   P
									 {H,H,H,H,H,H,H,H,H,H}, // 4   l
									 {H,H,H,H,H,H,H,H,H,H}, // 5   a
									 {H,H,H,H,H,H,H,H,H,H}, // 6   y
									 {H,H,H,H,H,H,H,H,H,H}, // 7   e
									 {H,H,H,H,H,H,H,H,H,H}, // 8   r
									 {H,H,D,D,D,D,H,H,H,H}, // 9   s
									 {H,D,D,D,D,D,D,D,D,H}, // 10   
									 {H,D,D,D,D,D,D,D,D,D}, // 11  T 													  {H,H,H,S,S,S,H,H,H,H}, // SD  o
									 {H,S,S,S,S,H,H,H,H,H}, // 12  o
									 {H,S,S,S,S,S,H,H,H,H}, // 13  t
									 {H,S,S,S,S,S,H,H,H,H}, // 14  a
									 {H,S,S,S,S,S,H,H,H,H}, // 15  l
									 {H,S,S,S,S,S,H,H,H,H}};// 16

			HandLabels = new string[14]
				{"3","4","5","6","7","8","9","10","11","12","13","14","15","16"};

		}

		// Player has a hard hand without an ace, count is high (lots of tens)
		//                      Dealer Card	     A,2,3,4,5,6,7,8,9,10
		private int[,] Hand2  = new int[14,10] {{H,H,H,H,H,H,H,H,H,H}, // 3   P
												{H,H,H,H,H,H,H,H,H,H}, // 4   l
												{H,H,H,H,H,H,H,H,H,H}, // 5   a
												{H,H,H,H,H,H,H,H,H,H}, // 6   y
												{H,H,H,H,H,H,H,H,H,H}, // 7   e
												{H,D,D,D,D,D,D,H,H,H}, // 8   r
												{H,D,D,D,D,D,D,D,H,H}, // 9   s
												{H,D,D,D,D,D,D,D,D,H}, // 10   
												{H,D,D,D,D,D,D,D,D,D}, // 11  T 
												{H,S,S,S,S,H,H,H,H,H}, // 12  o
												{H,S,S,S,S,S,H,H,H,H}, // 13  t
												{H,S,S,S,S,S,S,H,H,H}, // 14  a
												{H,S,S,S,S,S,S,S,H,H}, // 15  l
												{H,S,S,S,S,S,S,S,S,H}};// 16

		private string name = "Smart Multi Deck";
		public override string StrategyName{ get{ return name; }}
		public override bool GetInsuranceAdvice( double count, double cardCount, int decks )
		{
			return cardCount >= 3;
		}
		public override AdviceType GetAdvice( Hand playerHand, Card dealerCard, bool allowSplit, double cardCount )
		{
			AdviceType Advice = AdviceType.Null;

			try
			{
				if( dealerCard != null  && playerHand.Count > 0 )
				{
					if( playerHand.Count == 2 && allowSplit )
					{
						if( playerHand[0].FaceValue == playerHand[1].FaceValue )
						{
							Advice = (AdviceType)Pairs[ (int)playerHand[0].TrueValue, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[0].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[1].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand[1].FaceValue == Card.CardType.Ace )
						{
							Advice = (AdviceType)Aces[ (int)playerHand[0].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
						else if( playerHand.Total() >= 17 )
						{
							Advice = AdviceType.Stand;
						}
						else
						{
							if( cardCount > 0 )
								Advice = (AdviceType)Hand2[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
							else
								Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						}
					}
					else if( playerHand.Total() >= 17 )
					{
						Advice = AdviceType.Stand;
					}
					else
					{
						if( cardCount > 0 )
							Advice = (AdviceType)Hand2[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						else
							Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];

						if( Advice == AdviceType.DoubleDown )
							Advice = AdviceType.Hit;
					}
				}
			}
			catch (Exception Ex)
			{
				string foo = Ex.Message;
			}

			return Advice;
		}
	}

	[Serializable()]
	public class HighLowMultiDeck : Strategy
	{

		public HighLowMultiDeck()
		{
			// Split, No Double After, S17 (p.38)
			//		Dealer Card	      A, 2, 3, 4, 5, 6, 7, 8, 9,10
			Pairs = new int[10,10] {{-3, P, P, P, P, P,-9,-8,-7,-8}, // A   P
									{ L,-3,-5,-7,-9, P, P, 5, L, L}, // 2   l
									{ L, 0,-4,-7,-9, P, P, 4, L, L}, // 3   a
									{ L, L, 8, 3,-1,-2, L, L, L, L}, // 4   y
									{ L, L, L, L, L, L, L, L, L, L}, // 5   e
									{ L,-1,-4,-6,-8,-10,L, L, L, L}, // 6   r
									{ L,-9, P, P, P, P, P, 5, L, L}, // 7   P
									{ P, P, P, P, P, P, P, P, P,98}, // 8   a
									{ 3,-2,-3,-5,-6,-6, 3,-8,-9, L}, // 9   i
									{ L, L, 8, 6, 5, 4, L, L, L, L}};// 10  r

			PairsLabels = new string[10] 
				{"A-A","2-2","3-3","4-4","5-5","6-6","7-7","8-8","9-9","10-10"};

			// Player has an ace and something else
			//		Dealer Card	      A, 2, 3, 4, 5, 6, 7, 8, 9,10
			Aces  = new int[19,10] {{ H, H, H, H, H, H, H, H, H, H}, // 2   P
									{ H, H, H, H, H, H, H, H, H, H}, // 3   l
									{ H, H, H, H, H, H, H, H, H, H}, // 4   a
									{ H, H, H, H, H, H, H, H, H, H}, // 5   y
									{ H, H, H, H, H, H, H, H, H, H}, // 6   e
									{ H, H, H, H, H, H, H, H, H, H}, // 7   r
									{ H, H, H, H, H, H, H, H, H, H}, // 8   s
									{ H, H, H, H, H, H, H, H, H, H}, // 9   
									{ H, H, H, H, H, H, H, H, H, H}, // 10  T
									{ H, H, H, H, H, H, H, H, H, H}, // 11  o
									{ H, H, H, H, H, H, H, H, H, H}, // 12  t
									{ H, H, H, H, H, H, H, H, H, H}, // 13  a
									{ H, H, H, H, H, H, H, H, H, H}, // 14  l
									{ H, H, H, H, H, H, H, H, H, H}, // 15   
									{ H, H, H, H, H, H, H, H, H, H}, // 16   
									{ H, H, H, H, H, H, H, H, H, H}, // 17   
									{ 1, S, S, S, S, S, S, S, H, H}, // 18   
									{ S, S, S, S, S, S, S, S, S, S}, // 19   
									{ S, S, S, S, S, S, S, S, S, S}};// 20
	 
			AcesLabels = new string[8]
				{"A2","A3","A4","A5","A6","A7","A8","A9"};

			// Double Down (hard hand), S17 (p.41)
			//         Dealer Card	   A, 2, 3, 4, 5, 6, 7, 8, 9,10
			DoubleH = new int[18,10]{{ L, L, L, L, L, L, L, L, L, L}, // 3   P
									 { L, L, L, L, L, L, L, L, L, L}, // 4   l
									 { L, L, L, L, L, L, L, L, L, L}, // 5   a
									 { L, L, L, L, L, L, L, L, L, L}, // 6   y
									 { L, L, L, L, 9, 9, L, L, L, L}, // 7   e
									 { L, L, 9, 5, 3, 1, L, L, L, L}, // 8   r
									 { L, 1, 0,-2,-4,-6, 3, 7, L, L}, // 9   s
									 { 4,-8,-9,-10,D, D,-6,-4,-1, 4}, // 10   
									 { 1, D, D, D, D, D,-9,-6,-4,-4}, // 11  T 													  {L, L, L, L, L, L, L, L, L, L},  // LL  o
									 { L, L, L, L, L, L, L, L, L, L}, // 12  o
									 { L, L, L, L, L, L, L, L, L, L}, // 13  t
									 { L, L, L, L, L, L, L, L, L, L}, // 14  a
									 { L, L, L, L, L, L, L, L, L, L}, // 15  l
									 { L, L, L, L, L, L, L, L, L, L}, // 16
									 { L, L, L, L, L, L, L, L, L, L}, // 17
									 { L, L, L, L, L, L, L, L, L, L}, // 18
									 { L, L, L, L, L, L, L, L, L, L}, // 19
									 { L, L, L, L, L, L, L, L, L, L}};// 20

			// Double Down (soft hand), S17 (p.41)
			//          Dealer Card	   A, 2, 3, 4, 5, 6, 7, 8, 9,10
			DoubleS = new int[8,10] {{ L, L, 7, 3, 0,-1, L, L, L, L}, // 2   P
									 { L, L, 7, 1,-1,-4, L, L, L, L}, // 3   l
									 { L, L, 7, 0,-4,-9, L, L, L, L}, // 4   a
									 { L, L, 4,-2,-6, D, L, L, L, L}, // 5   y
									 { L, 1,-3,-7,-10,D, L, L, L, L}, // 6   e
									 { L, 0,-2,-6,-8,-10,L, L, L, L}, // 7   r
									 { L, 8, 5, 3, 1, 1, L, L, L, L}, // 8
									 { L,10, 8, 6, 5, 4, L, L, L, L}};// 9   


			DoubleLabels = new string[18] 
				{"3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"};

			// Player has a hard hand without an ace
			//            Dealer Card  A, 2, 3, 4, 5, 6, 7, 8, 9,10
			Hand  = new int[18,10] {{ H, H, H, H, H, H, H, H, H, H}, // 3   P
									{ H, H, H, H, H, H, H, H, H, H}, // 4   l
									{ H, H, H, H, H, H, H, H, H, H}, // 5   a
									{ H, H, H, H, H, H, H, H, H, H}, // 6   y
									{ H, H, H, H, H, H, H, H, H, H}, // 7   e
									{ H, H, H, H, H, H, H, H, H, H}, // 8   r
									{ H, H, H, H, H, H, H, H, H, H}, // 9   s
									{ H, H, H, H, H, H, H, H, H, H}, // 10   
									{ H, H, H, H, H, H, H, H, H, H}, // 11  T 													  {H,H,H,S,S,S,H,H,H,H}, // SD  o
									{ H, 3, 2, 0,-1, 0, H, H, H, H}, // 12  o
									{ H, 0,-1,-3,-4,-4, H, H, H, H}, // 13  t
									{ H,-3,-4,-6,-7,-7, H, H, H, H}, // 14  a
									{10,-5,-6,-7,-9,-9,10,10, 8, 4}, // 15  l
									{ 8,-8,-10,S, S, S, 9, 7, 5, 0}, // 16
									{-6, S, S, S, S, S, S, S, S, S}, // 17
									{ L, L, L, L, L, L, L, L, L, L}, // 18
									{ L, L, L, L, L, L, L, L, L, L}, // 19
									{ L, L, L, L, L, L, L, L, L, L}};// 20

			HandLabels = new string[13]
				{"5","6","7","8","9","10","11","12","13","14","15","16","17"};

		}

		private string name = "High Low Multi Deck";
		public override string StrategyName{ get{ return name; }}
		public override bool GetInsuranceAdvice( double count, double cardCount, int decks )
		{
			return count > decks * 4;
		}
		public override void Draw( Graphics drawingSurface, Point origin, Rectangle size, Rectangle space, Hand currentHand, Card dealerCard, double count )
		{
			SizeF labelSize;
			bool highlight = false;

			// Get largest string and move the table over to make room for the labels
			try
			{
				labelSize = drawingSurface.MeasureString("Seven",new Font(fontName,fontSize));
			}
			catch
			{
				labelSize = drawingSurface.MeasureString("Seven",new Font("Arial",fontSize));
			}

			StringFormat myFormat = new StringFormat();
			myFormat.Alignment = StringAlignment.Center;

			// Draw the Dealer's header row
			int dealerRowHeight = (int)labelSize.Height;
			drawingSurface.DrawString("Dealer's up card", new Font(fontName,fontSize),Brushes.Black, origin.X + labelSize.Width + (size.Width*10 + space.Width*10)/2, origin.Y, myFormat);

			// Draw the Dealer's up card labels
			for(int k=0; k<10; k++)
			{
				drawingSurface.DrawString(((Card.CardType)k).ToString(CultureInfo.InvariantCulture), new Font(fontName,fontSize), Brushes.Black, origin.X + k*space.Width + k*size.Width + (int)labelSize.Width + size.Width/2, origin.Y + dealerRowHeight, myFormat);
			}

			// Draw the Player's header column
			//			StringFormat myVerticalFormat = new StringFormat();
			//			myVerticalFormat.FormatFlags = StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
			//			myVerticalFormat.Alignment = StringAlignment.Center;
			//			g.DrawString("Player's Hand",new Font(fontName,fontSize),Brushes.Black,origin.X + (int)labelSize.Width+ (int)labelSize.Height + size.Width*10 + space.Width*10,origin.Y + dealerRowHeight + (size.Height*10 + space.Height*10)/2,myVerticalFormat);
			
			// Draw the actual Advice values, Hard Total | Soft Total | Aces | Pairs
			myFormat.Alignment = StringAlignment.Center;
			myFormat.LineAlignment = StringAlignment.Center;

			int[] tmpCard1 = new int[] {2,3,3,2,2,2,2,2,2,8,8,8,8};
			int[] tmpCard2 = new int[] {1,1,2,4,5,6,7,8,9,4,5,6,7};

			for(int j=0; j<=12; j++)
			{
				drawingSurface.DrawString(HandLabels[j].ToString(CultureInfo.InvariantCulture), new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<10; i++)
				{
					Hand tmpHand = new Hand();
					tmpHand.Add( new Card((Card.CardType)tmpCard1[j], Card.Suits.Clubs));
					tmpHand.Add( new Card((Card.CardType)tmpCard2[j], Card.Suits.Clubs));
					
					highlight = false;
					if( currentHand != null && dealerCard != null && !currentHand.IsPair && currentHand.Total() == tmpHand.Total() && dealerCard.TrueValue == i && (!currentHand.IsSoft || currentHand.Count > 2) )
						highlight = true;

					AdviceType advice = GetAdvice(tmpHand, new Card((Card.CardType)i, Card.Suits.Clubs), false, count);

					DrawSquare( drawingSurface, advice, highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}

			origin.Y += size.Height * 13 + space.Height * 13;

			// Draw the 18+ row
			drawingSurface.DrawString("18+", new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat );
			for(int j=0; j<10; j++)
			{				
				highlight = false;
				if( currentHand != null && dealerCard != null && !currentHand.IsPair && currentHand.Total() >= 18 && dealerCard.TrueValue == j && (!currentHand.IsSoft || currentHand.Count > 2))
					highlight = true;

				DrawSquare( drawingSurface, AdviceType.Stand, highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + j*space.Width + j*size.Width + (int)labelSize.Width, origin.Y + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
			}

			origin.Y += size.Height + space.Height;

			// Draw the soft totals S13 - S20
			string[] softLabels = new string[] {"S14","S15","S16","S17","S18","S19","S20"};

			for(int j=0; j<7; j++)
			{
				drawingSurface.DrawString(softLabels[j].ToString(CultureInfo.InvariantCulture), new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<10; i++)
				{
					Hand tmpHand = new Hand();
					tmpHand.Add( new Card((Card.CardType)0, Card.Suits.Clubs));
					tmpHand.Add( new Card((Card.CardType)1, Card.Suits.Clubs));
					tmpHand.Add( new Card((Card.CardType)j, Card.Suits.Clubs));
					
					highlight = false;
					if( currentHand != null && dealerCard != null && !currentHand.IsPair && currentHand.Total() == tmpHand.Total() && dealerCard.TrueValue == i && currentHand.IsSoft && currentHand.Count > 2 )
						highlight = true;

					AdviceType advice = GetAdvice(tmpHand, new Card((Card.CardType)i, Card.Suits.Clubs), false, count);

					DrawSquare( drawingSurface, advice, highlight, false, new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}

			origin.Y += size.Height * 7 + space.Height * 7;

			// Draw the strategies for soft hands
			for(int j=0; j<8; j++)
			{
				drawingSurface.DrawString(AcesLabels[j], new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<10; i++)
				{
					Hand tmpHand = new Hand();
					tmpHand.Add( new Card((Card.CardType)0, Card.Suits.Clubs));
					tmpHand.Add( new Card((Card.CardType)j+1, Card.Suits.Clubs));

					highlight = false;
					if( currentHand != null && dealerCard != null && dealerCard.TrueValue == i && !currentHand.IsPair && currentHand.IsSoft && currentHand.Count == 2 && currentHand.Total() == tmpHand.Total() )
						highlight = true;

					DrawSquare( drawingSurface, GetAdvice(tmpHand, new Card((Card.CardType)i, Card.Suits.Clubs), (currentHand != null && currentHand.Count == 2), count), highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}

			origin.Y += size.Height * 8 + space.Height * 8;

			// Draw the strategies for pairs
			for(int j=0; j<10; j++)
			{
				drawingSurface.DrawString(PairsLabels[j], new Font(fontName,fontSize), Brushes.Black, origin.X + (int)labelSize.Width/2, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + size.Height/2 + dealerRowHeight, myFormat);
				for(int i=0; i<10; i++)
				{
					Hand tmpHand = new Hand();
					tmpHand.Add( new Card((Card.CardType)j, Card.Suits.Clubs));
					tmpHand.Add( new Card((Card.CardType)j, Card.Suits.Clubs));

					highlight = false;
					if( currentHand != null && dealerCard != null && currentHand.IsPair )
					{
						if( currentHand[0].TrueValue == tmpHand[0].TrueValue && dealerCard.TrueValue == i )
							highlight = true;
					}
					DrawSquare( drawingSurface, GetAdvice(tmpHand, dealerCard, true, count), highlight, (currentHand != null && currentHand.Count == 2), new Rectangle(origin.X + i*space.Width + i*size.Width + (int)labelSize.Width, origin.Y + j*space.Height + j*size.Height + (int)labelSize.Height + dealerRowHeight, size.Width, size.Height ) );
				}
			}
		}

		public override AdviceType GetAdvice( Hand playerHand, Card dealerCard, bool allowSplit, double cardCount )
		{
			AdviceType Advice = AdviceType.Null;
			AdviceType suggestedAdvice = AdviceType.Null;

			try
			{
				if( dealerCard != null && playerHand.Count > 0 )
				{
					if( playerHand.Count == 2 && allowSplit )
					{
						if( playerHand[0].FaceValue == playerHand[1].FaceValue )
						{
							Advice = (AdviceType)Pairs[ (int)playerHand[0].TrueValue, (int)dealerCard.TrueValue ];
							suggestedAdvice = AdviceType.Split;
						}
					}

					if( playerHand.Count == 2 )
					{
						if( Advice == AdviceType.Null && playerHand[0].FaceValue == Card.CardType.Ace )
						{
							suggestedAdvice = AdviceType.DoubleDown;
							Advice = (AdviceType)DoubleS[ playerHand[1].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
					
						if( Advice == AdviceType.Null && playerHand[1].FaceValue == Card.CardType.Ace )
						{
							suggestedAdvice = AdviceType.DoubleDown;
							Advice = (AdviceType)DoubleS[ playerHand[0].TrueValue - 1, (int)dealerCard.TrueValue ];
						}
					
						if( Advice == AdviceType.Null )
						{
							suggestedAdvice = AdviceType.DoubleDown;
							Advice = (AdviceType)DoubleH[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
						}
					}

					if( Advice == AdviceType.Null && playerHand.IsSoft )
					{
						suggestedAdvice = AdviceType.Stand;
						Advice = (AdviceType)Aces[ playerHand.Total() - 2, (int)dealerCard.TrueValue ];
					}
					
					if( Advice == AdviceType.Null )
					{
						suggestedAdvice = AdviceType.Stand;
						Advice = (AdviceType)Hand[ playerHand.Total() - 3, (int)dealerCard.TrueValue ];
					}

					if( Math.Abs((int)Advice) < 100 )
					{
						if( (int)Advice > 90 )
						{
							if( cardCount < (int)Advice-90 )
								Advice = suggestedAdvice;
							else
								Advice = AdviceType.Null;
						}
						else
						{
							if( cardCount > (int)Advice )
								Advice = suggestedAdvice;
							else
								Advice = AdviceType.Null;
						}
					}

					if( Advice == AdviceType.Null && playerHand.Total() >= 18 )
						Advice = AdviceType.Stand;
					else if( Advice == AdviceType.Null )
						Advice = AdviceType.Hit;
				}
			}
			catch //(Exception Ex)
			{
				//string foo = Ex.Message;
			}

			return Advice;
		}
	}
}

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