mchess-server/chess/free_squares.go
Marco 26242424ed Implement thread-safe ringbuffer for websocket messages
This implements a ringbuffer that is used to decouple the raw websocket
connection from the messages that the game handler handles.
2023-11-26 21:37:14 +01:00

83 lines
3.2 KiB
Go

package chess
import "mchess_server/types"
func (b *Board) GetNonBlockedRowAndColumn(fromSquare types.Coordinate) []types.Coordinate {
squaresLeft := fromSquare.GetStraightInDirection(types.Coordinate.Left)
squaresRight := fromSquare.GetStraightInDirection(types.Coordinate.Right)
squaresAbove := fromSquare.GetStraightInDirection(types.Coordinate.Up)
squaresBelow := fromSquare.GetStraightInDirection(types.Coordinate.Down)
nonBlocked := b.getNonBlockedConsecutive(squaresLeft, fromSquare)
nonBlocked = append(nonBlocked, b.getNonBlockedConsecutive(squaresRight, fromSquare)...)
nonBlocked = append(nonBlocked, b.getNonBlockedConsecutive(squaresAbove, fromSquare)...)
nonBlocked = append(nonBlocked, b.getNonBlockedConsecutive(squaresBelow, fromSquare)...)
return nonBlocked
}
func (b *Board) GetNonBlockedDiagonals(fromSquare types.Coordinate) []types.Coordinate {
rightUp := fromSquare.GetDiagonalInDirection(types.Coordinate.Right, types.Coordinate.Up)
leftUp := fromSquare.GetDiagonalInDirection(types.Coordinate.Left, types.Coordinate.Up)
leftDown := fromSquare.GetDiagonalInDirection(types.Coordinate.Left, types.Coordinate.Down)
rightDown := fromSquare.GetDiagonalInDirection(types.Coordinate.Right, types.Coordinate.Down)
nonBlocked := b.getNonBlockedConsecutive(rightUp, fromSquare)
nonBlocked = append(nonBlocked, b.getNonBlockedConsecutive(leftUp, fromSquare)...)
nonBlocked = append(nonBlocked, b.getNonBlockedConsecutive(leftDown, fromSquare)...)
nonBlocked = append(nonBlocked, b.getNonBlockedConsecutive(rightDown, fromSquare)...)
return nonBlocked
}
func (b *Board) GetNonBlockedKingMoves(fromSquare types.Coordinate) []types.Coordinate {
return b.getNonBlockedRaw(fromSquare.GetAllKingMoves(), fromSquare)
}
func (b *Board) GetNonBlockedKnightMoves(fromSquare types.Coordinate) []types.Coordinate {
return b.getNonBlockedRaw(fromSquare.GetAllKnightMoves(), fromSquare)
}
// returns only those squares in a straight/diagonal that are not blocked
// until it hits a blocking piece (excluding same color, including diff color)
func (b *Board) getNonBlockedConsecutive(
squaresToCheck []types.Coordinate,
sourceSquare types.Coordinate,
) []types.Coordinate {
pieceOnSourceSquare := b.getPieceAt(sourceSquare)
nonBlocked := []types.Coordinate{}
for _, square := range squaresToCheck {
piece := b.getPieceAt(square)
if piece != nil {
if piece.GetColor() == pieceOnSourceSquare.GetColor() {
//We do not append squares with same-colored pieces
//and also not the squares behind it
break
}
// if there is an opposite colored piece we append it but
// stop appending the squares behind it
nonBlocked = append(nonBlocked, square)
break
}
nonBlocked = append(nonBlocked, square)
}
return nonBlocked
}
// returns any square in squaresToCheck that are not blocked
func (b *Board) getNonBlockedRaw(
squaresToCheck []types.Coordinate,
sourceSquare types.Coordinate,
) []types.Coordinate {
pieceOnSourceSquare := b.getPieceAt(sourceSquare)
nonBlocked := []types.Coordinate{}
for _, square := range squaresToCheck {
piece := b.getPieceAt(square)
if piece == nil || piece.GetColor() != pieceOnSourceSquare.GetColor() {
nonBlocked = append(nonBlocked, square)
}
}
return nonBlocked
}