mchess-server/chess/pawn.go

84 lines
2.4 KiB
Go
Raw Normal View History

package chess
import (
"local/m/mchess_server/types"
"github.com/samber/lo"
)
type Pawn struct {
Color types.ChessColor
HasMoved bool
}
func (p Pawn) AfterMoveAction() {
p.HasMoved = true
}
func (p Pawn) GetAllLegalAndIllegalMoves(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:
if fromSquare.Down(1) != nil {
theoreticalMoves = append(theoreticalMoves, *fromSquare.Down(1))
}
if !p.HasMoved && 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:
if fromSquare.Up(1) != nil {
theoreticalMoves = append(theoreticalMoves, *fromSquare.Up(1))
}
if !p.HasMoved && 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)
}