2023-06-20 21:53:54 +00:00
|
|
|
package chess
|
|
|
|
|
|
|
|
import (
|
2023-06-25 14:11:29 +00:00
|
|
|
"mchess_server/types"
|
2023-06-20 21:53:54 +00:00
|
|
|
|
|
|
|
"github.com/samber/lo"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Pawn struct {
|
2023-06-25 14:11:29 +00:00
|
|
|
Color types.ChessColor
|
2023-06-20 21:53:54 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 14:11:29 +00:00
|
|
|
func (p Pawn) GetAllMovesButBlocked(board Board, fromSquare types.Coordinate) []types.Coordinate {
|
2023-06-20 21:53:54 +00:00
|
|
|
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:
|
2023-06-25 14:11:29 +00:00
|
|
|
firstMove := fromSquare.Row == types.RangeLastValid-1
|
|
|
|
|
|
|
|
if fromSquare.Down(1) != nil {
|
2023-06-20 21:53:54 +00:00
|
|
|
theoreticalMoves = append(theoreticalMoves, *fromSquare.Down(1))
|
|
|
|
}
|
2023-06-25 14:11:29 +00:00
|
|
|
if firstMove && fromSquare.Down(2) != nil {
|
2023-06-20 21:53:54 +00:00
|
|
|
theoreticalMoves = append(theoreticalMoves, *fromSquare.Down(2))
|
|
|
|
}
|
|
|
|
|
2023-06-25 14:11:29 +00:00
|
|
|
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)
|
|
|
|
}
|
2023-06-20 21:53:54 +00:00
|
|
|
|
|
|
|
case types.White:
|
2023-06-25 14:11:29 +00:00
|
|
|
firstMove := fromSquare.Row == types.RangeFirstValid+1
|
|
|
|
|
2023-06-20 21:53:54 +00:00
|
|
|
if fromSquare.Up(1) != nil {
|
|
|
|
theoreticalMoves = append(theoreticalMoves, *fromSquare.Up(1))
|
|
|
|
}
|
2023-06-25 14:11:29 +00:00
|
|
|
if firstMove && fromSquare.Up(2) != nil {
|
2023-06-20 21:53:54 +00:00
|
|
|
theoreticalMoves = append(theoreticalMoves, *fromSquare.Up(2))
|
|
|
|
}
|
|
|
|
|
2023-06-25 14:11:29 +00:00
|
|
|
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)
|
|
|
|
}
|
2023-06-20 21:53:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|