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) }