Building a Blackjack Calculator in .NET: A Step-by-Step Tutorial

Building a Blackjack Calculator in .NET: A Step-by-Step Tutorial

Blackjack is a game of skill and probability where players can improve their odds by following basic strategy – a mathematically optimal way to play each hand. In this tutorial, we’ll build a Blackjack Calculator in .NET (C#) that helps players make the best decisions based on their hand and the dealer’s upcard.

We’ll use the basic strategy rules from SevenJackpots’ Blackjack Guide to determine the correct moves (Hit, Stand, Double, Split, or Surrender).

Prerequisites

  • Visual Studio (2022 or later)
  • Basic knowledge of C# and .NET
  • Understanding of blackjack rules

Step 1: Create a New .NET Console Application

  1. Open Visual Studio and create a new Console App (.NET Core) project
  2. Name it BlackjackCalculator and click Create

Step 2: Define the Blackjack Strategy Rules
We’ll encode the basic strategy into a structured format. The strategy depends on:

  • Player’s hand (hard totals, soft totals, pairs)
  • Dealer’s upcard (2 through Ace)

Hard Totals (No Ace in Hand)
For hands like 10-6 (16) or 9-7 (16), the strategy is different than if the player has an Ace.

Soft Totals (Ace + Another Card)
An Ace can be 1 or 11, so hands like A-5 (Soft 16) require different decisions.

Pairs (Splitting Logic)
If the player has two identical cards (e.g., 8-8), the calculator should recommend whether to Split.

We’ll store these rules in dictionaries for quick lookup.

Step 3: Implement the Blackjack Logic

1. Define the Strategy Tables

Add the following dictionaries to Program.cs:

using System;
using System.Collections.Generic;

class Program
{
 // Hard totals (player's hand without an Ace)
 private static readonly Dictionary<int, Dictionary<int, string>> HardTotals = new()
 {
    	{ 8, new Dictionary<int, string> { { 2, "H" }, { 3, "H" }, /* ... up to Ace */ } },
    	{ 9, new Dictionary<int, string> { { 2, "H" }, { 3, "D" }, /* ... */ } },
    	// Continue for all hard totals (5-21)
 };

 // Soft totals (player has an Ace)
 private static readonly Dictionary<int, Dictionary<int, string>> SoftTotals = new()
 {
    	{ 13, new Dictionary<int, string> { { 2, "H" }, { 3, "H" }, /* ... */ } },
    	// Continue for all soft totals (A2 to A9)
 };

 // Pairs (when player can split)
 private static readonly Dictionary<int, Dictionary<int, string>> Pairs = new()
 {
    	{ 2, new Dictionary<int, string> { { 2, "P" }, { 3, "P" }, /* ... */ } },
    	// Continue for all pairs (2-10, A)
 };
}
2. Create a Method to Get the Best Move

Add a method that checks the player’s hand and dealer’s upcard to return the optimal move:

static string GetOptimalMove(int playerTotal, bool isSoft, bool isPair, int dealerUpcard)
{
 if (isPair && Pairs.TryGetValue(playerTotal / 2, out var pairStrategy))
 {
    	if (pairStrategy.TryGetValue(dealerUpcard, out var move))
        	return move;
 }
 else if (isSoft && SoftTotals.TryGetValue(playerTotal, out var softStrategy))
 {
    	if (softStrategy.TryGetValue(dealerUpcard, out var move))
        	return move;
 }
 else if (HardTotals.TryGetValue(playerTotal, out var hardStrategy))
 {
    	if (hardStrategy.TryGetValue(dealerUpcard, out var move))
        	return move;
 }

 return "H"; // Default to Hit if no strategy found
}
3. Convert Move Codes to Readable Actions

Add a helper method to display H (Hit), S (Stand), D (Double), P (Split), or R (Surrender):

static string GetMoveDescription(string moveCode)
{
 return moveCode switch
 {
    	"H" => "Hit",
    	"S" => "Stand",
    	"D" => "Double Down",
    	"P" => "Split",
    	"R" => "Surrender",
    	_ => "Unknown"
 };
}
Step 4: Build the User Interface

Now, let’s create a simple console-based UI where the user inputs their hand and the dealer’s upcard.

static void Main()
{
 Console.WriteLine("=== BLACKJACK STRATEGY CALCULATOR ===");
    
 while (true)
 {
    	Console.WriteLine("\nEnter your hand (e.g., '10 6' for 16, 'A 5' for soft 16):");
    	string[] playerInput = Console.ReadLine().Split(' ');
   	 
    	Console.WriteLine("Enter dealer's upcard (2-10, J, Q, K, A):");
    	string dealerInput = Console.ReadLine();

    	// Parse player's hand
    	int playerTotal = 0;
    	bool isSoft = false;
    	bool isPair = playerInput.Length == 2 && playerInput[0] == playerInput[1];

    	foreach (string card in playerInput)
    	{
        	if (card == "A")
        	{
            	playerTotal += 11;
            	isSoft = true;
        	}
        	else if (int.TryParse(card, out int value))
            	playerTotal += value;
        	else if (card == "J" || card == "Q" || card == "K")
            	playerTotal += 10;
    	}

    	// Parse dealer's upcard
    	int dealerUpcard = dealerInput switch
    	{
        	"A" => 11,
        	"J" or "Q" or "K" => 10,
        	_ => int.Parse(dealerInput)
    	};

    	// Get optimal move
    	string move = GetOptimalMove(playerTotal, isSoft, isPair, dealerUpcard);
    	Console.WriteLine($"\nOptimal Move: {GetMoveDescription(move)}");

    	Console.WriteLine("\nCalculate again? (Y/N)");
    	if (Console.ReadLine().ToUpper() != "Y")
        	break;
 }
}
Step 5: Test the Blackjack Calculator

Run the program and test different scenarios:

Example 1: Hard 16 vs. Dealer 10

  • Input: 10 6 (Player: 16)
  • Dealer: 10
  • Expected Output: Stand (if surrender is unavailable) or Hit (if surrender is allowed)

Example 2: Soft 18 vs. Dealer 9

  • Input: A 7 (Player: Soft 18)
  • Dealer: 9
  • Expected Output: Stand

Example 3: Pair of 8s vs. Dealer 5

  • Input: 8 8 (Player: Pair of 8s)
  • Dealer: 5
  • Expected Output: Split

You’ve just built a Blackjack Strategy Calculator in .NET (C#)! This tool will help players make optimal decisions based on mathematically proven blackjack strategies.

Registration Open – Microservices with ASP.NET Core Web API

New Batch Starts: 7th July 2025
Session Time: 6:30 AM – 8:00 AM IST

Advance your career with our expert-led, hands-on live training program. Get complete course details, the syllabus, registration, and Zoom credentials for demo sessions via the links below.

Contact: +91 70218 01173 (Call / WhatsApp)