Fix calculating whether player may bear off

This commit is contained in:
Trevor Slocum 2023-10-30 21:12:58 -07:00
parent 991fd6d481
commit b89776c323
4 changed files with 27 additions and 23 deletions

View file

@ -76,8 +76,12 @@ func RollForMove(from int, to int, player int) int {
}
// CanBearOff returns whether the provided player can bear checkers off of the board.
func CanBearOff(board []int, player int) bool {
homeStart, homeEnd := HomeRange(player)
func CanBearOff(board []int, player int, local bool) bool {
homeStart, homeEnd := 1, 6
if !local {
homeStart, homeEnd = HomeRange(player)
}
homeStart, homeEnd = minInt(homeStart, homeEnd), maxInt(homeStart, homeEnd)
ok := true

View file

@ -74,7 +74,7 @@ func (g *serverGame) sendBoard(client *serverClient) {
GameState: bgammon.GameState{
Game: g.Game,
PlayerNumber: client.playerNumber,
Available: g.LegalMoves(),
Available: g.LegalMoves(false),
},
}
@ -91,7 +91,7 @@ func (g *serverGame) sendBoard(client *serverClient) {
ev.Moves = bgammon.FlipMoves(g.Game.Moves, client.playerNumber)
legalMoves := g.LegalMoves()
legalMoves := g.LegalMoves(false)
for i := range ev.GameState.Available {
ev.GameState.Available[i][0], ev.GameState.Available[i][1] = bgammon.FlipSpace(legalMoves[i][0], client.playerNumber), bgammon.FlipSpace(legalMoves[i][1], client.playerNumber)
}
@ -104,7 +104,7 @@ func (g *serverGame) sendBoard(client *serverClient) {
return
}
scanner := bufio.NewScanner(bytes.NewReader(g.BoardState(client.playerNumber)))
scanner := bufio.NewScanner(bytes.NewReader(g.BoardState(client.playerNumber, false)))
for scanner.Scan() {
client.sendNotice(string(scanner.Bytes()))
}

View file

@ -651,7 +651,7 @@ COMMANDS:
gameState := &bgammon.GameState{
Game: clientGame.Game,
PlayerNumber: cmd.client.playerNumber,
Available: clientGame.LegalMoves(),
Available: clientGame.LegalMoves(false),
}
if !gameState.MayDouble() {
cmd.client.sendNotice("You may not double at this time.")
@ -682,7 +682,7 @@ COMMANDS:
gameState := &bgammon.GameState{
Game: clientGame.Game,
PlayerNumber: cmd.client.playerNumber,
Available: clientGame.LegalMoves(),
Available: clientGame.LegalMoves(false),
}
if !gameState.MayResign() {
cmd.client.sendNotice("You may not resign at this time.")
@ -818,7 +818,7 @@ COMMANDS:
moves = append(moves, []int{from, to})
}
ok, expandedMoves := clientGame.AddMoves(moves)
ok, expandedMoves := clientGame.AddMoves(moves, false)
if !ok {
cmd.client.sendEvent(&bgammon.EventFailedMove{
From: 0,
@ -838,7 +838,7 @@ COMMANDS:
}
winPoints := 1
if !bgammon.CanBearOff(clientGame.Board, opponent) {
if !bgammon.CanBearOff(clientGame.Board, opponent, false) {
winPoints = 3 // Award backgammon.
} else if clientGame.Board[opponentHome] == 0 {
winPoints = 2 // Award gammon.
@ -895,7 +895,7 @@ COMMANDS:
for i, move := range clientGame.Moves {
undoMoves[l-1-i] = []int{move[1], move[0]}
}
ok, _ := clientGame.AddMoves(undoMoves)
ok, _ := clientGame.AddMoves(undoMoves, false)
if !ok {
cmd.client.sendNotice("Failed to undo move: invalid move.")
} else {
@ -935,7 +935,7 @@ COMMANDS:
continue
}
legalMoves := clientGame.LegalMoves()
legalMoves := clientGame.LegalMoves(false)
if len(legalMoves) != 0 {
available := bgammon.FlipMoves(legalMoves, cmd.client.playerNumber)
bgammon.SortMoves(available)

24
game.go
View file

@ -166,8 +166,8 @@ func (g *Game) AddLocalMove(move []int) bool {
return g.addMove(move)
}
func (g *Game) ExpandMove(move []int, currentSpace int, moves [][]int) ([][]int, bool) {
l := g.LegalMoves()
func (g *Game) ExpandMove(move []int, currentSpace int, moves [][]int, local bool) ([][]int, bool) {
l := g.LegalMoves(local)
var hitMoves [][]int
for _, m := range l {
if OpponentCheckers(g.Board[m[1]], g.Turn) == 1 {
@ -198,7 +198,7 @@ func (g *Game) ExpandMove(move []int, currentSpace int, moves [][]int) ([][]int,
gc := g.Copy()
gc.addMove(lm)
m, ok := gc.ExpandMove(move, currentSpace, newMoves)
m, ok := gc.ExpandMove(move, currentSpace, newMoves, local)
if ok {
return m, ok
}
@ -208,7 +208,7 @@ func (g *Game) ExpandMove(move []int, currentSpace int, moves [][]int) ([][]int,
}
// AddMoves adds moves to the game state. Adding a backwards move will remove the equivalent existing move.
func (g *Game) AddMoves(moves [][]int) (bool, [][]int) {
func (g *Game) AddMoves(moves [][]int, local bool) (bool, [][]int) {
if g.Player1.Name == "" || g.Player2.Name == "" || g.Winner != 0 {
return false, nil
}
@ -221,7 +221,7 @@ func (g *Game) AddMoves(moves [][]int) (bool, [][]int) {
validateOffset := 0
VALIDATEMOVES:
for _, move := range moves {
l := gameCopy.LegalMoves()
l := gameCopy.LegalMoves(local)
for _, lm := range l {
if lm[0] == move[0] && lm[1] == move[1] {
addMoves = append(addMoves, []int{move[0], move[1]})
@ -242,7 +242,7 @@ VALIDATEMOVES:
}
}
expandedMoves, ok := g.ExpandMove(move, move[0], nil)
expandedMoves, ok := g.ExpandMove(move, move[0], nil, local)
if ok {
for _, expanded := range expandedMoves {
addMoves = append(addMoves, []int{expanded[0], expanded[1]})
@ -260,7 +260,7 @@ VALIDATEMOVES:
var checkWin bool
ADDMOVES:
for _, move := range addMoves {
l := gameCopy.LegalMoves()
l := gameCopy.LegalMoves(local)
for _, lm := range l {
if lm[0] == move[0] && lm[1] == move[1] {
if !gameCopy.addMove(move) {
@ -316,7 +316,7 @@ ADDMOVES:
}
}
func (g *Game) LegalMoves() [][]int {
func (g *Game) LegalMoves(local bool) [][]int {
if g.Winner != 0 || g.Roll1 == 0 || g.Roll2 == 0 {
return nil
}
@ -408,7 +408,7 @@ func (g *Game) LegalMoves() [][]int {
}
})
} else {
canBearOff := CanBearOff(g.Board, g.Turn)
canBearOff := CanBearOff(g.Board, g.Turn, false)
for space := range g.Board {
if space == SpaceBarPlayer || space == SpaceBarOpponent { // Handled above.
continue
@ -474,7 +474,7 @@ func (g *Game) LegalMoves() [][]int {
}
maxTotal := 1
for _, m := range gc.LegalMoves() {
for _, m := range gc.LegalMoves(local) {
total := totalMoves(gc, m)
if total+1 > maxTotal {
maxTotal = total + 1
@ -580,7 +580,7 @@ func (g *Game) RenderSpace(player int, space int, spaceValue int, legalMoves [][
return append(append([]byte(" "), r...), ' ')
}
func (g *Game) BoardState(player int) []byte {
func (g *Game) BoardState(player int, local bool) []byte {
var t bytes.Buffer
playerRating := "0"
@ -622,7 +622,7 @@ func (g *Game) BoardState(player int) []byte {
t.WriteString(" ")
t.WriteByte('\n')
legalMoves := g.LegalMoves()
legalMoves := g.LegalMoves(local)
space := func(row int, col int) []byte {
spaceValue := row + 1
if row > 5 {