399 lines
8.1 KiB
Go
399 lines
8.1 KiB
Go
package blackjack
|
|
|
|
import "testing"
|
|
|
|
func TestParseCard(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
card string
|
|
want int
|
|
}{
|
|
{
|
|
name: "parse ace",
|
|
card: "ace",
|
|
want: 11,
|
|
},
|
|
{
|
|
name: "parse two",
|
|
card: "two",
|
|
want: 2,
|
|
},
|
|
{
|
|
name: "parse three",
|
|
card: "three",
|
|
want: 3,
|
|
},
|
|
{
|
|
name: "parse four",
|
|
card: "four",
|
|
want: 4,
|
|
},
|
|
{
|
|
name: "parse five",
|
|
card: "five",
|
|
want: 5,
|
|
},
|
|
{
|
|
name: "parse six",
|
|
card: "six",
|
|
want: 6,
|
|
},
|
|
{
|
|
name: "parse seven",
|
|
card: "seven",
|
|
want: 7,
|
|
},
|
|
{
|
|
name: "parse eight",
|
|
card: "eight",
|
|
want: 8,
|
|
},
|
|
{
|
|
name: "parse nine",
|
|
card: "nine",
|
|
want: 9,
|
|
},
|
|
{
|
|
name: "parse ten",
|
|
card: "ten",
|
|
want: 10,
|
|
},
|
|
{
|
|
name: "parse jack",
|
|
card: "jack",
|
|
want: 10,
|
|
},
|
|
{
|
|
name: "parse queen",
|
|
card: "queen",
|
|
want: 10,
|
|
},
|
|
{
|
|
name: "parse king",
|
|
card: "king",
|
|
want: 10,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := ParseCard(tt.card); got != tt.want {
|
|
t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBlackjack(t *testing.T) {
|
|
type hand struct {
|
|
card1, card2 string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
hand hand
|
|
want bool
|
|
}{
|
|
{
|
|
name: "blackjack with ten (ace first)",
|
|
hand: hand{card1: "ace", card2: "ten"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with jack (ace first)",
|
|
hand: hand{card1: "ace", card2: "jack"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with queen (ace first)",
|
|
hand: hand{card1: "ace", card2: "queen"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with king (ace first)",
|
|
hand: hand{card1: "ace", card2: "king"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with ten (ace second)",
|
|
hand: hand{card2: "ace", card1: "ten"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with jack (ace second)",
|
|
hand: hand{card2: "ace", card1: "jack"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with queen (ace second)",
|
|
hand: hand{card2: "ace", card1: "queen"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "blackjack with king (ace second)",
|
|
hand: hand{card2: "ace", card1: "king"},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "no blackjack with ace and five",
|
|
hand: hand{card2: "ace", card1: "five"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no blackjack with ace and nine",
|
|
hand: hand{card2: "ace", card1: "nine"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no blackjack with two aces",
|
|
hand: hand{card2: "ace", card1: "ace"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no blackjack with two figures",
|
|
hand: hand{card2: "queen", card1: "jack"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no blackjack with king and five",
|
|
hand: hand{card2: "king", card1: "five"},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no blackjack with eight and five",
|
|
hand: hand{card2: "eight", card1: "five"},
|
|
want: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := IsBlackjack(tt.hand.card1, tt.hand.card2); got != tt.want {
|
|
t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFirstTurn(t *testing.T) {
|
|
type hand struct {
|
|
card1, card2 string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
hand hand
|
|
dealer string
|
|
want string
|
|
}{
|
|
{
|
|
name: "pair of aces",
|
|
hand: hand{card1: "ace", card2: "ace"},
|
|
dealer: "ace",
|
|
want: "P",
|
|
},
|
|
{
|
|
name: "pair of jacks",
|
|
hand: hand{card1: "jack", card2: "jack"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "pair of kings",
|
|
hand: hand{card1: "king", card2: "king"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "pair of twos",
|
|
hand: hand{card1: "two", card2: "two"},
|
|
dealer: "ace",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "pair of fives",
|
|
hand: hand{card1: "five", card2: "five"},
|
|
dealer: "ace",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "blackjack with ace for dealer",
|
|
hand: hand{card1: "ace", card2: "jack"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "blackjack with queen for dealer",
|
|
hand: hand{card1: "king", card2: "ace"},
|
|
dealer: "queen",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "blackjack with five for dealer",
|
|
hand: hand{card1: "ace", card2: "ten"},
|
|
dealer: "five",
|
|
want: "W",
|
|
},
|
|
{
|
|
name: "blackjack with nine for dealer",
|
|
hand: hand{card1: "ace", card2: "king"},
|
|
dealer: "nine",
|
|
want: "W",
|
|
},
|
|
{
|
|
name: "score of 20",
|
|
hand: hand{card1: "ten", card2: "king"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 19",
|
|
hand: hand{card1: "ten", card2: "nine"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 18",
|
|
hand: hand{card1: "ten", card2: "eight"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 17",
|
|
hand: hand{card1: "seven", card2: "king"},
|
|
dealer: "ace",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 16 with six for dealer",
|
|
hand: hand{card1: "ten", card2: "six"},
|
|
dealer: "six",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 16 with seven for dealer",
|
|
hand: hand{card1: "ten", card2: "six"},
|
|
dealer: "seven",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 16 with ace for dealer",
|
|
hand: hand{card1: "ten", card2: "six"},
|
|
dealer: "ace",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 15 with six for dealer",
|
|
hand: hand{card1: "ten", card2: "five"},
|
|
dealer: "six",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 15 with seven for dealer",
|
|
hand: hand{card1: "ten", card2: "five"},
|
|
dealer: "seven",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 15 with king for dealer",
|
|
hand: hand{card1: "ten", card2: "five"},
|
|
dealer: "king",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 14 with six for dealer",
|
|
hand: hand{card1: "ten", card2: "four"},
|
|
dealer: "six",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 14 with seven for dealer",
|
|
hand: hand{card1: "ten", card2: "four"},
|
|
dealer: "seven",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 14 with queen for dealer",
|
|
hand: hand{card1: "ten", card2: "four"},
|
|
dealer: "queen",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 13 with six for dealer",
|
|
hand: hand{card1: "ten", card2: "three"},
|
|
dealer: "six",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 13 with seven for dealer",
|
|
hand: hand{card1: "ten", card2: "three"},
|
|
dealer: "seven",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 13 with queen for dealer",
|
|
hand: hand{card1: "ten", card2: "three"},
|
|
dealer: "queen",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 12 with six for dealer",
|
|
hand: hand{card1: "ten", card2: "two"},
|
|
dealer: "six",
|
|
want: "S",
|
|
},
|
|
{
|
|
name: "score of 12 with seven for dealer",
|
|
hand: hand{card1: "ten", card2: "two"},
|
|
dealer: "seven",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 12 with queen for dealer",
|
|
hand: hand{card1: "ten", card2: "two"},
|
|
dealer: "queen",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 11 with queen for dealer",
|
|
hand: hand{card1: "nine", card2: "two"},
|
|
dealer: "queen",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 10 with two for dealer",
|
|
hand: hand{card1: "eight", card2: "two"},
|
|
dealer: "two",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 5 with queen for dealer",
|
|
hand: hand{card1: "three", card2: "two"},
|
|
dealer: "queen",
|
|
want: "H",
|
|
},
|
|
{
|
|
name: "score of 4 with five for dealer",
|
|
hand: hand{card1: "two", card2: "two"},
|
|
dealer: "five",
|
|
want: "H",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := FirstTurn(tt.hand.card1, tt.hand.card2, tt.dealer); got != tt.want {
|
|
t.Errorf("FirstTurn(%s, %s, %s) = %s, want %s", tt.hand.card1, tt.hand.card2, tt.dealer, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// FirstTurn returns the semi-optimal decision for the first turn, given the cards of the player and the dealer.
|
|
// This function is already implemented and does not need to be edited. It pulls the other functions together in a
|
|
// complete decision tree for the first turn.
|
|
func FirstTurn(card1, card2, dealerCard string) string {
|
|
handScore := ParseCard(card1) + ParseCard(card2)
|
|
dealerScore := ParseCard(dealerCard)
|
|
|
|
if 20 < handScore {
|
|
return LargeHand(IsBlackjack(card1, card2), dealerScore)
|
|
}
|
|
return SmallHand(handScore, dealerScore)
|
|
}
|