aboutsummaryrefslogtreecommitdiff
path: root/go/game/draft.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/game/draft.go')
-rw-r--r--go/game/draft.go116
1 files changed, 116 insertions, 0 deletions
diff --git a/go/game/draft.go b/go/game/draft.go
new file mode 100644
index 00000000..f1ab541b
--- /dev/null
+++ b/go/game/draft.go
@@ -0,0 +1,116 @@
+package game
+
+import (
+ "fmt"
+ "log"
+ "math/rand"
+ "strings"
+)
+
+type Draft struct {
+ players []*Player
+ packs []PileOfCards
+ cardsPerPack int
+ packSize int
+ packsPerPlayer int
+ sets []SetIdentifier
+}
+
+func NewDraftFromDesc(players []*Player, desc string) *Draft {
+ var setList string
+ s := strings.Split(desc, ":")
+ desc, setList = s[0], s[1]
+ if sets, err := SetListToSets(setList); err != nil {
+ log.Fatal(err)
+ } else {
+
+ return NewDraft(players, desc, sets)
+ }
+ // not reachable
+ return nil
+}
+
+func NewDraft(players []*Player, desc string, sets []SetIdentifier) *Draft {
+ d := &Draft{players: players, sets: sets}
+ d.parseDesc(desc)
+ log.Printf("created new draft %s\n", d)
+ return d
+}
+
+func (d *Draft) parseDesc(desc string) {
+ fmt.Sscanf(desc, "%dx[%d;%d]", &d.packsPerPlayer, &d.cardsPerPack, &d.packSize)
+}
+
+func (d *Draft) Valid() bool {
+ if d.packSize < d.cardsPerPack*len(d.players) {
+ return false
+ }
+ return true
+}
+
+// run the draft
+// Rhis method only returns after the draft has finished.
+func (d *Draft) Run() {
+ pool := NewPileOfCards()
+ // TODO: increase pool to have enough cards for the draft
+ for _, set := range d.sets {
+ setDeck := NewDeck()
+ for _, c := range NewDeckFromCardPaths(set.CardPaths()).Cards() {
+ if c.IsBuyable() {
+ setDeck.AddCard(c)
+ }
+ }
+ setDeck.MoveInto(pool)
+ }
+
+ nPlayers := len(d.players)
+
+ packs := make([]PileOfCards, 0, nPlayers*d.packsPerPlayer)
+ for _ = range len(d.players) * d.packsPerPlayer {
+ pack := NewRandomPackFromPool(pool, d.packSize)
+ packs = append(packs, pack)
+ }
+
+ log.Printf("%d %d %d\n", d.packsPerPlayer, d.cardsPerPack, len(d.players))
+ for i := range d.packsPerPlayer {
+ for j := range d.cardsPerPack * len(d.players) {
+ for k, player := range d.players {
+ pack := packs[i*nPlayers+(k+j)%nPlayers]
+ pickPrompt := newDraftPickPrompt(pack)
+ log.Printf("prompt %s for a pick from pack %d\n", player.Name, i*nPlayers+(k+j)%nPlayers)
+ pick := prompt(player.Ctrl, pickPrompt)
+ pick.resolve(player.gameState)
+ }
+ }
+ }
+}
+
+type randomDraftAiCtrl struct {
+ ai *Player
+ pack PileOfCards
+}
+
+func (ctrl *randomDraftAiCtrl) Player() *Player {
+ return ctrl.ai
+}
+
+func (ctrl *randomDraftAiCtrl) SendNotification(n PlayerNotification) {
+ ctrl.pack = n.Context.(PileOfCards)
+}
+
+func (ctrl *randomDraftAiCtrl) RecvAction() Action {
+ availCards := ctrl.pack.Cards()
+ var pick int
+ if n := len(availCards); n > 1 {
+ pick = rand.Intn(n - 1)
+ } else {
+ pick = 0
+ }
+ return NewDraftPick(ctrl.ai, ctrl.pack, availCards[pick])
+}
+
+func (d *Draft) AddRandomAi() {
+ p := &Player{Id: -1, Name: "randomDraftAI", Deck: NewDeck()}
+ p.Ctrl = &randomDraftAiCtrl{ai: p}
+ d.players = append(d.players, p)
+}