Fix calculating whether player may bear off
This commit is contained in:
parent
991fd6d481
commit
b89776c323
4 changed files with 27 additions and 23 deletions
8
board.go
8
board.go
|
@ -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
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
@ -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
24
game.go
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue