Skip to content

Commit

Permalink
Notify when kings are checked on board (#45)
Browse files Browse the repository at this point in the history
* Added `didCheckKing(ofColor:)` method to `BoardDelegate` to notify
when a king is placed in check.
* Made `Move.checkState` and `Move.disambiguation` publicly readable

resolves #38
  • Loading branch information
pdil authored Sep 28, 2024
2 parents 0b36cf9 + 1d62745 commit f37fa69
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# [unreleased]

* `BoardDelegate` now notifies when king is in check, and provides the color of the checked king, see [Issue #38](https://github.com/chesskit-app/chesskit-swift/issues/38).
* `Move.checkState` and `Move.disambiguation` are now publicly accessible, see [Issue #38](https://github.com/chesskit-app/chesskit-swift/issues/38).

# ChessKit 0.12.1
Released Wednesday, September 11, 2024.

Expand Down
3 changes: 3 additions & 0 deletions Sources/ChessKit/Board.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/// as pawn promotions and end results.
public protocol BoardDelegate: AnyObject, Sendable {
func didPromote(with move: Move)
func didCheckKing(ofColor color: Piece.Color)
func didEnd(with result: Board.EndResult)
}

Expand Down Expand Up @@ -231,6 +232,8 @@ public struct Board: Sendable {
delegate?.didEnd(with: .draw(.insufficientMaterial))
} else if positionHashCounts[position.hashValue] == 3 {
delegate?.didEnd(with: .draw(.repetition))
} else if checkState == .check {
delegate?.didCheckKing(ofColor: processedMove.piece.color.opposite)
}

// pawn promotion
Expand Down
4 changes: 2 additions & 2 deletions Sources/ChessKit/Move.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public struct Move: Hashable, Sendable {
/// The piece that was promoted to, if applicable.
public internal(set) var promotedPiece: Piece?
/// The move disambiguation, if applicable.
var disambiguation: Disambiguation?
public internal(set) var disambiguation: Disambiguation?
/// The check state resulting from the move.
var checkState: CheckState
public internal(set) var checkState: CheckState
/// The move assessment annotation.
public var assessment: Assessment
/// The comment associated with a move.
Expand Down
15 changes: 15 additions & 0 deletions Tests/ChessKitTests/BoardTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,23 @@ final class BoardTests: XCTestCase {

func testCheckMove() {
var board = Board(position: .init(fen: "k7/7R/8/8/8/8/K7/8 w - - 0 1")!)

nonisolated(unsafe) var expectation: XCTestExpectation? = self.expectation(description: "Board returns check result")

let delegate = MockBoardDelegate(didCheckKing: { color in
if color == .black {
expectation?.fulfill()
expectation = nil
} else {
XCTFail()
}
})

board.delegate = delegate
let move = board.move(pieceAt: .h7, to: .h8)
XCTAssertEqual(move?.checkState, .check)

waitForExpectations(timeout: 1.0)
}

func testCheckmateMove() {
Expand Down
7 changes: 7 additions & 0 deletions Tests/ChessKitTests/Utilities/MockBoardDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,27 @@

final class MockBoardDelegate: BoardDelegate {
private let didPromote: (@Sendable (Move) -> Void)?
private let didCheckKing: (@Sendable (Piece.Color) -> Void)?
private let didEnd: (@Sendable (Board.EndResult) -> Void)?

init(
didPromote: (@Sendable (Move) -> Void)? = nil,
didCheckKing: (@Sendable (Piece.Color) -> Void)? = nil,
didEnd: (@Sendable (Board.EndResult) -> Void)? = nil
) {
self.didPromote = didPromote
self.didCheckKing = didCheckKing
self.didEnd = didEnd
}

func didPromote(with move: Move) {
didPromote?(move)
}

func didCheckKing(ofColor color: Piece.Color) {
didCheckKing?(color)
}

func didEnd(with result: Board.EndResult) {
didEnd?(result)
}
Expand Down

0 comments on commit f37fa69

Please sign in to comment.