private func getDirectionalMoves( from pos: Square.Position, with dir: [(Int8, Int8)] ) -> [Square.Position] { var squares = [Square.Position]() for i: (Int8, Int8) in dir { var currentSquare = pos + i while currentSquare.index != nil { squares.append(currentSquare) currentSquare += i } } return squares } protocol DiagonalMoves { func getDiagonalMoves(from pos: Square.Position) -> [Square.Position] } protocol Direction: CaseIterable { var values: (Int8, Int8) { get } static func isLegal( last: inout Square.Position?, current: Square.Position ) -> Bool } public enum DiagonalDirection: Direction { case northWest case northEast case southEast case southWest public var values: (Int8, Int8) { return switch self { case .northWest: (1, -1) case .northEast: (1, 1) case .southEast: (-1, 1) case .southWest: (-1, -1) } } public static func isLegal( last: inout Square.Position?, current: Square.Position ) -> Bool { var isPred = false for dir in DiagonalDirection.allCases { isPred = last == current - dir.values if isPred { last = current break } } return isPred } } extension DiagonalMoves { func getDiagonalMoves(from pos: Square.Position) -> [Square.Position] { getDirectionalMoves( from: pos, with: [ DiagonalDirection.northWest.values, DiagonalDirection.northEast.values, DiagonalDirection.southEast.values, DiagonalDirection.southWest.values, ]) } } protocol LinearMoves { func getLinearMoves(from pos: Square.Position) -> [Square.Position] } public enum LinearDirection: Direction { case north case south case east case west public var values: (Int8, Int8) { return switch self { case .north: (1, 0) case .south: (-1, 0) case .east: (0, 1) case .west: (0, -1) } } public static func isLegal( last: inout Square.Position?, current: Square.Position ) -> Bool { var isPred = false for dir in LinearDirection.allCases { isPred = last == current - dir.values if isPred { last = current break } } return isPred } } extension LinearMoves { func getLinearMoves(from pos: Square.Position) -> [Square.Position] { getDirectionalMoves( from: pos, with: [ LinearDirection.north.values, LinearDirection.east.values, LinearDirection.south.values, LinearDirection.west.values, ]) } }