Validate moves
This commit is contained in:
parent
2e11332392
commit
71a50ce22b
4 changed files with 52 additions and 11 deletions
|
@ -3,7 +3,7 @@
|
|||
[![Donate via LiberaPay](https://img.shields.io/liberapay/receives/rocket9labs.com.svg?logo=liberapay)](https://liberapay.com/rocket9labs.com)
|
||||
[![Donate via Patreon](https://img.shields.io/badge/dynamic/json?color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F5252223)](https://www.patreon.com/rocketnine)
|
||||
|
||||
**Note:** This is unfinished, alpha-quality software. Here be dragons.
|
||||
**Note:** This is unfinished alpha-quality software. Here be dragons.
|
||||
|
||||
## Play
|
||||
|
||||
|
@ -28,3 +28,5 @@ See [bgammon-cli](https://code.rocket9labs.com/tslocum/bgammon-cli)
|
|||
Please share issues and suggestions [here](https://code.rocket9labs.com/tslocum/bgammon/issues).
|
||||
|
||||
The bgammon protocol is specified in [PROTOCOL.md](https://code.rocket9labs.com/tslocum/bgammon/src/branch/main/PROTOCOL.md).
|
||||
|
||||
For information on how to play backgammon visit https://bkgm.com/rules.html
|
||||
|
|
|
@ -106,7 +106,7 @@ func (c *serverClient) sendEvent(e interface{}) {
|
|||
case *bgammon.EventFailedRoll:
|
||||
c.Write([]byte(fmt.Sprintf("failedroll %s", ev.Reason)))
|
||||
case *bgammon.EventMoved:
|
||||
c.Write([]byte(fmt.Sprintf("moved %s %s", ev.Player, bgammon.FormatMoves(ev.Moves, c.playerNumber))))
|
||||
c.Write([]byte(fmt.Sprintf("moved %s %s", ev.Player, bgammon.FormatAndFlipMoves(ev.Moves, c.playerNumber))))
|
||||
case *bgammon.EventFailedMove:
|
||||
c.Write([]byte(fmt.Sprintf("failedmove %d/%d %s", ev.From, ev.To, ev.Reason)))
|
||||
case *bgammon.EventFailedOk:
|
||||
|
|
|
@ -346,6 +346,16 @@ COMMANDS:
|
|||
continue
|
||||
}
|
||||
|
||||
// Set default game name.
|
||||
if len(bytes.TrimSpace(gameName)) == 0 {
|
||||
abbr := "'s"
|
||||
lastLetter := cmd.client.name[len(cmd.client.name)-1]
|
||||
if lastLetter == 's' || lastLetter == 'S' {
|
||||
abbr = "'"
|
||||
}
|
||||
gameName = []byte(fmt.Sprintf("%s%s game", cmd.client.name, abbr))
|
||||
}
|
||||
|
||||
g := newServerGame(<-s.newGameIDs)
|
||||
g.name = gameName
|
||||
g.password = gamePassword
|
||||
|
@ -480,6 +490,14 @@ COMMANDS:
|
|||
continue COMMANDS
|
||||
}
|
||||
|
||||
if !bgammon.ValidSpace(from) || !bgammon.ValidSpace(to) {
|
||||
cmd.client.sendEvent(&bgammon.EventFailedMove{
|
||||
From: from,
|
||||
To: to,
|
||||
Reason: "Illegal move.",
|
||||
})
|
||||
}
|
||||
|
||||
originalFrom, originalTo := from, to
|
||||
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)
|
||||
|
@ -496,9 +514,12 @@ COMMANDS:
|
|||
continue
|
||||
}
|
||||
clientGame.eachClient(func(client *serverClient) {
|
||||
client.sendEvent(&bgammon.EventMoved{
|
||||
ev := &bgammon.EventMoved{
|
||||
Moves: bgammon.FlipMoves(moves, client.playerNumber),
|
||||
})
|
||||
}
|
||||
ev.Player = string(cmd.client.name)
|
||||
|
||||
client.sendEvent(ev)
|
||||
clientGame.sendBoard(client)
|
||||
})
|
||||
case bgammon.CommandReset:
|
||||
|
@ -525,9 +546,12 @@ COMMANDS:
|
|||
cmd.client.sendNotice("Failed to undo move: invalid move.")
|
||||
} else {
|
||||
clientGame.eachClient(func(client *serverClient) {
|
||||
client.sendEvent(&bgammon.EventMoved{
|
||||
ev := &bgammon.EventMoved{
|
||||
Moves: bgammon.FlipMoves(undoMoves, client.playerNumber),
|
||||
})
|
||||
}
|
||||
ev.Player = string(cmd.client.name)
|
||||
|
||||
client.sendEvent(ev)
|
||||
clientGame.sendBoard(client)
|
||||
})
|
||||
}
|
||||
|
@ -544,7 +568,7 @@ COMMANDS:
|
|||
playerNumber = 2
|
||||
}
|
||||
cmd.client.sendEvent(&bgammon.EventFailedOk{
|
||||
Reason: fmt.Sprintf("The following legal moves are available: %s", bgammon.FormatMoves(legalMoves, playerNumber)),
|
||||
Reason: fmt.Sprintf("The following legal moves are available: %s", bgammon.FormatAndFlipMoves(legalMoves, playerNumber)),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
|
23
game.go
23
game.go
|
@ -592,7 +592,7 @@ func FlipSpace(space int, player int) int {
|
|||
case SpaceBarOpponent:
|
||||
return SpaceBarPlayer
|
||||
default:
|
||||
log.Panicf("unknown space %d", space)
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 24 - space + 1
|
||||
|
@ -606,18 +606,33 @@ func FlipMoves(moves [][]int, player int) [][]int {
|
|||
return m
|
||||
}
|
||||
|
||||
func FormatMoves(moves [][]int, player int) []byte {
|
||||
func FormatMoves(moves [][]int) []byte {
|
||||
var out bytes.Buffer
|
||||
for i := range moves {
|
||||
if i != 0 {
|
||||
out.WriteByte(' ')
|
||||
}
|
||||
// TODO
|
||||
out.Write([]byte(fmt.Sprintf("{{%d/%d}}", FlipSpace(moves[i][0], player), FlipSpace(moves[i][1], player))))
|
||||
out.Write([]byte(fmt.Sprintf("%d/%d", moves[i][0], moves[i][1])))
|
||||
}
|
||||
return out.Bytes()
|
||||
}
|
||||
|
||||
func FormatAndFlipMoves(moves [][]int, player int) []byte {
|
||||
return FormatMoves(FlipMoves(moves, player))
|
||||
}
|
||||
|
||||
func ValidSpace(space int) bool {
|
||||
if space < 1 || space > 24 {
|
||||
return false
|
||||
}
|
||||
switch space {
|
||||
case SpaceHomePlayer, SpaceHomeOpponent, SpaceBarPlayer, SpaceBarOpponent:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
VerticalBar rune = '\u2502' // │
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue