Support moving checkers
This commit is contained in:
parent
7a7141d189
commit
0df16bc71a
4 changed files with 126 additions and 58 deletions
|
@ -71,7 +71,14 @@ func (g *serverGame) sendBoard(client *serverClient) {
|
|||
|
||||
ev.GameState.Game = ev.GameState.Copy()
|
||||
for space := 1; space <= 24; space++ {
|
||||
ev.Board[space] = g.Game.Board[24-space+1]
|
||||
ev.Board[space] = g.Game.Board[bgammon.FlipSpace(space, client.playerNumber)]
|
||||
}
|
||||
|
||||
ev.Moves = bgammon.FlipMoves(g.Game.Moves, client.playerNumber)
|
||||
|
||||
legalMoves := g.LegalMoves()
|
||||
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)
|
||||
}
|
||||
|
||||
log.Println(g.Game.Board)
|
||||
|
@ -219,8 +226,3 @@ func (g *serverGame) opponent(client *serverClient) *serverClient {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ServerGameState struct {
|
||||
bgammon.GameState
|
||||
Board []int
|
||||
}
|
||||
|
|
|
@ -264,13 +264,6 @@ COMMANDS:
|
|||
}
|
||||
|
||||
clientGame := s.gameByClient(cmd.client)
|
||||
clientNumber := 0
|
||||
if clientGame != nil {
|
||||
clientNumber = 1
|
||||
if clientGame.client2 == cmd.client {
|
||||
clientNumber = 2
|
||||
}
|
||||
}
|
||||
|
||||
switch keyword {
|
||||
case bgammon.CommandHelp, "h":
|
||||
|
@ -416,7 +409,7 @@ COMMANDS:
|
|||
continue
|
||||
}
|
||||
|
||||
if !clientGame.roll(clientNumber) {
|
||||
if !clientGame.roll(cmd.client.playerNumber) {
|
||||
cmd.client.sendEvent(&bgammon.EventFailedRoll{
|
||||
Reason: "It is not your turn to roll.",
|
||||
})
|
||||
|
@ -427,12 +420,6 @@ COMMANDS:
|
|||
Roll2: clientGame.Roll2,
|
||||
}
|
||||
ev.Player = string(cmd.client.name)
|
||||
clientGame.eachClient(func(client *serverClient) {
|
||||
client.sendEvent(ev)
|
||||
if !client.json {
|
||||
clientGame.sendBoard(client)
|
||||
}
|
||||
})
|
||||
if clientGame.Turn == 0 && clientGame.Roll1 != 0 && clientGame.Roll2 != 0 {
|
||||
if clientGame.Roll1 > clientGame.Roll2 {
|
||||
clientGame.Turn = 1
|
||||
|
@ -443,6 +430,12 @@ COMMANDS:
|
|||
clientGame.Roll2 = 0
|
||||
}
|
||||
}
|
||||
clientGame.eachClient(func(client *serverClient) {
|
||||
client.sendEvent(ev)
|
||||
if clientGame.Turn != 0 || !client.json {
|
||||
clientGame.sendBoard(client)
|
||||
}
|
||||
})
|
||||
case bgammon.CommandMove, "m", "mv":
|
||||
if clientGame == nil {
|
||||
cmd.client.sendEvent(&bgammon.EventFailedMove{
|
||||
|
@ -451,7 +444,7 @@ COMMANDS:
|
|||
continue
|
||||
}
|
||||
|
||||
if clientGame.Turn != clientNumber {
|
||||
if clientGame.Turn != cmd.client.playerNumber {
|
||||
cmd.client.sendEvent(&bgammon.EventFailedMove{
|
||||
Reason: "It is not your turn to move.",
|
||||
})
|
||||
|
@ -492,7 +485,8 @@ COMMANDS:
|
|||
}
|
||||
|
||||
originalFrom, originalTo := from, to
|
||||
from, to = bgammon.FlipSpace(from, clientNumber), bgammon.FlipSpace(to, clientNumber)
|
||||
from, to = bgammon.FlipSpace(from, cmd.client.playerNumber), bgammon.FlipSpace(to, cmd.client.playerNumber)
|
||||
log.Printf("translated player %d %d-%d as %d-%d", cmd.client.playerNumber, originalFrom, originalTo, from, to)
|
||||
|
||||
legalMoves := gameCopy.LegalMoves()
|
||||
var found bool
|
||||
|
@ -503,7 +497,7 @@ COMMANDS:
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
log.Printf("available legal moves: %s", bgammon.FormatMoves(legalMoves, clientNumber))
|
||||
log.Printf("available legal moves: %s", bgammon.FormatMoves(legalMoves, cmd.client.playerNumber))
|
||||
cmd.client.sendEvent(&bgammon.EventFailedMove{
|
||||
From: originalFrom,
|
||||
To: originalTo,
|
||||
|
@ -526,12 +520,10 @@ COMMANDS:
|
|||
})
|
||||
continue
|
||||
}
|
||||
ev := &bgammon.EventMoved{
|
||||
Moves: moves,
|
||||
}
|
||||
ev.Player = string(cmd.client.name)
|
||||
clientGame.eachClient(func(client *serverClient) {
|
||||
client.sendEvent(ev)
|
||||
client.sendEvent(&bgammon.EventMoved{
|
||||
Moves: bgammon.FlipMoves(moves, client.playerNumber),
|
||||
})
|
||||
clientGame.sendBoard(client)
|
||||
})
|
||||
case bgammon.CommandOk, "k":
|
||||
|
@ -552,7 +544,14 @@ COMMANDS:
|
|||
continue
|
||||
}
|
||||
|
||||
log.Println("legal to pass turn")
|
||||
nextTurn := 1
|
||||
if clientGame.Turn == 1 {
|
||||
nextTurn = 2
|
||||
}
|
||||
clientGame.Roll1, clientGame.Roll2, clientGame.Moves, clientGame.Turn = 0, 0, nil, nextTurn
|
||||
clientGame.eachClient(func(client *serverClient) {
|
||||
clientGame.sendBoard(client)
|
||||
})
|
||||
case bgammon.CommandBoard, "b":
|
||||
if clientGame == nil {
|
||||
cmd.client.sendNotice("You are not currently in a game.")
|
||||
|
|
70
game.go
70
game.go
|
@ -91,16 +91,17 @@ ADDMOVES:
|
|||
l := g.LegalMoves()
|
||||
for _, lm := range l {
|
||||
if lm[0] == move[0] && lm[1] == move[1] {
|
||||
log.Printf("ADD MOV %d/%d", lm[0], lm[1])
|
||||
delta := 1
|
||||
if g.Turn == 2 {
|
||||
delta = -1
|
||||
}
|
||||
lm[0] -= delta
|
||||
opponentCheckers := numOpponentCheckers(g.Board[lm[1]], g.Turn)
|
||||
g.Board[lm[0]] -= delta
|
||||
opponentCheckers := OpponentCheckers(g.Board[lm[1]], g.Turn)
|
||||
if opponentCheckers == 1 {
|
||||
lm[1] = delta
|
||||
g.Board[lm[1]] = delta
|
||||
} else {
|
||||
lm[1] += delta
|
||||
g.Board[lm[1]] += delta
|
||||
}
|
||||
continue ADDMOVES
|
||||
}
|
||||
|
@ -165,7 +166,7 @@ func (g *Game) LegalMoves() [][]int {
|
|||
}
|
||||
|
||||
checkers := g.Board[space]
|
||||
playerCheckers := numPlayerCheckers(checkers, g.Turn)
|
||||
playerCheckers := PlayerCheckers(checkers, g.Turn)
|
||||
if playerCheckers == 0 {
|
||||
continue
|
||||
}
|
||||
|
@ -180,7 +181,7 @@ func (g *Game) LegalMoves() [][]int {
|
|||
if spaceCount != g.Roll1 && spaceCount != g.Roll2 {
|
||||
return
|
||||
}
|
||||
opponentCheckers := numOpponentCheckers(g.Board[homeSpace], g.Turn)
|
||||
opponentCheckers := OpponentCheckers(g.Board[homeSpace], g.Turn)
|
||||
if opponentCheckers <= 1 {
|
||||
moves = append(moves, []int{space, homeSpace})
|
||||
}
|
||||
|
@ -207,7 +208,7 @@ func (g *Game) LegalMoves() [][]int {
|
|||
return // TODO
|
||||
}
|
||||
|
||||
opponentCheckers := numOpponentCheckers(g.Board[to], g.Turn)
|
||||
opponentCheckers := OpponentCheckers(g.Board[to], g.Turn)
|
||||
if opponentCheckers <= 1 {
|
||||
movable := 1
|
||||
if g.Roll1 == g.Roll2 {
|
||||
|
@ -243,9 +244,9 @@ func (g *Game) RenderSpace(player int, space int, spaceValue int, legalMoves [][
|
|||
pieceColor = opponentColor
|
||||
} else {
|
||||
if value < 0 {
|
||||
pieceColor = "x"
|
||||
} else if value > 0 {
|
||||
pieceColor = "o"
|
||||
} else if value > 0 {
|
||||
pieceColor = "x"
|
||||
} else {
|
||||
pieceColor = playerColor
|
||||
}
|
||||
|
@ -358,33 +359,24 @@ func (g *Game) BoardState(player int) []byte {
|
|||
return g.RenderSpace(player, SpaceBarPlayer, spaceValue, legalMoves)
|
||||
}
|
||||
|
||||
var index int
|
||||
if !white {
|
||||
if row < 6 {
|
||||
col = 12 - col
|
||||
} else {
|
||||
col = 11 - col
|
||||
}
|
||||
|
||||
index = col
|
||||
var space int
|
||||
if white {
|
||||
space = 24 - col
|
||||
if row > 5 {
|
||||
index = 11 - col + 13
|
||||
space = 1 + col
|
||||
}
|
||||
} else {
|
||||
index = col + 3
|
||||
space = 13 + col
|
||||
if row > 5 {
|
||||
index = 11 - col + 15
|
||||
space = 12 - col
|
||||
}
|
||||
}
|
||||
if white {
|
||||
index = BoardSpaces - 1 - index
|
||||
}
|
||||
|
||||
if row == 5 {
|
||||
return []byte(" ")
|
||||
}
|
||||
|
||||
return g.RenderSpace(player, index, spaceValue, legalMoves)
|
||||
return g.RenderSpace(player, space, spaceValue, legalMoves)
|
||||
}
|
||||
|
||||
for i := 0; i < 11; i++ {
|
||||
|
@ -476,7 +468,7 @@ func spaceDiff(from int, to int) int {
|
|||
return diff
|
||||
}
|
||||
|
||||
func numPlayerCheckers(checkers int, player int) int {
|
||||
func PlayerCheckers(checkers int, player int) int {
|
||||
if player == 1 {
|
||||
if checkers > 0 {
|
||||
return checkers
|
||||
|
@ -490,7 +482,7 @@ func numPlayerCheckers(checkers int, player int) int {
|
|||
}
|
||||
}
|
||||
|
||||
func numOpponentCheckers(checkers int, player int) int {
|
||||
func OpponentCheckers(checkers int, player int) int {
|
||||
if player == 2 {
|
||||
if checkers > 0 {
|
||||
return checkers
|
||||
|
@ -509,18 +501,38 @@ func FlipSpace(space int, player int) int {
|
|||
return space
|
||||
}
|
||||
if space < 1 || space > 24 {
|
||||
return space // TODO fix
|
||||
switch space {
|
||||
case SpaceHomePlayer:
|
||||
return SpaceHomeOpponent
|
||||
case SpaceHomeOpponent:
|
||||
return SpaceHomePlayer
|
||||
case SpaceBarPlayer:
|
||||
return SpaceBarOpponent
|
||||
case SpaceBarOpponent:
|
||||
return SpaceBarPlayer
|
||||
default:
|
||||
log.Panicf("unknown space %d", space)
|
||||
}
|
||||
}
|
||||
return 24 - space + 1
|
||||
}
|
||||
|
||||
func FlipMoves(moves [][]int, player int) [][]int {
|
||||
m := make([][]int, len(moves))
|
||||
for i := range moves {
|
||||
m[i] = []int{FlipSpace(moves[i][0], player), FlipSpace(moves[i][1], player)}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func FormatMoves(moves [][]int, player int) []byte {
|
||||
var out bytes.Buffer
|
||||
for i := range moves {
|
||||
if i != 0 {
|
||||
out.WriteByte(' ')
|
||||
}
|
||||
out.Write([]byte(fmt.Sprintf("%d/%d", FlipSpace(moves[i][0], player), FlipSpace(moves[i][1], player))))
|
||||
// TODO
|
||||
out.Write([]byte(fmt.Sprintf("{{%d/%d}}", FlipSpace(moves[i][0], player), FlipSpace(moves[i][1], player))))
|
||||
}
|
||||
return out.Bytes()
|
||||
}
|
||||
|
|
55
gamestate.go
55
gamestate.go
|
@ -1,5 +1,9 @@
|
|||
package bgammon
|
||||
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
|
||||
type GameState struct {
|
||||
*Game
|
||||
PlayerNumber int
|
||||
|
@ -19,3 +23,54 @@ func (g *GameState) LocalPlayer() Player {
|
|||
}
|
||||
return g.Player2
|
||||
}
|
||||
|
||||
func (g *GameState) SpaceAt(x int, y int) int {
|
||||
if (x < 0 || x > 12) || (y < 0 || y > 9) {
|
||||
return -1
|
||||
}
|
||||
|
||||
space := -1
|
||||
if x <= 5 {
|
||||
space = x + 1
|
||||
} else if x == 6 {
|
||||
if y <= 4 {
|
||||
return SpaceBarOpponent
|
||||
} else {
|
||||
return SpaceBarPlayer
|
||||
}
|
||||
} else {
|
||||
space = x
|
||||
}
|
||||
|
||||
if g.PlayerNumber == 2 {
|
||||
if y <= 4 {
|
||||
space = 25 - space
|
||||
}
|
||||
} else {
|
||||
if y <= 4 {
|
||||
space += 12
|
||||
} else {
|
||||
space = 13 - space
|
||||
}
|
||||
}
|
||||
return space
|
||||
}
|
||||
|
||||
func (g *GameState) NeedRoll() bool {
|
||||
switch g.Turn {
|
||||
case 0:
|
||||
if g.PlayerNumber == 1 {
|
||||
return g.Player2.Name != "" && g.Roll1 == 0
|
||||
} else if g.PlayerNumber == 2 {
|
||||
return g.Player1.Name != "" && g.Roll2 == 0
|
||||
}
|
||||
return false
|
||||
case 1:
|
||||
return g.PlayerNumber == g.Turn && g.Player2.Name != "" && g.Roll1 == 0
|
||||
case 2:
|
||||
return g.PlayerNumber == g.Turn && g.Player1.Name != "" && g.Roll1 == 0
|
||||
default:
|
||||
log.Panicf("unknown turn %d", g.Turn)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue