diff --git a/api/move.go b/api/move.go index 3438ee3..566018e 100644 --- a/api/move.go +++ b/api/move.go @@ -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"` + Type MessageType `json:"messageType"` + Move *types.Move `json:"move,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}) + +} diff --git a/chess/board.go b/chess/board.go new file mode 100644 index 0000000..86a7ce8 --- /dev/null +++ b/chess/board.go @@ -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, "" +} diff --git a/chess/game.go b/chess/game.go index 46d8d4d..e9a106d 100644 --- a/chess/game.go +++ b/chess/game.go @@ -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(), + 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 diff --git a/types/chess_types.go b/types/chess_types.go deleted file mode 100644 index 8f5744d..0000000 --- a/types/chess_types.go +++ /dev/null @@ -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"` -} diff --git a/types/common.go b/types/common.go new file mode 100644 index 0000000..db03bd2 --- /dev/null +++ b/types/common.go @@ -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) +}