Refactor a itsy bitsy tiny bit and add rook moves.
This commit is contained in:
parent
f79e5be008
commit
3d4fee2631
@ -183,97 +183,13 @@ func (b *Board) handleSpecialMove(move types.Move) bool {
|
|||||||
|
|
||||||
switch pieceAtStartSquare.(type) {
|
switch pieceAtStartSquare.(type) {
|
||||||
case Pawn:
|
case Pawn:
|
||||||
was = b.handlePossiblePromotion(move)
|
pawn := pieceAtStartSquare.(Pawn)
|
||||||
|
was = pawn.HandlePossiblePromotion(b, move)
|
||||||
if !was {
|
if !was {
|
||||||
was = b.handleEnPassant(move, b.getLastMove())
|
was = pawn.HandleEnPassant(b, move, b.getLastMove())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return was
|
return was
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Board) handlePossiblePromotion(move types.Move) bool {
|
|
||||||
var isPromotionMove bool
|
|
||||||
var promotionToPiece types.PieceShortName
|
|
||||||
|
|
||||||
//TODO(m): What if message does not contain a promotion, but should be because a pawn is moved to the end square
|
|
||||||
messageContainsPromotion := move.IsPromotionMove()
|
|
||||||
|
|
||||||
if messageContainsPromotion {
|
|
||||||
promotionToPiece = *move.PromotionToPiece
|
|
||||||
}
|
|
||||||
|
|
||||||
switch move.ColorMoved {
|
|
||||||
case types.White:
|
|
||||||
if move.StartSquare.Row == types.RangeLastValid-1 &&
|
|
||||||
move.EndSquare.Row == types.RangeLastValid {
|
|
||||||
isPromotionMove = true
|
|
||||||
}
|
|
||||||
|
|
||||||
case types.Black:
|
|
||||||
if move.StartSquare.Row == types.RangeFirstValid+1 &&
|
|
||||||
move.EndSquare.Row == types.RangeFirstValid {
|
|
||||||
isPromotionMove = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if isPromotionMove {
|
|
||||||
delete(b.position, move.StartSquare)
|
|
||||||
b.position[move.EndSquare] = GetPieceForShortName(promotionToPiece, move.ColorMoved)
|
|
||||||
}
|
|
||||||
|
|
||||||
return isPromotionMove
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Board) handleEnPassant(move, lastMove types.Move) bool {
|
|
||||||
var wasEnPassant bool
|
|
||||||
|
|
||||||
if lastMove.PieceMoved != types.PawnShortName {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch move.ColorMoved {
|
|
||||||
case types.White:
|
|
||||||
if lastMove.StartSquare.Row != 7 || lastMove.EndSquare.Row != 5 {
|
|
||||||
wasEnPassant = false
|
|
||||||
}
|
|
||||||
if move.StartSquare.Row != 5 {
|
|
||||||
wasEnPassant = false
|
|
||||||
}
|
|
||||||
if move.EndSquare.Row != 6 {
|
|
||||||
wasEnPassant = false
|
|
||||||
}
|
|
||||||
if move.StartSquare.Col == lastMove.EndSquare.Col+1 &&
|
|
||||||
move.EndSquare.Col == lastMove.EndSquare.Col {
|
|
||||||
wasEnPassant = true
|
|
||||||
}
|
|
||||||
if move.StartSquare.Col == lastMove.EndSquare.Col-1 &&
|
|
||||||
move.EndSquare.Col == lastMove.EndSquare.Col {
|
|
||||||
wasEnPassant = true
|
|
||||||
}
|
|
||||||
case types.Black:
|
|
||||||
if lastMove.StartSquare.Row != 2 || lastMove.EndSquare.Row != 4 {
|
|
||||||
wasEnPassant = false
|
|
||||||
}
|
|
||||||
if move.StartSquare.Row != 4 {
|
|
||||||
wasEnPassant = false
|
|
||||||
}
|
|
||||||
if move.EndSquare.Row != 3 {
|
|
||||||
wasEnPassant = false
|
|
||||||
}
|
|
||||||
if move.StartSquare.Col == lastMove.EndSquare.Col+1 &&
|
|
||||||
move.EndSquare.Col == lastMove.EndSquare.Col {
|
|
||||||
wasEnPassant = true
|
|
||||||
}
|
|
||||||
if move.StartSquare.Col == lastMove.EndSquare.Col-1 &&
|
|
||||||
move.EndSquare.Col == lastMove.EndSquare.Col {
|
|
||||||
wasEnPassant = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if wasEnPassant { //play the move
|
|
||||||
delete(b.position, lastMove.EndSquare)
|
|
||||||
b.position[move.EndSquare] = GetPieceForShortName(move.PieceMoved, move.ColorMoved)
|
|
||||||
}
|
|
||||||
|
|
||||||
return wasEnPassant
|
|
||||||
}
|
|
||||||
|
@ -117,10 +117,20 @@ func Test_CheckMove_invalidPawnMoves(t *testing.T) {
|
|||||||
assert.Equal(t, boardBeforeMove, board)
|
assert.Equal(t, boardBeforeMove, board)
|
||||||
})
|
})
|
||||||
|
|
||||||
// t.Run("king of moving color is in check after move", func(t *testing.T) {
|
t.Run("king of moving color is in check after move", func(t *testing.T) {
|
||||||
// good, _ := board.CheckMove(move)
|
var board = newBoard()
|
||||||
// assert.False(t, good)
|
|
||||||
// })
|
board.position[types.Coordinate{Col: 1, Row: 6}] = King{Color: types.White}
|
||||||
|
board.position[types.Coordinate{Col: 2, Row: 6}] = Pawn{Color: types.White}
|
||||||
|
board.position[types.Coordinate{Col: 8, Row: 6}] = King{Color: types.Black}
|
||||||
|
|
||||||
|
move := types.Move{
|
||||||
|
StartSquare: types.Coordinate{Col: 2, Row: 6},
|
||||||
|
EndSquare: types.Coordinate{Col: 2, Row: 7},
|
||||||
|
}
|
||||||
|
good, _ := board.CheckAndPlay(move)
|
||||||
|
assert.False(t, good)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_CheckMove_validPromotion(t *testing.T) {
|
func Test_CheckMove_validPromotion(t *testing.T) {
|
||||||
|
41
chess/free_squares.go
Normal file
41
chess/free_squares.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package chess
|
||||||
|
|
||||||
|
import "mchess_server/types"
|
||||||
|
|
||||||
|
func (b *Board) GetNonBlockedRowAndColumn(fromSquare types.Coordinate) []types.Coordinate {
|
||||||
|
squaresLeft := fromSquare.GetAllSquaresLeft()
|
||||||
|
squaresRight := fromSquare.GetAllSquaresRight()
|
||||||
|
squaresAbove := fromSquare.GetAllSquaresAbove()
|
||||||
|
squaresBelow := fromSquare.GetAllSquaresBelow()
|
||||||
|
nonBlocked := []types.Coordinate{}
|
||||||
|
|
||||||
|
nonBlocked = append(nonBlocked, b.getNonBlocked(squaresLeft, fromSquare)...)
|
||||||
|
nonBlocked = append(nonBlocked, b.getNonBlocked(squaresRight, fromSquare)...)
|
||||||
|
nonBlocked = append(nonBlocked, b.getNonBlocked(squaresAbove, fromSquare)...)
|
||||||
|
nonBlocked = append(nonBlocked, b.getNonBlocked(squaresBelow, fromSquare)...)
|
||||||
|
|
||||||
|
return nonBlocked
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Board) getNonBlocked(
|
||||||
|
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() {
|
||||||
|
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
|
||||||
|
}
|
@ -21,6 +21,102 @@ func (p Pawn) GetColor() types.ChessColor {
|
|||||||
return p.Color
|
return p.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pawn) HandlePossiblePromotion(b *Board ,move types.Move) bool {
|
||||||
|
var isPromotionMove bool
|
||||||
|
var promotionToPiece types.PieceShortName
|
||||||
|
|
||||||
|
//TODO(m): What if message does not contain a promotion, but should be because a pawn is moved to the end square
|
||||||
|
messageContainsPromotion := move.IsPromotionMove()
|
||||||
|
|
||||||
|
if messageContainsPromotion {
|
||||||
|
promotionToPiece = *move.PromotionToPiece
|
||||||
|
}
|
||||||
|
|
||||||
|
switch move.ColorMoved {
|
||||||
|
case types.White:
|
||||||
|
if move.StartSquare.Row == types.RangeLastValid-1 &&
|
||||||
|
move.EndSquare.Row == types.RangeLastValid {
|
||||||
|
isPromotionMove = true
|
||||||
|
}
|
||||||
|
|
||||||
|
case types.Black:
|
||||||
|
if move.StartSquare.Row == types.RangeFirstValid+1 &&
|
||||||
|
move.EndSquare.Row == types.RangeFirstValid {
|
||||||
|
isPromotionMove = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPromotionMove {
|
||||||
|
delete(b.position, move.StartSquare)
|
||||||
|
b.position[move.EndSquare] = GetPieceForShortName(promotionToPiece, move.ColorMoved)
|
||||||
|
}
|
||||||
|
|
||||||
|
return isPromotionMove
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pawn) HandleEnPassant(b *Board, move, lastMove types.Move) bool {
|
||||||
|
var wasEnPassant bool
|
||||||
|
|
||||||
|
if lastMove.PieceMoved != types.PawnShortName {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch move.ColorMoved {
|
||||||
|
case types.White:
|
||||||
|
if lastMove.StartSquare.Row != 7 || lastMove.EndSquare.Row != 5 {
|
||||||
|
wasEnPassant = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.StartSquare.Row != 5 {
|
||||||
|
wasEnPassant = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.EndSquare.Row != 6 {
|
||||||
|
wasEnPassant = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.StartSquare.Col == lastMove.EndSquare.Col+1 &&
|
||||||
|
move.EndSquare.Col == lastMove.EndSquare.Col {
|
||||||
|
wasEnPassant = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.StartSquare.Col == lastMove.EndSquare.Col-1 &&
|
||||||
|
move.EndSquare.Col == lastMove.EndSquare.Col {
|
||||||
|
wasEnPassant = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case types.Black:
|
||||||
|
if lastMove.StartSquare.Row != 2 || lastMove.EndSquare.Row != 4 {
|
||||||
|
wasEnPassant = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.StartSquare.Row != 4 {
|
||||||
|
wasEnPassant = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.EndSquare.Row != 3 {
|
||||||
|
wasEnPassant = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.StartSquare.Col == lastMove.EndSquare.Col+1 &&
|
||||||
|
move.EndSquare.Col == lastMove.EndSquare.Col {
|
||||||
|
wasEnPassant = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if move.StartSquare.Col == lastMove.EndSquare.Col-1 &&
|
||||||
|
move.EndSquare.Col == lastMove.EndSquare.Col {
|
||||||
|
wasEnPassant = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if wasEnPassant { //play the move
|
||||||
|
delete(b.position, lastMove.EndSquare)
|
||||||
|
b.position[move.EndSquare] = GetPieceForShortName(move.PieceMoved, move.ColorMoved)
|
||||||
|
}
|
||||||
|
|
||||||
|
return wasEnPassant
|
||||||
|
}
|
||||||
func (p Pawn) getAllMoves(fromSquare types.Coordinate) []types.Coordinate {
|
func (p Pawn) getAllMoves(fromSquare types.Coordinate) []types.Coordinate {
|
||||||
theoreticalMoves := make([]types.Coordinate, 0, 4)
|
theoreticalMoves := make([]types.Coordinate, 0, 4)
|
||||||
|
|
||||||
@ -80,3 +176,4 @@ func (p Pawn) filterBlockedSquares(board Board, fromSquare types.Coordinate, squ
|
|||||||
}
|
}
|
||||||
return lo.Intersect(nonBlockedSquares, squaresToBeFiltered)
|
return lo.Intersect(nonBlockedSquares, squaresToBeFiltered)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,17 +3,16 @@ package chess
|
|||||||
import "mchess_server/types"
|
import "mchess_server/types"
|
||||||
|
|
||||||
type Rook struct {
|
type Rook struct {
|
||||||
Color types.ChessColor
|
Color types.ChessColor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Rook) AfterMoveAction() {
|
func (r Rook) AfterMoveAction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetColor implements Piece.
|
|
||||||
func (r Rook) GetColor() types.ChessColor {
|
func (r Rook) GetColor() types.ChessColor {
|
||||||
return r.Color
|
return r.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Rook) GetAllMovesButBlocked(board Board, fromSquare types.Coordinate) []types.Coordinate {
|
func (r Rook) GetAllMovesButBlocked(board Board, fromSquare types.Coordinate) []types.Coordinate {
|
||||||
return []types.Coordinate{}
|
return board.GetNonBlockedRowAndColumn(fromSquare)
|
||||||
}
|
}
|
||||||
|
72
chess/rook_test.go
Normal file
72
chess/rook_test.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package chess
|
||||||
|
|
||||||
|
import (
|
||||||
|
"mchess_server/types"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Rook_GetNonBlockedSquares(t *testing.T) {
|
||||||
|
t.Run("free row and column", func(t *testing.T) {
|
||||||
|
board := newBoard()
|
||||||
|
rook := Rook{Color: types.Black}
|
||||||
|
|
||||||
|
board.position[types.Coordinate{Col: 5, Row: 5}] = rook
|
||||||
|
squares := rook.GetAllMovesButBlocked(board, types.Coordinate{Col: 5, Row: 5})
|
||||||
|
assert.Len(t, squares, 14)
|
||||||
|
assert.Equal(t, types.Coordinate{Col: 4, Row: 5}, squares[0])
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("free row and column", func(t *testing.T) {
|
||||||
|
board := newBoard()
|
||||||
|
rook := Rook{Color: types.Black}
|
||||||
|
rookCoordinate := types.Coordinate{Col: 5, Row: 5}
|
||||||
|
|
||||||
|
board.position[rookCoordinate] = rook
|
||||||
|
board.position[types.Coordinate{Col: 3, Row: 5}] = Pawn{Color: types.White}
|
||||||
|
board.position[types.Coordinate{Col: 5, Row: 6}] = Pawn{Color: types.White}
|
||||||
|
board.position[types.Coordinate{Col: 6, Row: 5}] = Pawn{Color: types.Black}
|
||||||
|
|
||||||
|
squares := rook.GetAllMovesButBlocked(board, types.Coordinate{Col: 5, Row: 5})
|
||||||
|
|
||||||
|
squaresOnLeft := lo.Filter(squares, func(square types.Coordinate, _ int) bool {
|
||||||
|
return square.Row == rookCoordinate.Row && square.Col < rookCoordinate.Col
|
||||||
|
})
|
||||||
|
assert.Equal(t,
|
||||||
|
[]types.Coordinate{
|
||||||
|
{Col: 4, Row: 5},
|
||||||
|
{Col: 3, Row: 5},
|
||||||
|
},
|
||||||
|
squaresOnLeft)
|
||||||
|
|
||||||
|
squaresOnRight := lo.Filter(squares, func(square types.Coordinate, _ int) bool {
|
||||||
|
return square.Row == rookCoordinate.Row && square.Col > rookCoordinate.Col
|
||||||
|
})
|
||||||
|
assert.Equal(t,
|
||||||
|
[]types.Coordinate{},
|
||||||
|
squaresOnRight)
|
||||||
|
|
||||||
|
squaresAbove := lo.Filter(squares, func(square types.Coordinate, _ int) bool {
|
||||||
|
return square.Col == rookCoordinate.Col && square.Row > rookCoordinate.Row
|
||||||
|
})
|
||||||
|
assert.Equal(t,
|
||||||
|
[]types.Coordinate{
|
||||||
|
{Col: 5, Row: 6},
|
||||||
|
},
|
||||||
|
squaresAbove)
|
||||||
|
|
||||||
|
squaresBelow := lo.Filter(squares, func(square types.Coordinate, _ int) bool {
|
||||||
|
return square.Col == rookCoordinate.Col && square.Row < rookCoordinate.Row
|
||||||
|
})
|
||||||
|
assert.Equal(t,
|
||||||
|
[]types.Coordinate{
|
||||||
|
{Col: 5, Row: 4},
|
||||||
|
{Col: 5, Row: 3},
|
||||||
|
{Col: 5, Row: 2},
|
||||||
|
{Col: 5, Row: 1},
|
||||||
|
},
|
||||||
|
squaresBelow)
|
||||||
|
})
|
||||||
|
}
|
@ -1,49 +1,6 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
// coordinates starting at 1:1 and end at 8:8
|
|
||||||
type Coordinate struct {
|
|
||||||
Col int `json:"col"`
|
|
||||||
Row int `json:"row"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
RangeLastValid = 8
|
|
||||||
RangeFirstValid = 1
|
|
||||||
|
|
||||||
RangeUpperInvalid = 9
|
|
||||||
RangeLowerInvalid = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c Coordinate) Up(number int) *Coordinate {
|
|
||||||
check := c.Row + number
|
|
||||||
if check <= RangeLastValid {
|
|
||||||
return &Coordinate{Row: check, Col: c.Col}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (c Coordinate) Down(number int) *Coordinate {
|
|
||||||
check := c.Row - number
|
|
||||||
if check >= RangeFirstValid {
|
|
||||||
return &Coordinate{Row: check, Col: c.Col}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right and left is seen from a board where row 1 is on the bottom
|
|
||||||
func (c Coordinate) Right(number int) *Coordinate {
|
|
||||||
check := c.Col + number
|
|
||||||
if check >= RangeFirstValid {
|
|
||||||
return &Coordinate{Row: c.Row, Col: check}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (c Coordinate) Left(number int) *Coordinate {
|
|
||||||
check := c.Col - number
|
|
||||||
if check >= RangeFirstValid {
|
|
||||||
return &Coordinate{Row: c.Row, Col: check}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChessColor string
|
type ChessColor string
|
||||||
|
|
||||||
|
127
types/coordinate.go
Normal file
127
types/coordinate.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
// coordinates starting at 1:1 and end at 8:8
|
||||||
|
type Coordinate struct {
|
||||||
|
Col int `json:"col"`
|
||||||
|
Row int `json:"row"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
RangeLastValid = 8
|
||||||
|
RangeFirstValid = 1
|
||||||
|
|
||||||
|
RangeUpperInvalid = 9
|
||||||
|
RangeLowerInvalid = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c Coordinate) Up(number int) *Coordinate {
|
||||||
|
check := c.Row + number
|
||||||
|
if check <= RangeLastValid {
|
||||||
|
return &Coordinate{Row: check, Col: c.Col}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c Coordinate) Down(number int) *Coordinate {
|
||||||
|
check := c.Row - number
|
||||||
|
if check >= RangeFirstValid {
|
||||||
|
return &Coordinate{Row: check, Col: c.Col}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right and left is seen from a board where row 1 is on the bottom
|
||||||
|
func (c Coordinate) Right(number int) *Coordinate {
|
||||||
|
check := c.Col + number
|
||||||
|
if check <= RangeLastValid {
|
||||||
|
return &Coordinate{Row: c.Row, Col: check}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c Coordinate) Left(number int) *Coordinate {
|
||||||
|
check := c.Col - number
|
||||||
|
if check >= RangeFirstValid {
|
||||||
|
return &Coordinate{Row: c.Row, Col: check}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Coordinate) GetAllSquaresLeft() []Coordinate {
|
||||||
|
squares := []Coordinate{}
|
||||||
|
i := 1
|
||||||
|
for {
|
||||||
|
if square := c.Left(i); square != nil {
|
||||||
|
squares = append(squares, *square)
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
return squares
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Coordinate) GetAllSquaresRight() []Coordinate {
|
||||||
|
squares := []Coordinate{}
|
||||||
|
i := 1
|
||||||
|
for {
|
||||||
|
if square := c.Right(i); square != nil {
|
||||||
|
squares = append(squares, *square)
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
return squares
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Coordinate) GetAllSquaresAbove() []Coordinate {
|
||||||
|
squares := []Coordinate{}
|
||||||
|
i := 1
|
||||||
|
for {
|
||||||
|
if square := c.Up(i); square != nil {
|
||||||
|
squares = append(squares, *square)
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
return squares
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Coordinate) GetAllSquaresBelow() []Coordinate {
|
||||||
|
squares := []Coordinate{}
|
||||||
|
i := 1
|
||||||
|
for {
|
||||||
|
if square := c.Down(i); square != nil {
|
||||||
|
squares = append(squares, *square)
|
||||||
|
i += 1
|
||||||
|
} else {
|
||||||
|
return squares
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c Coordinate) GetSquaresOnRow() []Coordinate {
|
||||||
|
rowToReturn := []Coordinate{}
|
||||||
|
leftMostSquareOnRow := Coordinate{Col: RangeFirstValid, Row: c.Row}
|
||||||
|
index := 0
|
||||||
|
for {
|
||||||
|
squareToAppend := leftMostSquareOnRow.Right(index)
|
||||||
|
if squareToAppend == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
rowToReturn = append(rowToReturn, *squareToAppend)
|
||||||
|
index = index + 1
|
||||||
|
}
|
||||||
|
return rowToReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Coordinate) GetSquaresOnColumn() []Coordinate {
|
||||||
|
columnToReturn := []Coordinate{}
|
||||||
|
bottomSquareOnColumn := Coordinate{Col: c.Col, Row: RangeFirstValid}
|
||||||
|
index := 0
|
||||||
|
for {
|
||||||
|
squareToAppend := bottomSquareOnColumn.Up(index)
|
||||||
|
if squareToAppend == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
columnToReturn = append(columnToReturn, *squareToAppend)
|
||||||
|
index = index + 1
|
||||||
|
}
|
||||||
|
return columnToReturn
|
||||||
|
}
|
25
types/coordinate_test.go
Normal file
25
types/coordinate_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Coordinate_GetSquaresOfRow(t *testing.T) {
|
||||||
|
t.Run("get row for a coordinate", func(t *testing.T) {
|
||||||
|
startSquare := Coordinate{Col: 4, Row: 2}
|
||||||
|
row := startSquare.GetSquaresOnRow()
|
||||||
|
assert.Len(t, row, 8)
|
||||||
|
assert.Equal(t,row[0].Col, 1)
|
||||||
|
assert.Equal(t,row[7].Col, 8)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("get column for a coordinate", func(t *testing.T) {
|
||||||
|
startSquare := Coordinate{Col: 4, Row: 2}
|
||||||
|
column := startSquare.GetSquaresOnColumn()
|
||||||
|
assert.Len(t, column, 8)
|
||||||
|
assert.Equal(t,column[0].Row, 1)
|
||||||
|
assert.Equal(t,column[7].Row, 8)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user