Skip to content

Instantly share code, notes, and snippets.

@c9952594
Created July 25, 2016 01:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save c9952594/35f9b2a418975e0499d92bc1aebe0756 to your computer and use it in GitHub Desktop.
Save c9952594/35f9b2a418975e0499d92bc1aebe0756 to your computer and use it in GitHub Desktop.
An implementation of the BlackJack Helper coding challenge on CoderRadio
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
/* Slightly more logic to implement the implicit rules
*
* Program expects a single string as the input
* The first character is the dealers card the rest are the players cards
*
* Example: BlackJack Helper.exe 43T5
* Dealer has a 4
* Player has a 3 and a Ten and a Five
*/
namespace Blackjack_Helper {
class Program {
public const string Hit = "Hit";
public const string Stand = "Stand";
public const string Double = "Double if allowed, otherwise Hit";
public const string DoubleStand = "Double if allowed, otherwise Stand";
public const string Split = "Split";
public const string SurrenderOrHit = "Surrender if allowed, otherwise Hit";
public const string SurrenderOrSplit = "Surrender if allowed, otherwise Split";
public const string SurrenderOrStand = "Surrender if allowed, otherwise Stand";
public const string HelpText = "[Dealer card][Players cards]. Cards = 2,3,4,5,6,7,8,9,T,A";
static void Main(string[] args)
{
new Program(Console.In, Console.Out);
}
public Program(TextReader input, TextWriter output)
{
var cards = input.ReadLine();
if (cards == null || cards.Length < 3) {
output.Write(HelpText);
return;
}
var dealersIndex = new List<char> { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'A' }.IndexOf(cards.First());
var playersHand = new Hand(cards.Substring(1));
var rule = FindRule(playersHand, dealersIndex);
output.Write(rule);
}
private string FindRule(Hand playersHand, int dealersIndex)
{
if (playersHand.CanSplit)
return FindSplitRule(playersHand, dealersIndex);
if (playersHand.IsSoft)
return FindSoftRule(playersHand, dealersIndex);
return FindNormalRule(playersHand, dealersIndex);
}
private static string FindSplitRule(Hand playersHand, int dealersIndex)
{
return new Dictionary<int, string[]>()
{
[2] = new[] { Split, Split, Split, Split, Split, Split, Split, Split, Split, Split },
[4] = new[] { Split, Split, Split, Split, Split, Split, Hit, Hit, Hit, Hit },
[6] = new[] { Split, Split, Split, Split, Split, Split, Hit, Hit, Hit, Hit },
[8] = new[] { Hit, Hit, Hit, Split, Split, Hit, Hit, Hit, Hit, Hit },
[10] = new[] { Double, Double, Double, Double, Double, Double, Double, Double, Hit, Hit },
[12] = new[] { Split, Split, Split, Split, Split, Hit, Hit, Hit, Hit, Hit },
[14] = new[] { Split, Split, Split, Split, Split, Split, Hit, Hit, Hit, Hit },
[16] = new[] { Split, Split, Split, Split, Split, Split, Split, Split, Split, SurrenderOrSplit },
[19] = new[] { Split, Split, Split, Split, Split, Stand, Split, Split, Stand, Stand },
[20] = new[] { Stand, Stand, Stand, Stand, Stand, Stand, Stand, Stand, Stand, Stand }
}[playersHand.Value][dealersIndex];
}
private static string FindSoftRule(Hand playersHand, int dealersIndex)
{
return new Dictionary<int, string[]>
{
[3] = new[] { Hit, Hit, Hit, Double, Double, Hit, Hit, Hit, Hit, Hit },
[4] = new[] { Hit, Hit, Hit, Double, Double, Hit, Hit, Hit, Hit, Hit },
[5] = new[] { Hit, Hit, Double, Double, Double, Hit, Hit, Hit, Hit, Hit },
[6] = new[] { Hit, Hit, Double, Double, Double, Hit, Hit, Hit, Hit, Hit },
[7] = new[] { Hit, Double, Double, Double, Double, Hit, Hit, Hit, Hit, Hit },
[8] = new[] { Stand, DoubleStand, DoubleStand, DoubleStand, DoubleStand, Stand, Stand, Hit, Hit, Hit }
}[playersHand.Value][dealersIndex];
}
private static string FindNormalRule(Hand playersHand, int dealersIndex)
{
if (playersHand.Value < 8) return Hit;
if (playersHand.Value >= 17) return Stand;
return new Dictionary<int, string[]>
{
[8] = new[] { Hit, Hit, Hit, Hit, Hit, Hit, Hit, Hit, Hit, Hit },
[9] = new[] { Hit, Double, Double, Double, Double, Hit, Hit, Hit, Hit, Hit },
[10] = new[] { Double, Double, Double, Double, Double, Double, Double, Double, Hit, Hit },
[11] = new[] { Double, Double, Double, Double, Double, Double, Double, Double, Double, Double },
[12] = new[] { Hit, Hit, Stand, Stand, Stand, Hit, Hit, Hit, Hit, Hit },
[13] = new[] { Stand, Stand, Stand, Stand, Stand, Hit, Hit, Hit, Hit, Hit },
[14] = new[] { Stand, Stand, Stand, Stand, Stand, Hit, Hit, Hit, Hit, Hit },
[15] = new[] { Stand, Stand, Stand, Stand, Stand, Hit, Hit, Hit, SurrenderOrHit, SurrenderOrHit },
[16] = new[] { Stand, Stand, Stand, Stand, Stand, Hit, Hit, SurrenderOrHit, SurrenderOrHit, SurrenderOrHit },
[17] = new[] { Stand, Stand, Stand, Stand, Stand, Stand, Stand, Stand, Stand, SurrenderOrStand }
}[playersHand.Value][dealersIndex];
}
}
class Hand {
private readonly string _hand;
private readonly int _softValue;
private readonly int _hardValue;
public Hand(string hand)
{
_hand = hand.ToUpper();
var values = CalculateHandValue(hand);
_softValue = values.Item1;
_hardValue = values.Item2;
}
private Tuple<int, int> CalculateHandValue(string hand)
{
var aces = hand.Count(m => m == 'A');
var hard = hand.ToCharArray().Sum(c => {
if (c == 'A') return 11;
if (c == 'T') return 10;
return (int)char.GetNumericValue(c);
});
var soft = hard - (aces * 10);
while (hard > 21 && aces-- > 0)
hard -= 10;
return Tuple.Create(soft, hard);
}
public bool CanSplit => _hand.Length == 2 && _hand.All(card => card == _hand.First());
public bool IsSoft => _softValue <= 8 && _softValue != _hardValue;
public int Value => IsSoft ? _softValue : _hardValue;
}
public class Tests {
// 12
[TestCase("248", Program.Hit)]
[TestCase("557", Program.Stand)]
// 15
[TestCase("TT5", Program.SurrenderOrHit)]
[TestCase("T5T", Program.SurrenderOrHit)]
// Soft
[TestCase("3A7", Program.DoubleStand)]
[TestCase("3A34", Program.DoubleStand)]
[TestCase("342AA", Program.DoubleStand)]
[TestCase("37A", Program.DoubleStand)]
[TestCase("38A", Program.Stand)]
// Split (12)
[TestCase("566", Program.Split)]
public void HappyPath(string input, string expectedOutput)
{
TextReader inputStream = new StringReader(input);
TextWriter outputStream = new StringWriter(new StringBuilder());
new Program(inputStream, outputStream);
Assert.That(outputStream.ToString(), Is.EqualTo(expectedOutput));
}
[TestCase("")]
[TestCase("AA")]
[TestCase("/?")]
public void IncorrectInput(string input)
{
HappyPath(input, Program.HelpText);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment