Marco
efefa4ced5
With this commit, we stop waiting for the websocket connection to be established before the game starts. Now, the Connection type is responsible for waiting for the websocket connection before writing.
164 lines
3.4 KiB
Go
164 lines
3.4 KiB
Go
package chess
|
|
|
|
import (
|
|
"log"
|
|
"math/rand"
|
|
"mchess_server/api"
|
|
"mchess_server/types"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type Game struct {
|
|
id uuid.UUID
|
|
board Board
|
|
players []*Player
|
|
currentTurnPlayer *Player
|
|
gameState int
|
|
}
|
|
|
|
const (
|
|
Init = iota
|
|
Prepare
|
|
PlayerToMove
|
|
CheckMove
|
|
CheckPlayerChange
|
|
)
|
|
|
|
func NewGame() *Game {
|
|
var game = Game{
|
|
id: uuid.New(),
|
|
board: newBoard(),
|
|
gameState: Init,
|
|
}
|
|
game.board.Init()
|
|
|
|
return &game
|
|
}
|
|
|
|
func (game Game) GetPlayers() []*Player {
|
|
return game.players
|
|
}
|
|
|
|
func (game Game) GetPlayer1() *Player {
|
|
return game.players[0]
|
|
}
|
|
|
|
func (game Game) GetRandomPlayer() *Player {
|
|
index := rand.Int() % 2
|
|
return game.players[index]
|
|
}
|
|
|
|
func (game Game) GetPlayer2() *Player {
|
|
return game.players[1]
|
|
}
|
|
|
|
func (game *Game) prepare() {
|
|
game.players[0].color = types.White
|
|
game.players[1].color = types.Black
|
|
|
|
err := game.notifyPlayersAboutGameStart()
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
func (game *Game) Handle() {
|
|
defer game.killGame()
|
|
|
|
game.prepare()
|
|
|
|
var receivedMove types.Move
|
|
var err error
|
|
|
|
for {
|
|
switch game.gameState {
|
|
case Init:
|
|
game.currentTurnPlayer = game.GetPlayer1()
|
|
game.gameState = Prepare
|
|
|
|
case Prepare:
|
|
game.prepare()
|
|
game.gameState = PlayerToMove
|
|
|
|
case PlayerToMove:
|
|
log.Println("with ", game.currentTurnPlayer.GetPlayerColor(), " to move")
|
|
receivedMove, err = game.currentTurnPlayer.ReadMove()
|
|
if err != nil {
|
|
log.Println("Error while reading message:", err)
|
|
return
|
|
}
|
|
log.Println("Player ", game.currentTurnPlayer, " moved:\n", receivedMove)
|
|
|
|
game.gameState = CheckMove
|
|
case CheckMove:
|
|
valid, ruleViolation := game.board.CheckAndPlay(receivedMove)
|
|
|
|
if valid {
|
|
game.gameState = CheckPlayerChange
|
|
} else {
|
|
invalidMoveMessage, err := api.GetInvalidMoveMessage(receivedMove, ruleViolation.String())
|
|
if err != nil {
|
|
log.Println("Error marshalling 'colorDetermined' message for player 1", err)
|
|
return
|
|
}
|
|
game.currentTurnPlayer.writeMessage(invalidMoveMessage)
|
|
game.gameState = PlayerToMove
|
|
}
|
|
case CheckPlayerChange:
|
|
if game.currentTurnPlayer.Uuid == game.players[0].Uuid {
|
|
game.currentTurnPlayer = game.players[1]
|
|
} else {
|
|
game.currentTurnPlayer = game.players[0]
|
|
}
|
|
|
|
err := game.broadcastMove(receivedMove)
|
|
if err != nil {
|
|
log.Println("Error broadcasting move ", err)
|
|
return
|
|
}
|
|
|
|
game.gameState = PlayerToMove
|
|
}
|
|
log.Println("GameState = ", game.gameState)
|
|
}
|
|
}
|
|
|
|
func (game *Game) AddPlayersToGame(player *Player) {
|
|
game.players = append(game.players, player)
|
|
}
|
|
|
|
func (game *Game) killGame() {
|
|
log.Println("Game should be killed")
|
|
}
|
|
|
|
func (game Game) notifyPlayersAboutGameStart() error {
|
|
colorDeterminedPlayer1, err := api.GetColorDeterminedMessage(types.White)
|
|
if err != nil {
|
|
log.Println("Error marshalling 'colorDetermined' message for player 1", err)
|
|
return err
|
|
}
|
|
colorDeterminedPlayer2, err := api.GetColorDeterminedMessage(types.Black)
|
|
if err != nil {
|
|
log.Println("Error marshalling 'colorDetermined' message for player 2", err)
|
|
return err
|
|
}
|
|
|
|
game.GetPlayer1().writeMessage(colorDeterminedPlayer1)
|
|
game.GetPlayer2().writeMessage(colorDeterminedPlayer2)
|
|
return nil
|
|
}
|
|
|
|
func (game Game) broadcastMove(move types.Move) error {
|
|
err := game.GetPlayer1().SendMoveAndPosition(move, game.board.PGN())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = game.GetPlayer2().SendMoveAndPosition(move, game.board.PGN())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|