Skip to content

Commit 220b4b0

Browse files
author
Alexander Perechnev
committed
Merge branch 'release/1.3.7'
2 parents 0a395c1 + 0102f61 commit 220b4b0

File tree

6 files changed

+95
-7
lines changed

6 files changed

+95
-7
lines changed

ChessKit.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |spec|
1010
spec.name = "ChessKit"
11-
spec.version = "1.3.6"
11+
spec.version = "1.3.7"
1212
spec.summary = "Lightweight and fast chess framework written in Swift."
1313

1414
spec.description = "Lightweight and fast chess framework written in Swift. ChessKit is used as a base freamework for Ladoga chess engine."

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ target 'MyApp' do
4242
end
4343
```
4444

45-
## Gettings Started
45+
## Getting Started
4646

4747
ChessKit is well covered by [documentation](https://aperechnev.github.io/ChessKit/). But anyway here you can find an example describing how to start working with ChessKit faster.
4848

Sources/ChessKit/Game.swift

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,43 @@ public class Game {
209209
.filter { $0.color != self.position.state.turn }
210210
}
211211

212-
if piece.kind == .rook {
213-
let kind: PieceKind = move.from.file == 0 ? .queen : .king
214-
215-
self.position.state.castlings = self.position.state.castlings
216-
.filter { $0.color != self.position.state.turn || $0.kind != kind }
212+
self.position.state.castlings = self.position.state.castlings.filter {
213+
// filter should return true if we should not exclude
214+
// filter should return false if we should exclude current castling
215+
// $0 is one of KQkq pieces (white K, white Q, black k, black q)
216+
// castlingColorAndSideToExclude returns piece if move from/to is at some of 4 corners
217+
// if castlingColorAndSideToExclude returns piece
218+
// for either "from" or for "to" square - we have to exclude casling
219+
var excludeBecauseOfFrom = false
220+
var excludeBecauseOfTo = false
221+
if let colorAndSideToExclude = castlingColorAndSideToExclude(square: move.from) {
222+
excludeBecauseOfFrom = $0.color == colorAndSideToExclude.color && $0.kind == colorAndSideToExclude.kind
223+
}
224+
if let colorAndSideToExclude = castlingColorAndSideToExclude(square: move.to) {
225+
excludeBecauseOfTo = $0.color == colorAndSideToExclude.color && $0.kind == colorAndSideToExclude.kind
226+
}
227+
return !(excludeBecauseOfFrom || excludeBecauseOfTo)
228+
}
229+
}
230+
231+
private func castlingColorAndSideToExclude(square: Square) -> Piece? {
232+
// is A1?
233+
if square.file == 0 && square.rank == 0 {
234+
return Piece(kind: .queen, color: .white)
235+
}
236+
// is H1?
237+
if square.file == 7 && square.rank == 0 {
238+
return Piece(kind: .king, color: .white)
239+
}
240+
// is A8?
241+
if square.file == 0 && square.rank == 7 {
242+
return Piece(kind: .queen, color: .black)
243+
}
244+
// is H8?
245+
if square.file == 7 && square.rank == 7 {
246+
return Piece(kind: .king, color: .black)
217247
}
248+
return nil
218249
}
219250

220251
// MARK: Utilities

Sources/ChessKit/Rules/StandardRules.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ public class StandardRules: Rules {
169169
nextPosition.board[move.to] = nextPosition.board[move.from]
170170
nextPosition.board[move.from] = nil
171171

172+
// if move is en passant capture - remove captured pawn from board
173+
if let enPassantCapturedPawn = self.squareOfEnPassantCapturedPawn(move: move, position: position) {
174+
nextPosition.board[enPassantCapturedPawn] = nil
175+
}
176+
172177
if self.isIllelgalCastling(move: move, position: position) {
173178
return false
174179
}
@@ -179,6 +184,16 @@ public class StandardRules: Rules {
179184
return moves.filter(filter)
180185
}
181186

187+
private func squareOfEnPassantCapturedPawn(move: Move, position: Position) -> Square? {
188+
guard let enPassant = position.state.enPasant else {
189+
return nil
190+
}
191+
if move.to.file == enPassant.file && move.to.rank == enPassant.rank {
192+
return Square(file: enPassant.file, rank: enPassant.rank == 2 ? 3 : 4)
193+
}
194+
return nil
195+
}
196+
182197
private func enumeratedPieces(for position: Position) -> [(Square, Piece)] {
183198
return position.board.enumeratedPieces()
184199
.filter { $0.1.color == position.state.turn }
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// BoardPerformanceTests.swift
3+
// ChessKitTests
4+
//
5+
// Created by Alexander Perechnev on 25.08.2021.
6+
//
7+
8+
import XCTest
9+
@testable import ChessKit
10+
11+
class BoardPerformanceTests: XCTestCase {
12+
13+
private let board = Board()
14+
private let range = 0 ..< 100_000
15+
16+
private let coordinate = "e4"
17+
private let square = Square(coordinate: "e4")
18+
private let index = Square(coordinate: "e4").index
19+
20+
func testAccessByCoordinatePerformance() throws {
21+
self.measure {
22+
range.forEach { _ in let _ = board["e4"] }
23+
}
24+
}
25+
26+
func testAccessBySquarePerformance() throws {
27+
self.measure {
28+
range.forEach { _ in let _ = board[square] }
29+
}
30+
}
31+
32+
func testAccessByIndexPerformance() throws {
33+
self.measure {
34+
range.forEach { _ in let _ = board[index] }
35+
}
36+
}
37+
38+
}

Tests/ChessKitTests/Rules/Standard/PawnMovesTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class PawnMovesTests: XCTestCase {
5454
self.assert(fen: "rnbqkbnr/ppp1pppp/8/8/3pP1P1/7P/PPPP1P2/RNBQKBNR b KQkq e3 0 3",
5555
moves: "d4d3 d4e3",
5656
coordinate: "d4")
57+
58+
self.assert(fen: "8/8/3p2k1/P2Pr1Pp/3R2KP/8/8/8 w - h6 0 2",
59+
moves: "g5h6",
60+
coordinate: "g5")
5761
}
5862

5963
private func assert(fen: String, moves: String, coordinate: String) {

0 commit comments

Comments
 (0)