Refactor some of the game handler code

This commit is contained in:
Marco 2023-06-08 20:20:37 +02:00
parent 730fad9997
commit 7544bf0563
5 changed files with 130 additions and 32 deletions

View File

@ -1,11 +1,33 @@
package api package api
type Coordinate struct { import "local/m/mchess_server/types"
Col int `json:"col"`
Row int `json:"row"` type WebsocketMessage struct {
Type MessageType `json:"messageType"`
Move *types.Move `json:"move,omitempty"`
Color *Color `json:"color,omitempty"`
} }
type Move struct { type MessageType string
StartSquare Coordinate `json:"startSquare"`
EndSquare Coordinate `json:"endSquare"` const (
MoveMessage MessageType = "move"
ColorDetermined MessageType = "colorDetermined"
)
type Color string
const (
Black Color = "black"
White Color = "white"
)
func (m WebsocketMessage) IsValidMove() bool {
if m.Type != MoveMessage {
return false
}
if m.Move == nil {
return false
}
return true
} }

View File

@ -3,6 +3,7 @@ package chess
import ( import (
"encoding/json" "encoding/json"
"local/m/mchess_server/api" "local/m/mchess_server/api"
"local/m/mchess_server/types"
"log" "log"
"time" "time"
@ -48,30 +49,26 @@ func (game *Game) Handle() {
return return
} }
err := game.notifyPlayersAboutGameStart()
if err != nil {
return
}
gameState := PlayerToMove gameState := PlayerToMove
game.currentTurnPlayer = game.GetPlayer1() game.currentTurnPlayer = game.GetPlayer1()
var move api.Move var receivedMove types.Move
var receivedMessage []byte
var err error
for { for {
switch gameState { switch gameState {
case PlayerToMove: case PlayerToMove:
_, receivedMessage, err = game.currentTurnPlayer.ReadMessageFromPlayer() receivedMove, err = game.currentTurnPlayer.ReadMove()
if err != nil { if err != nil {
log.Println("Error while reading message:", err) log.Println("Error while reading message:", err)
// At the moment, we return when there is an error while reading a message.
// This means, the game just ends uncontrolled
return return
} }
err = json.Unmarshal(receivedMessage, &move) log.Println("Player ", game.currentTurnPlayer, " moved:\n", receivedMove)
log.Println("Player ", game.currentTurnPlayer, " moved:\n", move)
if err != nil {
log.Println("Game: ", game.id, err)
continue
}
gameState = CheckPlayerChange gameState = CheckPlayerChange
case CheckPlayerChange: case CheckPlayerChange:
@ -81,18 +78,13 @@ func (game *Game) Handle() {
game.currentTurnPlayer = game.players[0] game.currentTurnPlayer = game.players[0]
} }
err := game.GetPlayer1().WriteMessageToPlayer(receivedMessage) err = game.broadcastMove(receivedMove)
if err != nil { if err != nil {
log.Println("Error during message writing:", err) log.Println("Error broadcasting move ", err)
continue return
} }
err = game.GetPlayer2().WriteMessageToPlayer(receivedMessage)
if err != nil {
log.Println("Error during message writing:", err)
continue
}
gameState = PlayerToMove
gameState = PlayerToMove
} }
log.Println("GameState = ", gameState) log.Println("GameState = ", gameState)
@ -128,3 +120,35 @@ func (game *Game) waitForWebsocketConnections() bool {
} }
return true return true
} }
func (game Game) notifyPlayersAboutGameStart() error {
white := api.White
black := api.Black
colorDeterminedPlayer1, err := json.Marshal(api.WebsocketMessage{Type: api.ColorDetermined, Color: &white})
if err != nil {
log.Println("Error marshalling 'colorDetermined' message for player 1", err)
return err
}
colorDeterminedPlayer2, err := json.Marshal(api.WebsocketMessage{Type: api.ColorDetermined, Color: &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().SendMove(move)
if err != nil {
return err
}
err = game.GetPlayer2().SendMove(move)
if err != nil {
return err
}
return nil
}

View File

@ -2,6 +2,10 @@ package chess
import ( import (
"context" "context"
"encoding/json"
"errors"
"local/m/mchess_server/api"
"local/m/mchess_server/types"
"log" "log"
"time" "time"
@ -32,15 +36,52 @@ func (p *Player) SetConnection(ctx context.Context, conn *websocket.Conn) {
p.wsConnEstablished <- true p.wsConnEstablished <- true
} }
func (p *Player) WriteMessageToPlayer(msg []byte) error { func (p *Player) SendMove(move types.Move) error {
log.Printf("Writing message: %s to player %d", string(msg), p.Uuid) messageToSend, err := json.Marshal(api.WebsocketMessage{
Type: api.MoveMessage,
Move: &move,
})
if err != nil {
log.Println("Error while marshalling: ", err)
return err
}
err = p.writeMessage(messageToSend)
if err != nil {
log.Println("Error during message writing:", err)
return err
}
return nil
}
func (p *Player) writeMessage(msg []byte) error {
log.Printf("Writing message: %s to player %s", string(msg), p.Uuid.String())
return p.Conn.Write(p.context, websocket.MessageText, msg) return p.Conn.Write(p.context, websocket.MessageText, msg)
} }
func (p *Player) ReadMessageFromPlayer() (websocket.MessageType, []byte, error) { func (p *Player) ReadMove() (types.Move, error) {
_, receivedMessage, err := p.readMessage()
if err != nil {
return types.Move{}, err
}
var msg api.WebsocketMessage
err = json.Unmarshal(receivedMessage, &msg)
if err != nil {
return types.Move{}, err
}
if !msg.IsValidMove() {
return types.Move{}, errors.New("not a valid move")
}
return *msg.Move, nil
}
func (p *Player) readMessage() (websocket.MessageType, []byte, error) {
msgType, msg, err := p.Conn.Read(p.context) msgType, msg, err := p.Conn.Read(p.context)
log.Printf("Reading message: %s (with messagetype %d) from player %d", string(msg), msgType, p.Uuid) log.Printf("Reading message: %s from player %s", string(msg), p.Uuid.String())
return msgType, msg, err return msgType, msg, err
} }

View File

@ -66,7 +66,7 @@ func registerForRandomGame(c *gin.Context) {
} }
func registerWebSocketConnection(c *gin.Context) { func registerWebSocketConnection(c *gin.Context) {
webSocketConn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{OriginPatterns: []string{"chess.sw-gross.de"}}) webSocketConn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{OriginPatterns: []string{"chess.sw-gross.de", "localhost:*"}})
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return return

11
types/chess_types.go Normal file
View File

@ -0,0 +1,11 @@
package types
type Coordinate struct {
Col int `json:"col"`
Row int `json:"row"`
}
type Move struct {
StartSquare Coordinate `json:"startSquare"`
EndSquare Coordinate `json:"endSquare"`
}