Add groundwork for checking rules.

This commit is contained in:
Marco 2023-06-12 22:32:31 +02:00
parent 7544bf0563
commit 060ac8ad9e
5 changed files with 119 additions and 31 deletions

View File

@ -1,11 +1,14 @@
package api
import "local/m/mchess_server/types"
import (
"encoding/json"
"local/m/mchess_server/types"
)
type WebsocketMessage struct {
Type MessageType `json:"messageType"`
Move *types.Move `json:"move,omitempty"`
Color *Color `json:"color,omitempty"`
Color *types.ChessColor `json:"color,omitempty"`
}
type MessageType string
@ -15,13 +18,6 @@ const (
ColorDetermined MessageType = "colorDetermined"
)
type Color string
const (
Black Color = "black"
White Color = "white"
)
func (m WebsocketMessage) IsValidMove() bool {
if m.Type != MoveMessage {
return false
@ -31,3 +27,8 @@ func (m WebsocketMessage) IsValidMove() bool {
}
return true
}
func GetColorDeterminedMessage(color types.ChessColor) ([]byte, error) {
return json.Marshal(WebsocketMessage{Type: ColorDetermined, Color: &color})
}

55
chess/board.go Normal file
View File

@ -0,0 +1,55 @@
package chess
import "local/m/mchess_server/types"
type Board map[types.Coordinate]types.Piece
func (b Board) Init() {
var coord types.Coordinate
for i := 1; i <= 8; i++ {
coord.Row = 2
coord.Col = i
b[coord] = types.Piece{Class: types.Pawn, Color: types.White}
coord.Row = 7
coord.Col = i
b[coord] = types.Piece{Class: types.Pawn, Color: types.Black}
}
b[types.Coordinate{Row: 1, Col: 1}] = types.Piece{Class: types.Rook, Color: types.White}
b[types.Coordinate{Row: 1, Col: 2}] = types.Piece{Class: types.Knight, Color: types.White}
b[types.Coordinate{Row: 1, Col: 3}] = types.Piece{Class: types.Bishop, Color: types.White}
b[types.Coordinate{Row: 1, Col: 4}] = types.Piece{Class: types.Queen, Color: types.White}
b[types.Coordinate{Row: 1, Col: 5}] = types.Piece{Class: types.King, Color: types.White}
b[types.Coordinate{Row: 1, Col: 6}] = types.Piece{Class: types.Bishop, Color: types.White}
b[types.Coordinate{Row: 1, Col: 7}] = types.Piece{Class: types.Knight, Color: types.White}
b[types.Coordinate{Row: 1, Col: 8}] = types.Piece{Class: types.Rook, Color: types.White}
b[types.Coordinate{Row: 8, Col: 1}] = types.Piece{Class: types.Rook, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 2}] = types.Piece{Class: types.Knight, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 3}] = types.Piece{Class: types.Bishop, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 4}] = types.Piece{Class: types.Queen, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 5}] = types.Piece{Class: types.King, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 6}] = types.Piece{Class: types.Bishop, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 7}] = types.Piece{Class: types.Knight, Color: types.Black}
b[types.Coordinate{Row: 8, Col: 8}] = types.Piece{Class: types.Rook, Color: types.Black}
}
func (b Board) GetPieceAt(coord types.Coordinate) (types.Piece, bool) {
piece, found := b[coord]
if !found {
piece = types.Piece{}
}
return piece, found
}
func (b *Board) CheckMove(move types.Move) (bool, string) {
_, found := b.GetPieceAt(move.StartSquare)
if !found {
return false, "no piece at start square"
}
return true, ""
}

View File

@ -1,7 +1,6 @@
package chess
import (
"encoding/json"
"local/m/mchess_server/api"
"local/m/mchess_server/types"
"log"
@ -12,19 +11,23 @@ import (
type Game struct {
id uuid.UUID
board Board
players []*Player
currentTurnPlayer *Player
}
const (
PlayerToMove = 0
CheckPlayerChange = 1
PlayerToMove = iota
CheckMove
CheckPlayerChange
)
func NewGame() *Game {
var game Game = Game{
id: uuid.New(),
board: make(map[types.Coordinate]types.Piece),
}
game.board.Init()
return &game
}
@ -69,8 +72,15 @@ func (game *Game) Handle() {
}
log.Println("Player ", game.currentTurnPlayer, " moved:\n", receivedMove)
gameState = CheckPlayerChange
gameState = CheckMove
case CheckMove:
valid, reason := game.board.CheckMove(receivedMove)
log.Println(reason)
if valid {
gameState = CheckPlayerChange
}
case CheckPlayerChange:
if game.currentTurnPlayer.Uuid == game.players[0].Uuid {
game.currentTurnPlayer = game.players[1]
@ -122,14 +132,12 @@ func (game *Game) waitForWebsocketConnections() bool {
}
func (game Game) notifyPlayersAboutGameStart() error {
white := api.White
black := api.Black
colorDeterminedPlayer1, err := json.Marshal(api.WebsocketMessage{Type: api.ColorDetermined, Color: &white})
colorDeterminedPlayer1, err := api.GetColorDeterminedMessage(types.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})
colorDeterminedPlayer2, err := api.GetColorDeterminedMessage(types.Black)
if err != nil {
log.Println("Error marshalling 'colorDetermined' message for player 2", err)
return err

View File

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

35
types/common.go Normal file
View File

@ -0,0 +1,35 @@
package types
type Coordinate struct {
Col int `json:"col"`
Row int `json:"row"`
}
type Move struct {
StartSquare Coordinate `json:"startSquare"`
EndSquare Coordinate `json:"endSquare"`
}
type PieceClass string
const (
Pawn PieceClass = "pawn"
Rook PieceClass = "rook"
Knight PieceClass = "knight"
Bishop PieceClass = "bishop"
Queen PieceClass = "queen"
King PieceClass = "king"
)
type ChessColor string
const (
White ChessColor = "white"
Black ChessColor = "black"
)
type Piece struct {
Class PieceClass
Color ChessColor
HasMoved bool //we need this for pawns (first move is special) and rooks+king (for castling)
}