Fix parsing gnubg moves

This commit is contained in:
Trevor Slocum 2024-11-18 19:49:00 -08:00
parent 4be1dd8bc4
commit c272a0881d
4 changed files with 39 additions and 33 deletions

View file

@ -96,7 +96,7 @@ func gnubgPosition(g *bgammon.Game) string {
return position
}
func parseMoves(g *bgammon.Game, moves []byte) ([4][2]int8, error) {
func parseMoves(moves []byte) ([4][2]int8, error) {
l := len(moves)
var m [4][2]int8
@ -118,6 +118,17 @@ func parseMoves(g *bgammon.Game, moves []byte) ([4][2]int8, error) {
move := moves[i : i+moveLength]
move = bytes.ReplaceAll(move, []byte("*"), nil)
slash := bytes.IndexRune(move, '/')
if slash == -1 {
return [4][2]int8{}, fmt.Errorf("failed to parse gnubg moves: invalid count: %s", moves)
}
nextSlash := bytes.IndexRune(move[slash+1:], '/')
var remaining []byte
if nextSlash != -1 {
remaining = move[slash+nextSlash+2:]
move = move[:slash+nextSlash+1]
}
count := 1
paren := bytes.IndexRune(move, '(')
if paren != -1 {
@ -129,17 +140,6 @@ func parseMoves(g *bgammon.Game, moves []byte) ([4][2]int8, error) {
mv := append(move[:paren], move[paren+3:]...)
move = mv
}
slash := bytes.IndexRune(move, '/')
if slash == -1 {
return [4][2]int8{}, fmt.Errorf("failed to parse gnubg moves: invalid count: %s", moves)
}
nextSlash := bytes.IndexRune(move[slash+1:], '/')
var remaining []byte
if nextSlash != -1 {
remaining = move[slash+nextSlash+2:]
move = move[:slash+nextSlash+1]
}
from := bgammon.ParseSpace(string(move[:slash]))
if from < 0 || from > 27 {
return [4][2]int8{}, fmt.Errorf("failed to parse gnubg moves: invalid from (%s): %s", move[:slash], moves)
@ -149,15 +149,6 @@ func parseMoves(g *bgammon.Game, moves []byte) ([4][2]int8, error) {
return [4][2]int8{}, fmt.Errorf("failed to parse gnubg moves: invalid to (%s): %s", move[:slash], moves)
}
if to == bgammon.SpaceHomePlayer && bgammon.PlayerCheckers(Game.Game.Board[from], 1) == 0 {
for space := from - 1; space > 1; space-- {
if bgammon.PlayerCheckers(Game.Game.Board[space], 1) != 0 {
from = space
break
}
}
}
for j := 0; j < count; j++ {
m[mc][0], m[mc][1] = int8(from), int8(to)
ok := Game.AddLocalMove([]int8{int8(from), int8(to)})
@ -168,7 +159,7 @@ func parseMoves(g *bgammon.Game, moves []byte) ([4][2]int8, error) {
}
if len(remaining) > 0 {
rm, err := parseMoves(g, append([]byte(strconv.Itoa(int(to))+"/"), remaining...))
rm, err := parseMoves(append([]byte(strconv.Itoa(int(to))+"/"), remaining...))
if err != nil {
return [4][2]int8{}, fmt.Errorf("failed to parse gnubg moves: invalid remaining moves (%s): %s", append([]byte(strconv.Itoa(int(to))+"/"), remaining...), moves)
}
@ -183,6 +174,27 @@ func parseMoves(g *bgammon.Game, moves []byte) ([4][2]int8, error) {
i += moveLength + 1
}
// Relocate bear-off moves after moves within the board.
var mb, mo [][2]int8
for j := 0; j < 4; j++ {
if m[j][0] == 0 && m[j][1] == 0 {
break
} else if m[j][1] == bgammon.SpaceHomePlayer {
mo = append(mo, m[j])
continue
}
mb = append(mb, m[j])
}
m = [4][2]int8{}
mc = 0
for _, mv := range mb {
m[mc] = mv
mc++
}
for _, mv := range mo {
m[mc] = mv
mc++
}
return m, nil
}
@ -259,7 +271,7 @@ func analyze(g *bgammon.Game) ([4][2]int8, error) {
}
moves = moves[:len(moves)-1]
return parseMoves(Game.Game, moves)
return parseMoves(moves)
}
func FlipSpace(space int8, player int8, variant int8) int8 {

2
go.mod
View file

@ -5,7 +5,7 @@ go 1.23
toolchain go1.23.2
require (
code.rocket9labs.com/tslocum/bgammon v0.0.0-20241117073713-a318a6a9010e
code.rocket9labs.com/tslocum/bgammon v0.0.0-20241118091417-1188379900a1
nhooyr.io/websocket v1.8.17
)

4
go.sum
View file

@ -1,7 +1,7 @@
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-20241117073713-a318a6a9010e h1:PhN0FyXnuCrhzJaa+jS08ckVjf4Y17ECm+C1leBCJcg=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20241117073713-a318a6a9010e/go.mod h1:FzdCJoZoG/6nkxLl6OufdfFTXggr5ZArtl7eJ/CCcj0=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20241118091417-1188379900a1 h1:X0sTclnDOUSv0EOxwwBYWUnrq7kXFpfSvlDI/H3T7Fk=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20241118091417-1188379900a1/go.mod h1:FzdCJoZoG/6nkxLl6OufdfFTXggr5ZArtl7eJ/CCcj0=
code.rocket9labs.com/tslocum/tabula v0.0.0-20241024013344-d112a9463c51 h1:JkjRKoSSmtHFSVIOAZV6e+Z+7r0mIxClsDpJxC/ZlOs=
code.rocket9labs.com/tslocum/tabula v0.0.0-20241024013344-d112a9463c51/go.mod h1:WEJXESKXqrMFLAArikQ79lpRibNeeE1C0VruxXYMF5M=
nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y=

View file

@ -22,13 +22,7 @@ func main() {
password = os.Getenv("BOT_PASSWORD")
}
/*g := bgammon.NewGame(bgammon.VariantBackgammon)
g.Turn = 1
g.Roll1 = 6
g.Roll2 = 4
moves, err := analyze(g)
log.Println(moves, err)
log.Fatal("TEST")*/
//moves, err := parseMoves([]byte("10/off(2) 7/2(2)"))
c := newClient(serverAddress, username, password, points)