mchess-server/chess/pawn.go
2023-06-25 16:11:29 +02:00

83 lines
2.4 KiB
Go

package chess
import (
"mchess_server/types"
"github.com/samber/lo"
)
type Pawn struct {
Color types.ChessColor
}
func (p Pawn) GetAllMovesButBlocked(board Board, fromSquare types.Coordinate) []types.Coordinate {
theoreticalSquares := p.getAllMoves(fromSquare)
legalSquares := p.filterBlockedSquares(board, fromSquare, theoreticalSquares)
return legalSquares
}
func (p Pawn) GetColor() types.ChessColor {
return p.Color
}
func (p Pawn) getAllMoves(fromSquare types.Coordinate) []types.Coordinate {
theoreticalMoves := make([]types.Coordinate, 0, 4)
switch p.Color {
case types.Black:
firstMove := fromSquare.Row == types.RangeLastValid-1
if fromSquare.Down(1) != nil {
theoreticalMoves = append(theoreticalMoves, *fromSquare.Down(1))
}
if firstMove && fromSquare.Down(2) != nil {
theoreticalMoves = append(theoreticalMoves, *fromSquare.Down(2))
}
if lowerRight := fromSquare.Down(1).Right(1); lowerRight != nil {
theoreticalMoves = append(theoreticalMoves, *lowerRight)
}
if lowerLeft := fromSquare.Down(1).Left(1); lowerLeft != nil {
theoreticalMoves = append(theoreticalMoves, *lowerLeft)
}
case types.White:
firstMove := fromSquare.Row == types.RangeFirstValid+1
if fromSquare.Up(1) != nil {
theoreticalMoves = append(theoreticalMoves, *fromSquare.Up(1))
}
if firstMove && fromSquare.Up(2) != nil {
theoreticalMoves = append(theoreticalMoves, *fromSquare.Up(2))
}
if upperRight := fromSquare.Up(1).Right(1); upperRight != nil {
theoreticalMoves = append(theoreticalMoves, *upperRight)
}
if upperLeft := fromSquare.Up(1).Left(1); upperLeft != nil {
theoreticalMoves = append(theoreticalMoves, *upperLeft)
}
}
return theoreticalMoves
}
func (p Pawn) filterBlockedSquares(board Board, fromSquare types.Coordinate, squaresToBeFiltered []types.Coordinate) []types.Coordinate {
var nonBlockedSquares []types.Coordinate
//order of movesToBeFiltered is important here
for _, square := range squaresToBeFiltered {
pieceAtSquare := board.getPieceAt(square)
if square.Col == fromSquare.Col { // squares ahead
if pieceAtSquare == nil {
nonBlockedSquares = append(nonBlockedSquares, square)
}
} else { //squares that pawn attacks
if pieceAtSquare != nil && pieceAtSquare.GetColor() != p.Color {
nonBlockedSquares = append(nonBlockedSquares, square)
}
}
}
return lo.Intersect(nonBlockedSquares, squaresToBeFiltered)
}