Add bot and session primitives
This commit is contained in:
parent
14ac80df84
commit
cd04155257
7 changed files with 230 additions and 23 deletions
|
@ -1,19 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
room "git.fromouter.space/mcg/cardgage/room/api"
|
||||
)
|
||||
|
||||
type draftBot struct {
|
||||
Sessions map[string]session
|
||||
}
|
||||
|
||||
func newDraftBot() *draftBot {
|
||||
return &draftBot{
|
||||
Sessions: make(map[string]session),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *draftBot) onMessage(msg room.ServerMessage) {
|
||||
|
||||
}
|
37
draftbot/bot/bot.go
Normal file
37
draftbot/bot/bot.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package bot
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"git.fromouter.space/mcg/draft"
|
||||
)
|
||||
|
||||
// Bot implements a bot for filling spots in draft pods
|
||||
type Bot struct {
|
||||
player *draft.Player
|
||||
|
||||
// Currently unused, the bot just picks at random.
|
||||
// In the future, these fields will be used for having the bot try to assemble
|
||||
// a sort-of playable deck. The actual deck doesn't matter, just the fact
|
||||
// that their picks make some sort of sense.
|
||||
color1 string
|
||||
color2 string
|
||||
entryCount int
|
||||
friendCount int
|
||||
otherCount int
|
||||
}
|
||||
|
||||
// MakeBot returns a bot for a given pod spot
|
||||
func MakeBot(player *draft.Player) *Bot {
|
||||
bot := &Bot{
|
||||
player: player,
|
||||
}
|
||||
return bot
|
||||
}
|
||||
|
||||
// PickNext makes the bot pick a card from his pack
|
||||
func (b *Bot) PickNext() {
|
||||
// For now, just pick a card at random
|
||||
cardid := rand.Intn(len(b.player.CurrentPack))
|
||||
b.player.Pick(b.player.CurrentPack[cardid])
|
||||
}
|
80
draftbot/cube.go
Normal file
80
draftbot/cube.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.fromouter.space/mcg/draft"
|
||||
"git.fromouter.space/mcg/draft/mlp"
|
||||
)
|
||||
|
||||
func loadCube(cubeURL string) ([]draft.Card, error) {
|
||||
// Fetch document
|
||||
resp, err := http.Get(cubeURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Each line is a card ID
|
||||
cardids := strings.Split(string(respBytes), "\n")
|
||||
cards := make([]draft.Card, 0)
|
||||
// Convert to draft.Card
|
||||
for _, cardid := range cardids {
|
||||
cardid := strings.TrimSpace(cardid)
|
||||
if len(cardid) < 1 {
|
||||
// Skip empty lines
|
||||
continue
|
||||
}
|
||||
cards = append(cards, draft.Card{ID: cardid})
|
||||
}
|
||||
return cards, nil
|
||||
}
|
||||
|
||||
// I8PCubeConfig is an external JSON doc with the I8PCube pack seeding schema and card list
|
||||
type I8PCubeConfig struct {
|
||||
Schema mlp.I8PSchema
|
||||
Cards map[mlp.I8PType][]string
|
||||
}
|
||||
|
||||
// ToCube creates a I8PCube from the config
|
||||
func (cfg *I8PCubeConfig) ToCube() (*mlp.I8PCube, error) {
|
||||
// Load cards from given list
|
||||
var err error
|
||||
pool := make(mlp.I8PPool)
|
||||
for typ, cardids := range cfg.Cards {
|
||||
pool[typ], err = mlp.LoadCardList(cardids, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Make cube and return it
|
||||
return mlp.MakeI8PCube(pool, cfg.Schema), nil
|
||||
}
|
||||
|
||||
func loadI8PCube(cubeURL string) (*mlp.I8PCube, error) {
|
||||
// Fetch document
|
||||
resp, err := http.Get(cubeURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Deserialize response to JSON object
|
||||
var cubeconf I8PCubeConfig
|
||||
err = json.NewDecoder(resp.Body).Decode(&cubeconf)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create cube from config
|
||||
return cubeconf.ToCube()
|
||||
}
|
30
draftbot/draftbot.go
Normal file
30
draftbot/draftbot.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
room "git.fromouter.space/mcg/cardgage/room/api"
|
||||
)
|
||||
|
||||
type draftBot struct {
|
||||
Sessions map[string]session
|
||||
}
|
||||
|
||||
func newDraftBot() *draftBot {
|
||||
return &draftBot{
|
||||
Sessions: make(map[string]session),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *draftBot) onMessage(msg room.ServerMessage) {
|
||||
switch msg.Type {
|
||||
case room.MsgMessage:
|
||||
logger.Log("event", "message",
|
||||
"roomid", msg.RoomID,
|
||||
"from", msg.Message.From,
|
||||
"to", msg.Message.To,
|
||||
"content", msg.Message.Message)
|
||||
case room.MsgEvent:
|
||||
logger.Log("event", "event",
|
||||
"roomid", msg.RoomID,
|
||||
"content", msg.Event.Message)
|
||||
}
|
||||
}
|
|
@ -5,6 +5,6 @@ go 1.12
|
|||
require (
|
||||
git.fromouter.space/Artificiale/moa v0.0.1-p2
|
||||
git.fromouter.space/mcg/cardgage v0.0.1-p2
|
||||
git.fromouter.space/mcg/draft v0.0.0-20190617210125-5e49b051369f
|
||||
git.fromouter.space/mcg/draft v0.0.2
|
||||
github.com/go-kit/kit v0.8.0
|
||||
)
|
||||
|
|
|
@ -3,8 +3,8 @@ git.fromouter.space/Artificiale/moa v0.0.1-p2 h1:KhoRQeYCFIpHZEucrXz142O5zfSsyEx
|
|||
git.fromouter.space/Artificiale/moa v0.0.1-p2/go.mod h1:dHYul6vVMwDCzre18AFs6NmI22yeI7AE0iQC1jFEQi0=
|
||||
git.fromouter.space/mcg/cardgage v0.0.1-p2 h1:u65ofEmtDHHQ8nbai97DW9kcrYa4x0I3NHv2oXhw8dI=
|
||||
git.fromouter.space/mcg/cardgage v0.0.1-p2/go.mod h1:vCmJ9HRdRGSWg2YQW9oNG7geYACdgWYmzL+zZdrsYhQ=
|
||||
git.fromouter.space/mcg/draft v0.0.0-20190617210125-5e49b051369f h1:aw1RbRQnWsWYN0W3BL8u0xqkdeX1j7xnwan+du5UqHA=
|
||||
git.fromouter.space/mcg/draft v0.0.0-20190617210125-5e49b051369f/go.mod h1:QQmDm9FgAZL3b2/pIDd4Eo608SxMiCQQe5vIybe/CDY=
|
||||
git.fromouter.space/mcg/draft v0.0.2 h1:OT1uztgfCZnZCOg3uOtjQKH2WdwRAxNdYr4KXklVgXY=
|
||||
git.fromouter.space/mcg/draft v0.0.2/go.mod h1:QQmDm9FgAZL3b2/pIDd4Eo608SxMiCQQe5vIybe/CDY=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
|
|
|
@ -1,9 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"git.fromouter.space/mcg/draft"
|
||||
"git.fromouter.space/mcg/draft/mlp"
|
||||
"git.fromouter.space/mcg/mlp-server-tools/draftbot/bot"
|
||||
)
|
||||
|
||||
type session struct {
|
||||
Players map[string]draft.Player
|
||||
Options draftOptions
|
||||
Players map[string]*draft.Player
|
||||
Bots []*bot.Bot
|
||||
Pod *draft.Pod
|
||||
}
|
||||
|
||||
// Types of drafts
|
||||
const (
|
||||
draftBlock = "block"
|
||||
draftSet = "set"
|
||||
draftCube = "cube"
|
||||
draftI8PCube = "i8pcube"
|
||||
)
|
||||
|
||||
type draftOptions struct {
|
||||
Type string `json:"type"`
|
||||
|
||||
// Block draft properties
|
||||
Block string `json:"block,omitempty"`
|
||||
|
||||
// Set draft properties
|
||||
Set string `json:"set,omitempty"`
|
||||
|
||||
// Cube draft properties
|
||||
CubeURL string `json:"cube_url,omitempty"`
|
||||
PackSize int `json:"pack_size,omitempty"`
|
||||
|
||||
// I8PCube properties
|
||||
MainCount int `json:"main_count,omitempty"`
|
||||
ProblemCount int `json:"problem_count,omitempty"`
|
||||
|
||||
// Shared
|
||||
PackCount int `json:"pack_count,omitempty"` // Set and Cube
|
||||
}
|
||||
|
||||
func (do draftOptions) getProvider() (draft.PackProvider, error) {
|
||||
switch do.Type {
|
||||
case draftBlock:
|
||||
return mlp.BlockPacks(mlp.BlockID(do.Block))
|
||||
case draftSet:
|
||||
set, err := mlp.LoadSetHTTP(mlp.SetID(do.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return draft.PacksFromSet(do.PackCount, set), nil
|
||||
case draftCube:
|
||||
cards, err := loadCube(do.CubeURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cube := &draft.GenericCube{
|
||||
Cards: cards,
|
||||
PackSize: do.PackSize,
|
||||
}
|
||||
return draft.PacksFromSet(do.PackCount, cube), nil
|
||||
case draftI8PCube:
|
||||
cube, err := loadI8PCube(do.CubeURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cube.PackProvider(do.MainCount, do.ProblemCount), nil
|
||||
}
|
||||
return nil, errors.New("unknown draft type")
|
||||
}
|
||||
|
||||
func newSession(playerCount int, opt draftOptions) (*session, error) {
|
||||
// Get pack provider for given options
|
||||
provider, err := opt.getProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &session{
|
||||
Options: opt,
|
||||
Pod: draft.MakePod(playerCount, provider),
|
||||
}, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue