2019-05-31 12:07:49 +00:00
|
|
|
package draft_test
|
2019-05-31 08:57:51 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math/rand"
|
|
|
|
"testing"
|
2019-05-31 12:07:49 +00:00
|
|
|
|
|
|
|
"git.fromouter.space/mcg/draft"
|
2019-05-31 08:57:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// TestSetRepeatable makes sure that a set can generate more cards than it contains
|
|
|
|
func TestSetRepeatable(t *testing.T) {
|
|
|
|
const PACKSIZE = 5
|
2019-05-31 12:07:49 +00:00
|
|
|
s := &draft.GenericSet{
|
|
|
|
Cards: []draft.Card{{ID: "a"}, {ID: "b"}, {ID: "c"}},
|
2019-05-31 08:57:51 +00:00
|
|
|
PackSize: PACKSIZE,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a pack
|
2019-05-31 12:07:49 +00:00
|
|
|
pack := draft.MakePack(s)
|
2019-05-31 08:57:51 +00:00
|
|
|
|
|
|
|
if len(pack) < PACKSIZE {
|
|
|
|
t.Errorf("Pack expected to contain %d cards, contains %d", PACKSIZE, len(pack))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that all cards have something in it
|
|
|
|
for i, card := range pack {
|
|
|
|
if card.ID == "" {
|
|
|
|
t.Errorf("Pack contains \"empty\" card")
|
|
|
|
}
|
|
|
|
if card.ID != "a" && card.ID != "b" && card.ID != "c" {
|
|
|
|
t.Errorf("Pack contains unexpected card %s at index %d, not contained in pool", card.ID, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestAlternateProviders tests alternate providers
|
|
|
|
func TestAlternateProviders(t *testing.T) {
|
2019-05-31 12:07:49 +00:00
|
|
|
customProvider := func(n int) []draft.Card {
|
|
|
|
out := make([]draft.Card, n)
|
2019-05-31 08:57:51 +00:00
|
|
|
for n := range out {
|
2019-05-31 12:07:49 +00:00
|
|
|
out[n] = draft.Card{ID: "x"}
|
2019-05-31 08:57:51 +00:00
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
2019-05-31 12:07:49 +00:00
|
|
|
s := &draft.GenericSet{
|
|
|
|
Cards: []draft.Card{{ID: "a"}, {ID: "b"}, {ID: "c"}},
|
2019-05-31 08:57:51 +00:00
|
|
|
PackSize: 1,
|
2019-05-31 12:07:49 +00:00
|
|
|
Alternates: []draft.AlternateProvider{
|
2019-05-31 08:57:51 +00:00
|
|
|
{
|
|
|
|
Probability: 0.3,
|
|
|
|
Provider: customProvider,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
// Use set seed for getting deterministic results
|
|
|
|
rand.Seed(0)
|
|
|
|
|
|
|
|
nonalternates, alternates := 0, 0
|
|
|
|
for i := 0; i < 500000; i++ {
|
2019-05-31 12:07:49 +00:00
|
|
|
pack := draft.MakePack(s)
|
2019-05-31 08:57:51 +00:00
|
|
|
if pack[0].ID == "x" {
|
|
|
|
alternates++
|
|
|
|
} else {
|
|
|
|
nonalternates++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate distribution
|
|
|
|
distribution := float32(float32(alternates) / (float32(nonalternates) + float32(alternates)))
|
|
|
|
|
|
|
|
// After 500k packs, I'm expecting distribution to be within 2%
|
|
|
|
if distribution < 0.29 || distribution > 0.31 {
|
|
|
|
t.Errorf("Distribution is sketchy after 500k packs: %f%%", distribution*100)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestCubeOverflow makes sure cubes stop providing cards as they are exhausted instead of going out of bound
|
|
|
|
func TestCubeOverflow(t *testing.T) {
|
|
|
|
const PACKSIZE = 5
|
2019-05-31 12:07:49 +00:00
|
|
|
c := &draft.GenericCube{
|
|
|
|
Cards: []draft.Card{
|
2019-05-31 08:57:51 +00:00
|
|
|
{ID: "a"}, {ID: "b"}, {ID: "c"}, {ID: "d"}, {ID: "e"},
|
|
|
|
{ID: "f"}, {ID: "g"}, {ID: "h"}, {ID: "i"},
|
|
|
|
},
|
|
|
|
PackSize: PACKSIZE,
|
|
|
|
}
|
|
|
|
|
2019-05-31 12:07:49 +00:00
|
|
|
pack1 := draft.MakePack(c)
|
|
|
|
pack2 := draft.MakePack(c)
|
2019-05-31 08:57:51 +00:00
|
|
|
|
|
|
|
// Pack 2 can only contain 4 cards, as there are not enough cards to fill it
|
|
|
|
if len(pack2) >= PACKSIZE {
|
|
|
|
t.Errorf("Pack 2 expected to contain only 4 cards, has %d", len(pack2))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for duplicates
|
|
|
|
allcards := append(pack1, pack2...)
|
|
|
|
uniq := sliceUniq(allcards)
|
|
|
|
if len(allcards) != len(uniq) {
|
|
|
|
t.Errorf("Duplicate cards found across packs")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-31 12:07:49 +00:00
|
|
|
// TestPackString makes sure packs are serialized correctly
|
|
|
|
func TestPackString(t *testing.T) {
|
|
|
|
p := draft.Pack{{ID: "a"}, {ID: "b"}, {ID: "c"}}
|
|
|
|
expected := "a b c"
|
|
|
|
|
|
|
|
if p.String() != expected {
|
|
|
|
t.Errorf("Expected \"%s\" but got \"%s\"", expected, p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-31 08:57:51 +00:00
|
|
|
// ExampleGenericSet is an example usage of the Set APIs to make packs
|
|
|
|
func ExampleGenericSet() {
|
|
|
|
// Create a set with some items
|
2019-05-31 12:07:49 +00:00
|
|
|
s := &draft.GenericSet{
|
|
|
|
Cards: []draft.Card{
|
2019-05-31 08:57:51 +00:00
|
|
|
{ID: "a"},
|
|
|
|
{ID: "b"},
|
|
|
|
{ID: "c"},
|
|
|
|
},
|
|
|
|
PackSize: 5,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a pack
|
2019-05-31 12:07:49 +00:00
|
|
|
pack := draft.MakePack(s)
|
2019-05-31 08:57:51 +00:00
|
|
|
|
|
|
|
// Print cards in pack
|
|
|
|
for i, card := range pack {
|
|
|
|
fmt.Printf("Card #%d: %s\n", i, card.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://gist.github.com/alioygur/16c66b4249cb42715091fe010eec7e33
|
2019-05-31 12:07:49 +00:00
|
|
|
func sliceUniq(s []draft.Card) []draft.Card {
|
2019-05-31 08:57:51 +00:00
|
|
|
for i := 0; i < len(s); i++ {
|
|
|
|
for i2 := i + 1; i2 < len(s); i2++ {
|
|
|
|
if s[i].ID == s[i2].ID {
|
|
|
|
// delete
|
|
|
|
s = append(s[:i2], s[i2+1:]...)
|
|
|
|
i2--
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|