Add bot and session primitives

This commit is contained in:
Hamcha 2019-06-26 12:56:02 +02:00
parent 14ac80df84
commit cd04155257
7 changed files with 230 additions and 23 deletions

View file

@ -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
View 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
View 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
View 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)
}
}

View file

@ -5,6 +5,6 @@ go 1.12
require ( require (
git.fromouter.space/Artificiale/moa v0.0.1-p2 git.fromouter.space/Artificiale/moa v0.0.1-p2
git.fromouter.space/mcg/cardgage 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 github.com/go-kit/kit v0.8.0
) )

View file

@ -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/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 h1:u65ofEmtDHHQ8nbai97DW9kcrYa4x0I3NHv2oXhw8dI=
git.fromouter.space/mcg/cardgage v0.0.1-p2/go.mod h1:vCmJ9HRdRGSWg2YQW9oNG7geYACdgWYmzL+zZdrsYhQ= 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.2 h1:OT1uztgfCZnZCOg3uOtjQKH2WdwRAxNdYr4KXklVgXY=
git.fromouter.space/mcg/draft v0.0.0-20190617210125-5e49b051369f/go.mod h1:QQmDm9FgAZL3b2/pIDd4Eo608SxMiCQQe5vIybe/CDY= 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/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/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= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=

View file

@ -1,9 +1,88 @@
package main package main
import ( import (
"errors"
"git.fromouter.space/mcg/draft" "git.fromouter.space/mcg/draft"
"git.fromouter.space/mcg/draft/mlp"
"git.fromouter.space/mcg/mlp-server-tools/draftbot/bot"
) )
type session struct { 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
} }