2023-06-12 20:32:31 +00:00
|
|
|
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
|
|
|
|
}
|
2023-06-14 17:46:46 +00:00
|
|
|
|
|
|
|
func (b Board) CheckMove(move types.Move) (bool, string) {
|
2023-06-13 22:59:16 +00:00
|
|
|
pieceAtStartSquare, found := b.GetPieceAt(move.StartSquare)
|
2023-06-12 20:32:31 +00:00
|
|
|
if !found {
|
|
|
|
return false, "no piece at start square"
|
|
|
|
}
|
2023-06-14 17:46:46 +00:00
|
|
|
movingColor := pieceAtStartSquare.Color
|
2023-06-12 20:32:31 +00:00
|
|
|
|
2023-06-14 17:46:46 +00:00
|
|
|
pieceAtEndSquare, found := b.GetPieceAt(move.EndSquare)
|
|
|
|
if found {
|
|
|
|
if pieceAtEndSquare.Color == pieceAtStartSquare.Color {
|
|
|
|
return false, "same-coloured piece at end square"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// At the moment, we do not need to check if the correct color is moving,
|
|
|
|
//since we are only reading moves from the player whose turn it is.
|
|
|
|
|
|
|
|
//Check if king of moving color is in check -> move not allowed
|
|
|
|
//Do that by checking if the king is in a square attacked by the other color.
|
|
|
|
oppKingCoordinate := b.getSquareOfPiece(types.Piece{
|
|
|
|
Class: types.King,
|
|
|
|
Color: movingColor})
|
|
|
|
if oppKingCoordinate == nil {
|
|
|
|
return false, string(movingColor) + " king not found"
|
2023-06-13 22:59:16 +00:00
|
|
|
}
|
2023-06-14 17:46:46 +00:00
|
|
|
|
|
|
|
b.isSquareAttacked(*oppKingCoordinate, movingColor.Opposite())
|
2023-06-13 22:59:16 +00:00
|
|
|
|
2023-06-14 17:46:46 +00:00
|
|
|
//Check for checkmate
|
|
|
|
//Is every square that the king can move to attacked? And can no other
|
|
|
|
//piece block? -> checkmate
|
2023-06-13 22:59:16 +00:00
|
|
|
|
2023-06-14 17:46:46 +00:00
|
|
|
//Maybe for checking checkmate, we have to check the 'path' in which the
|
|
|
|
//checkmate is given
|
2023-06-13 22:59:16 +00:00
|
|
|
|
2023-06-14 17:46:46 +00:00
|
|
|
// |K| | | | |Q|
|
|
|
|
// in this scenaria the path are all the squares between queen and king.
|
|
|
|
// If a piece can be moved into the path, it is no checkmate
|
2023-06-13 22:59:16 +00:00
|
|
|
|
2023-06-12 20:32:31 +00:00
|
|
|
return true, ""
|
|
|
|
}
|
2023-06-14 17:46:46 +00:00
|
|
|
|
|
|
|
func (b Board) getSquareOfPiece(piece types.Piece) *types.Coordinate {
|
|
|
|
for k, v := range b {
|
|
|
|
if v == piece {
|
|
|
|
return &k
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b Board) isSquareAttacked(square types.Coordinate, byColor types.ChessColor) bool {
|
|
|
|
attacked := false
|
|
|
|
|
|
|
|
//get every legal move of color to check if this square is attacked
|
|
|
|
return attacked
|
|
|
|
}
|