-
-
Notifications
You must be signed in to change notification settings - Fork 657
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #686 from leenipper/poker-add-generator
poker: create test case generator
- Loading branch information
Showing
4 changed files
with
327 additions
and
225 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"strings" | ||
"text/template" | ||
|
||
"../../../gen" | ||
) | ||
|
||
func main() { | ||
t := template.New("").Funcs(template.FuncMap{ | ||
"pokerHands": PokerHands, | ||
}) | ||
t, err := t.Parse(tmpl) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
var j js | ||
if err := gen.Gen("poker", &j, t); err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
// The JSON structure we expect to be able to unmarshal into | ||
type js struct { | ||
Cases []struct { | ||
Description string | ||
Input []string | ||
Expected []string | ||
} | ||
} | ||
|
||
var suitCharToSymbol = map[byte]string{'C': "♧", 'D': "♢", 'H': "♡", 'S': "♤"} | ||
|
||
// PokerHands converts hands using C/D/H/S as the suit | ||
// to one which uses the symbols ♧ / ♢ / ♡ / ♤ instead. | ||
// For example, "2H 3C 4D 5S 9S" is converted to "2♡ 3♧ 4♢ 5♤ 9♤". | ||
func PokerHands(inputHands []string) []string { | ||
hands := make([]string, len(inputHands)) | ||
for i, inputHand := range inputHands { | ||
cards := strings.Fields(inputHand) | ||
handStr := "" | ||
for j, c := range cards { | ||
rankStr := c[0 : len(c)-1] | ||
handStr += rankStr + suitCharToSymbol[c[len(c)-1]] | ||
if j != len(cards)-1 { | ||
handStr += " " | ||
} | ||
} | ||
hands[i] = handStr | ||
} | ||
return hands | ||
} | ||
|
||
// template applied to above data structure generates the Go test cases | ||
var tmpl = `package poker | ||
{{.Header}} | ||
type validTestCase struct { | ||
name string | ||
hands []string | ||
best []string | ||
} | ||
var validTestCases = []validTestCase { | ||
{{range .J.Cases}}{ | ||
name: "{{.Description}}", | ||
hands: []string{ | ||
{{range pokerHands .Input}} {{printf "%q" .}}, | ||
{{end}} }, | ||
best: {{pokerHands .Expected | printf "%#v"}}, | ||
}, | ||
{{end}}} | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
package poker | ||
|
||
// Source: exercism/x-common | ||
// Commit: d078ba8 poker: Add canonical-data (#793) | ||
// x-common version: 1.0.0 | ||
|
||
type validTestCase struct { | ||
name string | ||
hands []string | ||
best []string | ||
} | ||
|
||
var validTestCases = []validTestCase{ | ||
{ | ||
name: "single hand always wins", | ||
hands: []string{ | ||
"4♤ 5♤ 7♡ 8♢ J♧", | ||
}, | ||
best: []string{"4♤ 5♤ 7♡ 8♢ J♧"}, | ||
}, | ||
{ | ||
name: "highest card out of all hands wins", | ||
hands: []string{ | ||
"4♢ 5♤ 6♤ 8♢ 3♧", | ||
"2♤ 4♧ 7♤ 9♡ 10♡", | ||
"3♤ 4♤ 5♢ 6♡ J♡", | ||
}, | ||
best: []string{"3♤ 4♤ 5♢ 6♡ J♡"}, | ||
}, | ||
{ | ||
name: "a tie has multiple winners", | ||
hands: []string{ | ||
"4♢ 5♤ 6♤ 8♢ 3♧", | ||
"2♤ 4♧ 7♤ 9♡ 10♡", | ||
"3♤ 4♤ 5♢ 6♡ J♡", | ||
"3♡ 4♡ 5♧ 6♧ J♢", | ||
}, | ||
best: []string{"3♤ 4♤ 5♢ 6♡ J♡", "3♡ 4♡ 5♧ 6♧ J♢"}, | ||
}, | ||
{ | ||
name: "multiple hands with the same high cards, tie compares next highest ranked, down to last card", | ||
hands: []string{ | ||
"3♤ 5♡ 6♤ 8♢ 7♡", | ||
"2♤ 5♢ 6♢ 8♧ 7♤", | ||
}, | ||
best: []string{"3♤ 5♡ 6♤ 8♢ 7♡"}, | ||
}, | ||
{ | ||
name: "one pair beats high card", | ||
hands: []string{ | ||
"4♤ 5♡ 6♧ 8♢ K♡", | ||
"2♤ 4♡ 6♤ 4♢ J♡", | ||
}, | ||
best: []string{"2♤ 4♡ 6♤ 4♢ J♡"}, | ||
}, | ||
{ | ||
name: "highest pair wins", | ||
hands: []string{ | ||
"4♤ 2♡ 6♤ 2♢ J♡", | ||
"2♤ 4♡ 6♧ 4♢ J♢", | ||
}, | ||
best: []string{"2♤ 4♡ 6♧ 4♢ J♢"}, | ||
}, | ||
{ | ||
name: "two pairs beats one pair", | ||
hands: []string{ | ||
"2♤ 8♡ 6♤ 8♢ J♡", | ||
"4♤ 5♡ 4♧ 8♧ 5♧", | ||
}, | ||
best: []string{"4♤ 5♡ 4♧ 8♧ 5♧"}, | ||
}, | ||
{ | ||
name: "both hands have two pairs, highest ranked pair wins", | ||
hands: []string{ | ||
"2♤ 8♡ 2♢ 8♢ 3♡", | ||
"4♤ 5♡ 4♧ 8♤ 5♢", | ||
}, | ||
best: []string{"2♤ 8♡ 2♢ 8♢ 3♡"}, | ||
}, | ||
{ | ||
name: "both hands have two pairs, with the same highest ranked pair, tie goes to low pair", | ||
hands: []string{ | ||
"2♤ Q♤ 2♧ Q♢ J♡", | ||
"J♢ Q♡ J♤ 8♢ Q♧", | ||
}, | ||
best: []string{"J♢ Q♡ J♤ 8♢ Q♧"}, | ||
}, | ||
{ | ||
name: "both hands have two identically ranked pairs, tie goes to remaining card (kicker)", | ||
hands: []string{ | ||
"J♢ Q♡ J♤ 8♢ Q♧", | ||
"J♤ Q♤ J♧ 2♢ Q♢", | ||
}, | ||
best: []string{"J♢ Q♡ J♤ 8♢ Q♧"}, | ||
}, | ||
{ | ||
name: "three of a kind beats two pair", | ||
hands: []string{ | ||
"2♤ 8♡ 2♡ 8♢ J♡", | ||
"4♤ 5♡ 4♧ 8♤ 4♡", | ||
}, | ||
best: []string{"4♤ 5♡ 4♧ 8♤ 4♡"}, | ||
}, | ||
{ | ||
name: "both hands have three of a kind, tie goes to highest ranked triplet", | ||
hands: []string{ | ||
"2♤ 2♡ 2♧ 8♢ J♡", | ||
"4♤ A♡ A♤ 8♧ A♢", | ||
}, | ||
best: []string{"4♤ A♡ A♤ 8♧ A♢"}, | ||
}, | ||
{ | ||
name: "with multiple decks, two players can have same three of a kind, ties go to highest remaining cards", | ||
hands: []string{ | ||
"4♤ A♡ A♤ 7♧ A♢", | ||
"4♤ A♡ A♤ 8♧ A♢", | ||
}, | ||
best: []string{"4♤ A♡ A♤ 8♧ A♢"}, | ||
}, | ||
{ | ||
name: "a straight beats three of a kind", | ||
hands: []string{ | ||
"4♤ 5♡ 4♧ 8♢ 4♡", | ||
"3♤ 4♢ 2♤ 6♢ 5♧", | ||
}, | ||
best: []string{"3♤ 4♢ 2♤ 6♢ 5♧"}, | ||
}, | ||
{ | ||
name: "aces can end a straight (10 J Q K A)", | ||
hands: []string{ | ||
"4♤ 5♡ 4♧ 8♢ 4♡", | ||
"10♢ J♡ Q♤ K♢ A♧", | ||
}, | ||
best: []string{"10♢ J♡ Q♤ K♢ A♧"}, | ||
}, | ||
{ | ||
name: "aces can start a straight (A 2 3 4 5)", | ||
hands: []string{ | ||
"4♤ 5♡ 4♧ 8♢ 4♡", | ||
"4♢ A♡ 3♤ 2♢ 5♧", | ||
}, | ||
best: []string{"4♢ A♡ 3♤ 2♢ 5♧"}, | ||
}, | ||
{ | ||
name: "both hands with a straight, tie goes to highest ranked card", | ||
hands: []string{ | ||
"4♤ 6♧ 7♤ 8♢ 5♡", | ||
"5♤ 7♡ 8♤ 9♢ 6♡", | ||
}, | ||
best: []string{"5♤ 7♡ 8♤ 9♢ 6♡"}, | ||
}, | ||
{ | ||
name: "even though an ace is usually high, a 5-high straight is the lowest-scoring straight", | ||
hands: []string{ | ||
"2♡ 3♧ 4♢ 5♢ 6♡", | ||
"4♤ A♡ 3♤ 2♢ 5♡", | ||
}, | ||
best: []string{"2♡ 3♧ 4♢ 5♢ 6♡"}, | ||
}, | ||
{ | ||
name: "flush beats a straight", | ||
hands: []string{ | ||
"4♧ 6♡ 7♢ 8♢ 5♡", | ||
"2♤ 4♤ 5♤ 6♤ 7♤", | ||
}, | ||
best: []string{"2♤ 4♤ 5♤ 6♤ 7♤"}, | ||
}, | ||
{ | ||
name: "both hands have a flush, tie goes to high card, down to the last one if necessary", | ||
hands: []string{ | ||
"4♡ 7♡ 8♡ 9♡ 6♡", | ||
"2♤ 4♤ 5♤ 6♤ 7♤", | ||
}, | ||
best: []string{"4♡ 7♡ 8♡ 9♡ 6♡"}, | ||
}, | ||
{ | ||
name: "full house beats a flush", | ||
hands: []string{ | ||
"3♡ 6♡ 7♡ 8♡ 5♡", | ||
"4♤ 5♡ 4♧ 5♢ 4♡", | ||
}, | ||
best: []string{"4♤ 5♡ 4♧ 5♢ 4♡"}, | ||
}, | ||
{ | ||
name: "both hands have a full house, tie goes to highest-ranked triplet", | ||
hands: []string{ | ||
"4♡ 4♤ 4♢ 9♤ 9♢", | ||
"5♡ 5♤ 5♢ 8♤ 8♢", | ||
}, | ||
best: []string{"5♡ 5♤ 5♢ 8♤ 8♢"}, | ||
}, | ||
{ | ||
name: "with multiple decks, both hands have a full house with the same triplet, tie goes to the pair", | ||
hands: []string{ | ||
"5♡ 5♤ 5♢ 9♤ 9♢", | ||
"5♡ 5♤ 5♢ 8♤ 8♢", | ||
}, | ||
best: []string{"5♡ 5♤ 5♢ 9♤ 9♢"}, | ||
}, | ||
{ | ||
name: "four of a kind beats a full house", | ||
hands: []string{ | ||
"4♤ 5♡ 4♢ 5♢ 4♡", | ||
"3♤ 3♡ 2♤ 3♢ 3♧", | ||
}, | ||
best: []string{"3♤ 3♡ 2♤ 3♢ 3♧"}, | ||
}, | ||
{ | ||
name: "both hands have four of a kind, tie goes to high quad", | ||
hands: []string{ | ||
"2♤ 2♡ 2♧ 8♢ 2♢", | ||
"4♤ 5♡ 5♤ 5♢ 5♧", | ||
}, | ||
best: []string{"4♤ 5♡ 5♤ 5♢ 5♧"}, | ||
}, | ||
{ | ||
name: "with multiple decks, both hands with identical four of a kind, tie determined by kicker", | ||
hands: []string{ | ||
"3♤ 3♡ 2♤ 3♢ 3♧", | ||
"3♤ 3♡ 4♤ 3♢ 3♧", | ||
}, | ||
best: []string{"3♤ 3♡ 4♤ 3♢ 3♧"}, | ||
}, | ||
{ | ||
name: "straight flush beats four of a kind", | ||
hands: []string{ | ||
"4♤ 5♡ 5♤ 5♢ 5♧", | ||
"7♤ 8♤ 9♤ 6♤ 10♤", | ||
}, | ||
best: []string{"7♤ 8♤ 9♤ 6♤ 10♤"}, | ||
}, | ||
{ | ||
name: "both hands have straight flush, tie goes to highest-ranked card", | ||
hands: []string{ | ||
"4♡ 6♡ 7♡ 8♡ 5♡", | ||
"5♤ 7♤ 8♤ 9♤ 6♤", | ||
}, | ||
best: []string{"5♤ 7♤ 8♤ 9♤ 6♤"}, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.