diff --git a/bei.go b/bei.go index 635dac6..e205ad4 100644 --- a/bei.go +++ b/bei.go @@ -140,7 +140,7 @@ func (c *BEIClient) readLine() ([]byte, error) { } } -func (c *BEIClient) Double(state []int) (interface{}, error) { +func (c *BEIClient) Double(state []int8) (interface{}, error) { if c.terminated { return nil, nil } else if !c.connected { @@ -155,7 +155,7 @@ func (c *BEIClient) Double(state []int) (interface{}, error) { if i > 0 { stateBytes = append(stateBytes, ',') } - stateBytes = append(stateBytes, []byte(strconv.Itoa(v))...) + stateBytes = append(stateBytes, []byte(strconv.Itoa(int(v)))...) } if c.REST() { @@ -172,7 +172,7 @@ func (c *BEIClient) Double(state []int) (interface{}, error) { return bei.DecodeEvent(buf) } -func (c *BEIClient) Move(state []int) (interface{}, error) { +func (c *BEIClient) Move(state []int8) (interface{}, error) { if c.terminated { return nil, nil } else if !c.connected { @@ -187,7 +187,7 @@ func (c *BEIClient) Move(state []int) (interface{}, error) { if i > 0 { stateBytes = append(stateBytes, ',') } - stateBytes = append(stateBytes, []byte(strconv.Itoa(v))...) + stateBytes = append(stateBytes, []byte(strconv.Itoa(int(v)))...) } if c.REST() { @@ -204,7 +204,7 @@ func (c *BEIClient) Move(state []int) (interface{}, error) { return bei.DecodeEvent(buf) } -func (c *BEIClient) Choose(state []int) (interface{}, error) { +func (c *BEIClient) Choose(state []int8) (interface{}, error) { if c.terminated { return nil, nil } else if !c.connected { @@ -219,7 +219,7 @@ func (c *BEIClient) Choose(state []int) (interface{}, error) { if i > 0 { stateBytes = append(stateBytes, ',') } - stateBytes = append(stateBytes, []byte(strconv.Itoa(v))...) + stateBytes = append(stateBytes, []byte(strconv.Itoa(int(v)))...) } if c.REST() { @@ -236,15 +236,13 @@ func (c *BEIClient) Choose(state []int) (interface{}, error) { return bei.DecodeEvent(buf) } -func beiState(game *bgammon.Game) []int { +func beiState(game *bgammon.Game) []int8 { // TODO send turn numbers - var state []int + var state []int8 state = append(state, game.Board...) - state = append(state, game.Roll1, game.Roll2, 1, 1, game.DoubleValue, game.DoublePlayer, game.Player1.Points, game.Player2.Points, game.Points) - acey := 0 - entered1, entered2 := 1, 1 - if game.Acey { - acey = 1 + state = append(state, game.Roll1, game.Roll2, game.Roll3, 1, 1, game.DoubleValue, game.DoublePlayer, game.Player1.Points, game.Player2.Points, game.Points) + entered1, entered2 := int8(1), int8(1) + if game.Variant != bgammon.VariantBackgammon { if !game.Player1.Entered { entered1 = 0 } @@ -252,5 +250,5 @@ func beiState(game *bgammon.Game) []int { entered2 = 0 } } - return append(state, 0, 0, 0, 0, acey, entered1, entered2) + return append(state, 0, 0, 0, 0, game.Variant, entered1, entered2) } diff --git a/client.go b/client.go index 7768e39..3b77bcf 100644 --- a/client.go +++ b/client.go @@ -63,7 +63,7 @@ func NewClient(address string, username string, password string, points int) *Cl Out: make(chan []byte, bufferSize), points: points, game: &bgammon.GameState{ - Game: bgammon.NewGame(false), + Game: bgammon.NewGame(bgammon.VariantBackgammon), }, } go c.handleTimeout() @@ -540,6 +540,9 @@ func (c *Client) HandleEvents() { } } else { diceFormatted = fmt.Sprintf("%d-%d", c.game.Roll1, c.game.Roll2) + if c.game.Roll3 != 0 { + diceFormatted += fmt.Sprintf("-%d", c.game.Roll3) + } } if ev.Player == c.game.Player2.Name { c.lastActivity = time.Now() @@ -559,10 +562,10 @@ func (c *Client) HandleEvents() { for _, m := range ev.Moves { if playerNumber == 1 && c.game.Board[m[1]] == -1 { c.barsPlayer++ - c.barsPlayerPips += bgammon.SpaceDiff(bgammon.SpaceBarOpponent, m[1], false) + c.barsPlayerPips += int(bgammon.SpaceDiff(bgammon.SpaceBarOpponent, m[1], c.game.Variant)) } else if playerNumber == 2 && c.game.Board[m[1]] == 1 { c.barsOpponent++ - c.barsOpponentPips += bgammon.SpaceDiff(bgammon.SpaceBarPlayer, m[1], false) + c.barsOpponentPips += int(bgammon.SpaceDiff(bgammon.SpaceBarPlayer, m[1], c.game.Variant)) } c.game.AddLocalMove(m) } @@ -570,6 +573,8 @@ func (c *Client) HandleEvents() { log.Printf("%s moved %s.", ev.Player, bgammon.FormatMoves(ev.Moves)) } case *bgammon.EventFailedMove: + log.Printf("%+v", c.game.Game) + log.Printf("%+v", c.game.Board) var extra string if ev.From != 0 || ev.To != 0 { extra = fmt.Sprintf(" from %s to %s", bgammon.FormatSpace(ev.From), bgammon.FormatSpace(ev.To)) @@ -705,11 +710,11 @@ func saveReplay(content []byte, username string, outDir string) error { func QueryString(g *bgammon.GameState) string { b := g.Board var buf strings.Builder - buf.Write([]byte("die1=" + strconv.Itoa(g.Roll1) + "&die2=" + strconv.Itoa(g.Roll2) + "&p0=" + strconv.Itoa(b[bgammon.SpaceBarOpponent]))) + buf.Write([]byte("die1=" + strconv.Itoa(int(g.Roll1)) + "&die2=" + strconv.Itoa(int(g.Roll2)) + "&p0=" + strconv.Itoa(int(b[bgammon.SpaceBarOpponent])))) for i := 1; i < 25; i++ { - buf.Write([]byte("&p" + strconv.Itoa(i) + "=" + strconv.Itoa(b[i]))) + buf.Write([]byte("&p" + strconv.Itoa(i) + "=" + strconv.Itoa(int(b[i])))) } - buf.Write([]byte("&p25=" + strconv.Itoa(b[bgammon.SpaceBarPlayer]))) + buf.Write([]byte("&p25=" + strconv.Itoa(int(b[bgammon.SpaceBarPlayer])))) return buf.String() } diff --git a/go.mod b/go.mod index fd6cab0..e4b0a63 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module code.rocket9labs.com/tslocum/bgammon-benchmark go 1.21.4 require ( - code.rocket9labs.com/tslocum/bei v0.0.0-20231223213316-ef6cb993c773 - code.rocket9labs.com/tslocum/bgammon v0.0.0-20231223081447-262d006c714c + code.rocket9labs.com/tslocum/bei v0.0.0-20240108012722-6db380cc190b + code.rocket9labs.com/tslocum/bgammon v0.0.0-20240108183627-118a7f78eb98 nhooyr.io/websocket v1.8.10 ) @@ -17,7 +17,7 @@ require ( github.com/andybalholm/cascadia v1.3.2 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/gobwas/ws v1.3.1 // indirect + github.com/gobwas/ws v1.3.2 // indirect github.com/google/uuid v1.5.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -27,6 +27,7 @@ require ( github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect github.com/jackc/pgx/v5 v5.5.1 // indirect github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect + github.com/jlouis/glicko2 v1.0.0 // indirect github.com/matcornic/hermes/v2 v2.1.0 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -37,8 +38,8 @@ require ( github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/vanng822/css v1.0.1 // indirect github.com/vanng822/go-premailer v1.20.2 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 1eb62aa..5c6fd1c 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -code.rocket9labs.com/tslocum/bei v0.0.0-20231223213316-ef6cb993c773 h1:cu3FKYfk5WQcuxMXrqghHAmriyFiRCZ/8aUqIKI9yLU= -code.rocket9labs.com/tslocum/bei v0.0.0-20231223213316-ef6cb993c773/go.mod h1:tS60/VNAJphKvDBkSLQhKALa15msIAuWWfEKNc4oFZc= -code.rocket9labs.com/tslocum/bgammon v0.0.0-20231223081447-262d006c714c h1:ri5THzKvxE5WqAH/d/U6gXunHJx2cwYUWrer8YQ0QEk= -code.rocket9labs.com/tslocum/bgammon v0.0.0-20231223081447-262d006c714c/go.mod h1:pM1hNhG/vKgk4Ktpszv5duQ3gJMrawO6gwotpJjHxyE= +code.rocket9labs.com/tslocum/bei v0.0.0-20240108012722-6db380cc190b h1:Y0a14Kf/hSYepSmp4ZfDeE4CZZGBGBS97CNjCbKJm0c= +code.rocket9labs.com/tslocum/bei v0.0.0-20240108012722-6db380cc190b/go.mod h1:tS60/VNAJphKvDBkSLQhKALa15msIAuWWfEKNc4oFZc= +code.rocket9labs.com/tslocum/bgammon v0.0.0-20240108183627-118a7f78eb98 h1:6lndXAeTooxepIWtpVWOhEFjig6DVh6bkVaWJVtrmX4= +code.rocket9labs.com/tslocum/bgammon v0.0.0-20240108183627-118a7f78eb98/go.mod h1:0DTOM6NviKJsDDBANcB7hbk2fseN5qtHJZAFeKsnAPQ= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= @@ -31,8 +31,8 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.3.1 h1:Qi34dfLMWJbiKaNbDVzM9x27nZBjmkaW6i4+Ku+pGVU= -github.com/gobwas/ws v1.3.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= +github.com/gobwas/ws v1.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q= +github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -58,6 +58,8 @@ github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFr github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA= github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= +github.com/jlouis/glicko2 v1.0.0 h1:pSl/OTRclxdrhtqoqJpvO41GoUL1dmaTnxC2F6+W+y8= +github.com/jlouis/glicko2 v1.0.0/go.mod h1:5dzlxjhVPPLk+wiUwwF2oVyDwsNXMgnw7WrLRxuejBs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -106,8 +108,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -123,8 +125,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -143,8 +145,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/main.go b/main.go index a7c6fb5..ebe54e2 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,7 @@ func main() { count int points int outDir string - playAcey bool + variant int quiet bool verbose bool debug int @@ -69,7 +69,7 @@ func main() { flag.StringVar(&outDir, "match-dir", "", "Write .match files to specified directory") flag.StringVar(&wildbgAddress, "wildbg", "", "wildbg service address (REST)") flag.IntVar(&matchDelay, "delay", 0, "Delay (in seconds) to wait before starting match") - flag.BoolVar(&playAcey, "acey", false, "Play acey-deucey") + flag.IntVar(&variant, "variant", 0, "Variant (0: Backgammon, 1: Acey-deucey, 2: Tabula)") flag.BoolVar(&quiet, "quiet", false, "Do not print rolls or moves") flag.BoolVar(&verbose, "verbose", false, "Print all client messages") flag.IntVar(&debug, "debug", 0, "Port to serve debug information on") @@ -109,11 +109,7 @@ func main() { conn := <-conns c := NewLocalClient(conn, "", botName, "", 1, beiClient) - acey := 0 - if playAcey { - acey = 1 - } - c.Out <- []byte(fmt.Sprintf("c public %d %d", points, acey)) + c.Out <- []byte(fmt.Sprintf("c public %d %d", points, variant)) go c.HandleEvents() }