6 Commits

Author SHA1 Message Date
Steve Barnegren 42fd768958 Updated podspec 2017-12-21 17:16:19 +00:00
Steve Barnegren f8e53472bf Merge pull request #2 from sochalewski/master
Swifty, swifter, the swiftest
2017-12-21 16:44:16 +00:00
Piotr Sochalewski ac147b5ee8 Swifty, swifter, the swiftest 2017-12-09 12:58:05 +01:00
Steve Barnegren fdf1f73ce9 Merge branch 'development'
# Conflicts:
#	.swift-version
2017-11-18 19:22:26 +00:00
Steve Barnegren 16c757ff1f Merge branch 'development' 2017-04-02 18:45:29 +01:00
Steve Barnegren 88dda592b9 Added swift version file for cocoa pods 2017-03-16 22:22:19 +00:00
41 changed files with 543 additions and 502 deletions
+6 -6
View File
@@ -267,7 +267,7 @@ extension GameViewController: BoardViewDelegate {
}
// Select new piece if possible
if player.occupiesSquareAt(location: location) {
if player.occupiesSquare(at: location) {
selectedIndex = index
}
@@ -275,8 +275,8 @@ extension GameViewController: BoardViewDelegate {
if let selectedIndex = selectedIndex {
do {
try player.movePiece(fromLocation: BoardLocation(index: selectedIndex),
toLocation: location)
try player.movePiece(from: BoardLocation(index: selectedIndex),
to: location)
} catch Player.MoveError.pieceUnableToMoveToLocation {
print("Piece is unable to move to this location")
@@ -309,7 +309,7 @@ extension GameViewController: GameDelegate {
}
func gameDidAddPiece(game: Game) {
// do nothing
// Do nothing
}
func gameDidMovePiece(game: Game, piece: Piece, toLocation: BoardLocation) {
@@ -320,7 +320,7 @@ extension GameViewController: GameDelegate {
pieceView.location = toLocation
// Animage
// Animate
view.setNeedsLayout()
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
@@ -359,7 +359,7 @@ extension GameViewController: GameDelegate {
func gameWonByPlayer(game: Game, player: Player) {
let colorName = player.color.toString()
let colorName = player.color.string
let title = "Checkmate!"
let message = "\(colorName.capitalized) wins!"
@@ -11,16 +11,6 @@ import SwiftChess
class MenuViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Actions
@IBAction func playerVsAIButtonPressed(_ sender: UIButton) {
+20 -20
View File
@@ -37,12 +37,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterCountPiecesWeighting = 1
let lowValueRater = BoardRaterCountPieces(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterCountPiecesWeighting = 2
let highValueRater = BoardRaterCountPieces(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -63,12 +63,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterBoardDominanceWeighting = 1
let lowValueRater = BoardRaterBoardDominance(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterBoardDominanceWeighting = 2
let highValueRater = BoardRaterBoardDominance(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -89,12 +89,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterCenterOwnershipWeighting = 1
let lowValueRater = BoardRaterCenterOwnership(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterCenterOwnershipWeighting = 2
let highValueRater = BoardRaterCenterOwnership(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -115,12 +115,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterCenterDominanceWeighting = 1
let lowValueRater = BoardRaterCenterDominance(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterCenterDominanceWeighting = 2
let highValueRater = BoardRaterCenterDominance(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -142,12 +142,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterThreatenedPiecesWeighting = 1
let lowValueRater = BoardRaterThreatenedPieces(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterThreatenedPiecesWeighting = 2
let highValueRater = BoardRaterThreatenedPieces(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -167,12 +167,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterThreatenedPiecesOwnPiecesMultiplier = 1
let lowValueRater = BoardRaterThreatenedPieces(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterThreatenedPiecesOwnPiecesMultiplier = 2
let highValueRater = BoardRaterThreatenedPieces(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
// Result should be more negative for a higher value, as white is under threat
XCTAssertLessThan(highValueRating, lowValueRating)
@@ -194,12 +194,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterPawnProgressionWeighting = 1
let lowValueRater = BoardRaterPawnProgression(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterPawnProgressionWeighting = 2
let highValueRater = BoardRaterPawnProgression(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -220,12 +220,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterKingSurroundingPossessionWeighting = 1
let lowValueRater = BoardRaterKingSurroundingPossession(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterKingSurroundingPossessionWeighting = 2
let highValueRater = BoardRaterKingSurroundingPossession(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
@@ -247,12 +247,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterCheckMateOpportunityWeighting = 1
let lowValueRater = BoardRaterCheckMateOpportunity(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterCheckMateOpportunityWeighting = 2
let highValueRater = BoardRaterCheckMateOpportunity(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
@@ -274,12 +274,12 @@ class AIConfigurationTests: XCTestCase {
var lowValueConfig = AIConfiguration()
lowValueConfig.boardRaterCenterFourOccupationWeighting = 1
let lowValueRater = BoardRaterCenterFourOccupation(configuration: lowValueConfig)
let lowValueRating = lowValueRater.ratingfor(board: board.board, color: .white)
let lowValueRating = lowValueRater.ratingFor(board: board.board, color: .white)
var highValueConfig = AIConfiguration()
highValueConfig.boardRaterCenterFourOccupationWeighting = 2
let highValueRater = BoardRaterCenterFourOccupation(configuration: highValueConfig)
let highValueRating = highValueRater.ratingfor(board: board.board, color: .white)
let highValueRating = highValueRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(highValueRating, lowValueRating)
}
+6 -6
View File
@@ -63,7 +63,7 @@ class AIPlayerTests: XCTestCase {
fatalError()
}
XCTAssertFalse(player.canAIMovePiece(fromLocation: knightLocation, toLocation: testLocation))
XCTAssertFalse(player.canAIMovePiece(from: knightLocation, to: testLocation))
}
func testKingCannotMoveInToCheck() {
@@ -88,7 +88,7 @@ class AIPlayerTests: XCTestCase {
fatalError()
}
XCTAssertFalse(player.canAIMovePiece(fromLocation: kingLocation, toLocation: testLocation))
XCTAssertFalse(player.canAIMovePiece(from: kingLocation, to: testLocation))
}
func testPawnCannotPutOwnKingInToCheck() {
@@ -111,7 +111,7 @@ class AIPlayerTests: XCTestCase {
fatalError()
}
XCTAssertFalse(player.canAIMovePiece(fromLocation: pawnLocation, toLocation: testLocation))
XCTAssertFalse(player.canAIMovePiece(from: pawnLocation, to: testLocation))
}
@@ -135,7 +135,7 @@ class AIPlayerTests: XCTestCase {
fatalError()
}
XCTAssertFalse(player.canAIMovePiece(fromLocation: queenLocation, toLocation: testLocation))
XCTAssertFalse(player.canAIMovePiece(from: queenLocation, to: testLocation))
}
func testRookCannotPutOwnKingInToCheck() {
@@ -158,7 +158,7 @@ class AIPlayerTests: XCTestCase {
fatalError()
}
XCTAssertFalse(player.canAIMovePiece(fromLocation: rookLocation, toLocation: testLocation))
XCTAssertFalse(player.canAIMovePiece(from: rookLocation, to: testLocation))
}
func testBishopCannotPutOwnKingInToCheck() {
@@ -181,6 +181,6 @@ class AIPlayerTests: XCTestCase {
fatalError()
}
XCTAssertFalse(player.canAIMovePiece(fromLocation: bishopLocation, toLocation: testLocation))
XCTAssertFalse(player.canAIMovePiece(from: bishopLocation, to: testLocation))
}
}
+2 -2
View File
@@ -136,10 +136,10 @@ class BoardLocationTests: XCTestCase {
let opening = FakeOpening()
let whiteMoves = opening.moves(forColor: .white)
let whiteMoves = opening.moves(for: .white)
XCTAssertEqual(whiteMoves.count, expectedWhiteLocations.count)
let blackMoves = opening.moves(forColor: .black)
let blackMoves = opening.moves(for: .black)
XCTAssertEqual(blackMoves.count, expectedBlackLocations.count)
for i in 0..<whiteMoves.count {
@@ -35,7 +35,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" +
"- - - - - - - -" )
let queenRating = boardRater.ratingfor(board: queenBoard.board, color: .white)
let queenRating = boardRater.ratingFor(board: queenBoard.board, color: .white)
let pawnBoard = ASCIIBoard(pieces: "- - - - - - - -" +
"- - - - - - - -" +
@@ -45,7 +45,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" +
"- - - - - - - -" )
let pawnRating = boardRater.ratingfor(board: pawnBoard.board, color: .white)
let pawnRating = boardRater.ratingFor(board: pawnBoard.board, color: .white)
XCTAssertGreaterThan(queenRating, pawnRating)
}
@@ -60,7 +60,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - -" +
"P - - - - - - -" +
"Q P - - - - - -" )
let blockedRating = boardRater.ratingfor(board: blockedBoard.board, color: .white)
let blockedRating = boardRater.ratingFor(board: blockedBoard.board, color: .white)
let nonBockedBoard = ASCIIBoard(pieces: "- - - - - - - -" +
"- - - - - - - -" +
@@ -70,7 +70,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" +
"Q - - - - - - -" )
let nonBockedRating = boardRater.ratingfor(board: nonBockedBoard.board, color: .white)
let nonBockedRating = boardRater.ratingFor(board: nonBockedBoard.board, color: .white)
XCTAssertGreaterThan(nonBockedRating, blockedRating)
@@ -86,7 +86,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - k" +
"- - - - - - - p" +
"Q - - - - - - -" )
let whiteRating = boardRater.ratingfor(board: whiteDominantBoard.board, color: .white)
let whiteRating = boardRater.ratingFor(board: whiteDominantBoard.board, color: .white)
let blackDominantBoard = ASCIIBoard(pieces: "r - - - - - - -" +
"- - - - - - - -" +
@@ -96,7 +96,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - K" +
"- - - - - - - P" +
"q - - - - - - -" )
let blackRating = boardRater.ratingfor(board: blackDominantBoard.board, color: .white)
let blackRating = boardRater.ratingFor(board: blackDominantBoard.board, color: .white)
XCTAssertGreaterThan(whiteRating, blackRating)
}
@@ -111,7 +111,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" +
"Q - - - - - - -" )
let queenInCornerRating = boardRater.ratingfor(board: queenInCornerBoard.board, color: .white)
let queenInCornerRating = boardRater.ratingFor(board: queenInCornerBoard.board, color: .white)
let queenInCenterBoard = ASCIIBoard(pieces: "- - - - - - - -" +
"- - - - - - - -" +
@@ -121,7 +121,7 @@ class BoardRaterBoardDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" +
"- - - - - - - -" )
let queenInCenterRating = boardRater.ratingfor(board: queenInCenterBoard.board, color: .white)
let queenInCenterRating = boardRater.ratingFor(board: queenInCenterBoard.board, color: .white)
XCTAssertGreaterThan(queenInCenterRating, queenInCornerRating)
}
@@ -34,7 +34,7 @@ class BoardRaterCenterDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" +
"- - - - - - - -" )
let centerVisibleRating = boardRater.ratingfor(board: centerVisibleBoard.board, color: .white)
let centerVisibleRating = boardRater.ratingFor(board: centerVisibleBoard.board, color: .white)
let centerObstructedBoard = ASCIIBoard(pieces: "- - - - - - - -" +
"- - - - - - - -" +
@@ -44,7 +44,7 @@ class BoardRaterCenterDominanceTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - P -" +
"- - - - - - - Q" )
let centerObstructedRating = boardRater.ratingfor(board: centerObstructedBoard.board, color: .white)
let centerObstructedRating = boardRater.ratingFor(board: centerObstructedBoard.board, color: .white)
XCTAssertGreaterThan(centerVisibleRating, centerObstructedRating)
}
@@ -39,7 +39,7 @@ class BoardRaterCenterFourOccupationTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = defaultBoardRater().ratingfor(board: board.board, color: .white)
let rating = defaultBoardRater().ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -54,7 +54,7 @@ class BoardRaterCenterFourOccupationTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = defaultBoardRater().ratingfor(board: board.board, color: .white)
let rating = defaultBoardRater().ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -69,7 +69,7 @@ class BoardRaterCenterFourOccupationTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = defaultBoardRater().ratingfor(board: board.board, color: .white)
let rating = defaultBoardRater().ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -84,7 +84,7 @@ class BoardRaterCenterFourOccupationTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = defaultBoardRater().ratingfor(board: board.board, color: .white)
let rating = defaultBoardRater().ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -99,7 +99,7 @@ class BoardRaterCenterFourOccupationTests: XCTestCase {
"P P P P P P P P" +
"P P P P P P P P" )
let rating = defaultBoardRater().ratingfor(board: board.board, color: .white)
let rating = defaultBoardRater().ratingFor(board: board.board, color: .white)
XCTAssertEqual(rating, 0, accuracy: 0.01)
}
@@ -114,7 +114,7 @@ class BoardRaterCenterFourOccupationTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = defaultBoardRater().ratingfor(board: board.board, color: .white)
let rating = defaultBoardRater().ratingFor(board: board.board, color: .white)
XCTAssertLessThan(rating, 0)
}
@@ -35,7 +35,7 @@ class BoardRaterCenterOwnershipTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let centerRating = boardRater.ratingfor(board: centerBoard.board, color: .white)
let centerRating = boardRater.ratingFor(board: centerBoard.board, color: .white)
let sideBoard = ASCIIBoard(pieces: "- - - - - - - -" +
"- - - - - - - -" +
@@ -46,7 +46,7 @@ class BoardRaterCenterOwnershipTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let sideRating = boardRater.ratingfor(board: sideBoard.board, color: .white)
let sideRating = boardRater.ratingFor(board: sideBoard.board, color: .white)
XCTAssertGreaterThan(centerRating, sideRating)
}
@@ -27,8 +27,8 @@ class BoardRaterCheckMateOpportunityTests: XCTestCase {
func testBoardWithNoCheckMateOpportuniesResultsInZeroRating() {
let board = Board(state: .newGame)
let whiteRating = boardRater.ratingfor(board: board, color: .white)
let blackRating = boardRater.ratingfor(board: board, color: .black)
let whiteRating = boardRater.ratingFor(board: board, color: .white)
let blackRating = boardRater.ratingFor(board: board, color: .black)
let accuracy = Double(0.1)
XCTAssertEqual(whiteRating, 0, accuracy: accuracy)
@@ -47,7 +47,7 @@ class BoardRaterCheckMateOpportunityTests: XCTestCase {
"- - - - - - - -" +
"R - - - G - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -63,7 +63,7 @@ class BoardRaterCheckMateOpportunityTests: XCTestCase {
"- r - - - - - -" +
"- - - - G - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertLessThan(rating, 0)
}
@@ -89,8 +89,8 @@ class BoardRaterCheckMateOpportunityTests: XCTestCase {
"- - - - - - - -" +
"R - - - G - - R" )
let singleRating = boardRater.ratingfor(board: singleCheckMateBoard.board, color: .white)
let multipleRating = boardRater.ratingfor(board: multipleCheckMateBoard.board, color: .white)
let singleRating = boardRater.ratingFor(board: singleCheckMateBoard.board, color: .white)
let multipleRating = boardRater.ratingFor(board: multipleCheckMateBoard.board, color: .white)
XCTAssertGreaterThan(multipleRating, singleRating)
}
@@ -36,7 +36,7 @@ class BoardRaterCountPiecesTests: XCTestCase {
"P P P P P P P P" +
"R K B Q G B K R" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssert(rating > 0, "Expected rating to be positive")
}
@@ -51,7 +51,7 @@ class BoardRaterCountPiecesTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssert(rating < 0, "Expected rating to be negative")
}
@@ -75,8 +75,8 @@ class BoardRaterCountPiecesTests: XCTestCase {
"P P P P P P P P" +
"P P P P P P P P" )
let fewerPiecesRating = boardRater.ratingfor(board: fewerPiecesBoard.board, color: .white)
let morePiecesRating = boardRater.ratingfor(board: morePiecesBoard.board, color: .white)
let fewerPiecesRating = boardRater.ratingFor(board: fewerPiecesBoard.board, color: .white)
let morePiecesRating = boardRater.ratingFor(board: morePiecesBoard.board, color: .white)
XCTAssert(morePiecesRating > fewerPiecesRating, "Expected more pieces to produce higher rating")
}
@@ -100,8 +100,8 @@ class BoardRaterCountPiecesTests: XCTestCase {
"- - - - - - - -" +
"R R R - - - - -" )
let lowerValuePiecesRating = boardRater.ratingfor(board: lowerValuePiecesBoard.board, color: .white)
let higherValuePiecesRating = boardRater.ratingfor(board: higherValuePiecesBoard.board, color: .white)
let lowerValuePiecesRating = boardRater.ratingFor(board: lowerValuePiecesBoard.board, color: .white)
let higherValuePiecesRating = boardRater.ratingFor(board: higherValuePiecesBoard.board, color: .white)
XCTAssert(higherValuePiecesRating > lowerValuePiecesRating,
"Expected higher value pieces to produce higher rating")
}
@@ -114,7 +114,7 @@ class BoardRaterCountPiecesTests: XCTestCase {
self.measure {
for _ in 0..<1000 {
_ = self.boardRater.ratingfor(board: board, color: .white)
_ = self.boardRater.ratingFor(board: board, color: .white)
}
}
}
@@ -209,8 +209,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - - - - - -" +
"- - - - G - - -" )
let lowRating = boardRater.ratingfor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingfor(board: highRatingBoard.board, color: .white)
let lowRating = boardRater.ratingFor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingFor(board: highRatingBoard.board, color: .white)
XCTAssertGreaterThan(highRating, lowRating)
}
@@ -235,8 +235,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"R - - - - - - -" +
"- - - - G - - -" )
let lowRating = boardRater.ratingfor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingfor(board: highRatingBoard.board, color: .white)
let lowRating = boardRater.ratingFor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingFor(board: highRatingBoard.board, color: .white)
XCTAssertGreaterThan(highRating, lowRating)
}
@@ -261,8 +261,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - - - - - -" +
"- - - - G - - -" )
let lowRating = boardRater.ratingfor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingfor(board: highRatingBoard.board, color: .white)
let lowRating = boardRater.ratingFor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingFor(board: highRatingBoard.board, color: .white)
XCTAssertGreaterThan(highRating, lowRating)
}
@@ -287,8 +287,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - - - - - -" +
"- - - - G - - -" )
let lowRating = boardRater.ratingfor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingfor(board: highRatingBoard.board, color: .white)
let lowRating = boardRater.ratingFor(board: lowRatingBoard.board, color: .white)
let highRating = boardRater.ratingFor(board: highRatingBoard.board, color: .white)
XCTAssertGreaterThan(highRating, lowRating)
}
@@ -313,8 +313,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"r - - - P - - Q" +
"- K - - g - k -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let invertedRating = boardRater.ratingfor(board: invertedBoard.board, color: .black)
let rating = boardRater.ratingFor(board: board.board, color: .white)
let invertedRating = boardRater.ratingFor(board: invertedBoard.board, color: .black)
XCTAssertEqual(rating, invertedRating, accuracy: 0.01)
}
@@ -330,7 +330,7 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - P P P - -" +
"- - - P G P - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -345,7 +345,7 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - - - - - -" +
"- - - - G - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .black)
let rating = boardRater.ratingFor(board: board.board, color: .black)
XCTAssertGreaterThan(rating, 0)
}
@@ -369,8 +369,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - - - - - -" +
"- - - - G - - -" )
let openKingRating = boardRater.ratingfor(board: openKingBoard.board, color: .white)
let surroundedKingRating = boardRater.ratingfor(board: surroundedKingBoard.board, color: .white)
let openKingRating = boardRater.ratingFor(board: openKingBoard.board, color: .white)
let surroundedKingRating = boardRater.ratingFor(board: surroundedKingBoard.board, color: .white)
XCTAssertLessThan(surroundedKingRating, openKingRating)
}
@@ -395,8 +395,8 @@ class BoardRaterKingSurroundingPossessionTests: XCTestCase {
"- - - P P P - -" +
"- - - P G P - -" )
let openKingRating = boardRater.ratingfor(board: openKingBoard.board, color: .black)
let surroundedKingRating = boardRater.ratingfor(board: surroundedKingBoard.board, color: .black)
let openKingRating = boardRater.ratingFor(board: openKingBoard.board, color: .black)
let surroundedKingRating = boardRater.ratingFor(board: surroundedKingBoard.board, color: .black)
XCTAssertLessThan(surroundedKingRating, openKingRating)
}
@@ -46,8 +46,8 @@ class BoardRaterPawnProgressionTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let progressedRating = boardRater.ratingfor(board: progressedBoard.board, color: .white)
let lessProgressedRating = boardRater.ratingfor(board: lessProgressedBoard.board, color: .white)
let progressedRating = boardRater.ratingFor(board: progressedBoard.board, color: .white)
let lessProgressedRating = boardRater.ratingFor(board: lessProgressedBoard.board, color: .white)
XCTAssert(progressedRating > lessProgressedRating)
}
@@ -72,8 +72,8 @@ class BoardRaterPawnProgressionTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let progressedRating = boardRater.ratingfor(board: progressedBoard.board, color: .black)
let lessProgressedRating = boardRater.ratingfor(board: lessProgressedBoard.board, color: .black)
let progressedRating = boardRater.ratingFor(board: progressedBoard.board, color: .black)
let lessProgressedRating = boardRater.ratingFor(board: lessProgressedBoard.board, color: .black)
XCTAssert(progressedRating > lessProgressedRating)
}
@@ -89,7 +89,7 @@ class BoardRaterPawnProgressionTests: XCTestCase {
"- P - P - - P -" +
"- - - - - - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertEqual(rating, 0, accuracy: 0.0001)
}
@@ -105,7 +105,7 @@ class BoardRaterPawnProgressionTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .black)
let rating = boardRater.ratingFor(board: board.board, color: .black)
XCTAssertEqual(rating, 0, accuracy: 0.0001)
}
@@ -121,8 +121,8 @@ class BoardRaterPawnProgressionTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let whiteRating = boardRater.ratingfor(board: board.board, color: .white)
let blackRating = boardRater.ratingfor(board: board.board, color: .black)
let whiteRating = boardRater.ratingFor(board: board.board, color: .white)
let blackRating = boardRater.ratingFor(board: board.board, color: .black)
XCTAssertEqual(whiteRating, blackRating, accuracy: 0.0001)
}
@@ -138,8 +138,8 @@ class BoardRaterPawnProgressionTests: XCTestCase {
"P - - - - - - p" +
"P - - - - - - p" )
let whiteRating = boardRater.ratingfor(board: board.board, color: .white)
let blackRating = boardRater.ratingfor(board: board.board, color: .black)
let whiteRating = boardRater.ratingFor(board: board.board, color: .white)
let blackRating = boardRater.ratingFor(board: board.board, color: .black)
XCTAssertEqual(whiteRating, blackRating, accuracy: 0.0001)
}
@@ -38,7 +38,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertEqual(rating, 0, accuracy: 0.01)
}
@@ -54,7 +54,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertLessThan(rating, 0)
}
@@ -70,7 +70,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
"- - - - - - - -" +
"- - - - - - - -" )
let rating = boardRater.ratingfor(board: board.board, color: .white)
let rating = boardRater.ratingFor(board: board.board, color: .white)
XCTAssertGreaterThan(rating, 0)
}
@@ -97,7 +97,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let queenLocation = BoardLocation(index: board.indexOfCharacter("Q"))
let gameBoard = board.board
let protectingLocations = boardRater.getPieces(protecting: gameBoard.getPiece(at: queenLocation)!,
onBoard: board.board).map { $0.location }
on: board.board).map { $0.location }
// Check all of the expected locations appeared in the protecting locations array
for expectedIndex in expectedIndexes {
@@ -141,7 +141,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let protectingPieces = boardRater.getPieces(protecting: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
// None of the pieces are protecting the queen, so expect count to be zero
XCTAssertTrue(protectingPieces.count == 0)
@@ -162,7 +162,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let protectingPieces = boardRater.getPieces(protecting: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
// The black pieces cannot protect the white queen, so expect count to be zero
XCTAssertTrue(protectingPieces.count == 0)
@@ -183,7 +183,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let protectingPieces = boardRater.getPieces(protecting: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
XCTAssertTrue(protectingPieces.count == 0)
@@ -204,7 +204,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let protectingPieces = boardRater.getPieces(protecting: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
XCTAssertTrue(protectingPieces.count == 1)
}
@@ -232,7 +232,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let threateningLocations = boardRater.getPieces(threatening: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard).map { $0.location }
on: gameBoard).map { $0.location }
// Check all of the expected locations appeared in the protecting locations array
for expectedIndex in expectedIndexes {
@@ -276,7 +276,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let threateningPieces = boardRater.getPieces(threatening: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
// None of the pieces are threatening the queen, so expect count to be zero
XCTAssertTrue(threateningPieces.count == 0)
@@ -297,7 +297,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let threateningPieces = boardRater.getPieces(threatening: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
// The white pieces cannot threaten the white queen, so expect count to be zero
XCTAssertTrue(threateningPieces.count == 0)
@@ -318,7 +318,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let threateningPieces = boardRater.getPieces(threatening: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
XCTAssertTrue(threateningPieces.count == 0)
}
@@ -338,7 +338,7 @@ class BoardRaterThreatenedPiecesTests: XCTestCase {
let gameBoard = board.board
let threateningPieces = boardRater.getPieces(threatening: gameBoard.getPiece(at: queenLocation)!,
onBoard: gameBoard)
on: gameBoard)
XCTAssertTrue(threateningPieces.count == 1)
}
+17 -17
View File
@@ -149,7 +149,7 @@ class BoardTests: XCTestCase {
let location = BoardLocation(index: 10)
board.setPiece(Piece(type: .pawn, color: .white),
at: location)
board.removePiece(atLocation: location)
board.removePiece(at: location)
XCTAssertNil(board.getPiece(at: location))
}
@@ -164,7 +164,7 @@ class BoardTests: XCTestCase {
let endLocation = BoardLocation(index: 20)
board.setPiece(piece, at: startLocation)
board.movePiece(fromLocation: startLocation, toLocation: endLocation)
board.movePiece(from: startLocation, to: endLocation)
guard let returnedPiece = board.getPiece(at: endLocation) else {
XCTFail("Expected piece to exist at location")
@@ -204,7 +204,7 @@ class BoardTests: XCTestCase {
var gameBoard = board.board
gameBoard.movePiece(fromLocation: fromLocation, toLocation: toLocation)
gameBoard.movePiece(from: fromLocation, to: toLocation)
guard let piece = gameBoard.getPiece(at: toLocation) else {
XCTFail("Couldn't find piece at new position")
@@ -297,10 +297,10 @@ class BoardTests: XCTestCase {
board.setPiece(Piece(type: .pawn, color: .black), at: $0)
}
let returnedWhitelocations = board.getLocationsOfColor(.white)
let returnedWhitelocations = board.getLocations(of: .white)
XCTAssertEqual(whiteLocations.count, returnedWhitelocations.count)
let returnedBlacklocations = board.getLocationsOfColor(.black)
let returnedBlacklocations = board.getLocations(of: .black)
XCTAssertEqual(blackLocations.count, returnedBlacklocations.count)
whiteLocations.forEach { (location) in
@@ -673,8 +673,8 @@ class BoardTests: XCTestCase {
var gameBoard = board.board
// move then back
gameBoard.movePiece(fromLocation: startLocation, toLocation: newLocation)
gameBoard.movePiece(fromLocation: newLocation, toLocation: startLocation)
gameBoard.movePiece(from: startLocation, to: newLocation)
gameBoard.movePiece(from: newLocation, to: startLocation)
XCTAssertFalse(gameBoard.canColorCastle(color: .white, side: .kingSide))
}
@@ -695,8 +695,8 @@ class BoardTests: XCTestCase {
var gameBoard = board.board
// move then back
gameBoard.movePiece(fromLocation: startLocation, toLocation: newLocation)
gameBoard.movePiece(fromLocation: newLocation, toLocation: startLocation)
gameBoard.movePiece(from: startLocation, to: newLocation)
gameBoard.movePiece(from: newLocation, to: startLocation)
XCTAssertFalse(gameBoard.canColorCastle(color: .white, side: .kingSide))
}
@@ -1053,8 +1053,8 @@ class BoardTests: XCTestCase {
let sourceLocation = BoardLocation(x: 0, y: 1)
let targetLocation = BoardLocation(x: 0, y: 3)
board1.movePiece(fromLocation: sourceLocation, toLocation: targetLocation)
board2.movePiece(fromLocation: sourceLocation, toLocation: targetLocation)
board1.movePiece(from: sourceLocation, to: targetLocation)
board2.movePiece(from: sourceLocation, to: targetLocation)
XCTAssertEqual(board1, board2)
}
@@ -1062,8 +1062,8 @@ class BoardTests: XCTestCase {
func testNonEqualBoardsAreNotEqual() {
var board1 = Board(state: .newGame)
board1.movePiece(fromLocation: BoardLocation(x: 0, y: 1),
toLocation: BoardLocation(x: 0, y: 3))
board1.movePiece(from: BoardLocation(x: 0, y: 1),
to: BoardLocation(x: 0, y: 3))
let board2 = Board(state: .newGame)
@@ -1089,11 +1089,11 @@ class BoardTests: XCTestCase {
func testPieceLocationsAreCorrectAfterMoves() {
var board = Board(state: .newGame)
board.movePiece(fromLocation: BoardLocation(gridPosition: .e2),
toLocation: BoardLocation(gridPosition: .e4))
board.movePiece(from: BoardLocation(gridPosition: .e2),
to: BoardLocation(gridPosition: .e4))
board.movePiece(fromLocation: BoardLocation(gridPosition: .d7),
toLocation: BoardLocation(gridPosition: .d5))
board.movePiece(from: BoardLocation(gridPosition: .d7),
to: BoardLocation(gridPosition: .d5))
for location in BoardLocation.all {
+4 -4
View File
@@ -64,8 +64,8 @@ class GameTests: XCTestCase {
// White player moves pawn
do {
try whitePlayer.movePiece(fromLocation: BoardLocation(x: 0, y: 1),
toLocation: BoardLocation(x: 0, y: 2))
try whitePlayer.movePiece(from: BoardLocation(x: 0, y: 1),
to: BoardLocation(x: 0, y: 2))
} catch {
XCTFail("Expected to be able to move piece")
return
@@ -73,8 +73,8 @@ class GameTests: XCTestCase {
// Black player moves pawn
do {
try blackPlayer.movePiece(fromLocation: BoardLocation(x: 7, y: 6),
toLocation: BoardLocation(x: 7, y: 5))
try blackPlayer.movePiece(from: BoardLocation(x: 7, y: 6),
to: BoardLocation(x: 7, y: 5))
} catch {
XCTFail("Expected to be able to move piece")
return
+2 -2
View File
@@ -39,8 +39,8 @@ class OpeningsTests: XCTestCase {
}
// Assert the piece can move
if piece.movement.canPieceMove(fromLocation: source, toLocation: target, board: board) {
board.movePiece(fromLocation: source, toLocation: target)
if piece.movement.canPieceMove(from: source, to: target, board: board) {
board.movePiece(from: source, to: target)
} else {
XCTFail("Cannot move piece from \(source) to \(target)")
}
+12 -12
View File
@@ -31,8 +31,8 @@ class PerformanceTests: XCTestCase {
self.measure {
BoardLocation.all.forEach {
_ = pawn.movement.canPieceMove(fromLocation: pawnLocation,
toLocation: $0,
_ = pawn.movement.canPieceMove(from: pawnLocation,
to: $0,
board: board)
}
}
@@ -62,8 +62,8 @@ class PerformanceTests: XCTestCase {
self.measure {
BoardLocation.all.forEach {
_ = queen.movement.canPieceMove(fromLocation: queenLocation,
toLocation: $0,
_ = queen.movement.canPieceMove(from: queenLocation,
to: $0,
board: board)
}
}
@@ -93,8 +93,8 @@ class PerformanceTests: XCTestCase {
self.measure {
BoardLocation.all.forEach {
_ = king.movement.canPieceMove(fromLocation: kingLocation,
toLocation: $0,
_ = king.movement.canPieceMove(from: kingLocation,
to: $0,
board: board)
}
}
@@ -124,8 +124,8 @@ class PerformanceTests: XCTestCase {
self.measure {
BoardLocation.all.forEach {
_ = knight.movement.canPieceMove(fromLocation: knightLocation,
toLocation: $0,
_ = knight.movement.canPieceMove(from: knightLocation,
to: $0,
board: board)
}
}
@@ -155,8 +155,8 @@ class PerformanceTests: XCTestCase {
self.measure {
BoardLocation.all.forEach {
_ = bishop.movement.canPieceMove(fromLocation: bishopLocation,
toLocation: $0,
_ = bishop.movement.canPieceMove(from: bishopLocation,
to: $0,
board: board)
}
}
@@ -186,8 +186,8 @@ class PerformanceTests: XCTestCase {
self.measure {
BoardLocation.all.forEach {
_ = rook.movement.canPieceMove(fromLocation: rookLocation,
toLocation: $0,
_ = rook.movement.canPieceMove(from: rookLocation,
to: $0,
board: board)
}
}
+75 -75
View File
@@ -39,10 +39,10 @@ class PieceMovementTests: XCTestCase {
for allowedIndex in allowedIndexes {
XCTAssertTrue(
movement.canPieceMove(fromLocation: BoardLocation(index: movingIndex),
toLocation: BoardLocation(index: allowedIndex),
movement.canPieceMove(from: BoardLocation(index: movingIndex),
to: BoardLocation(index: allowedIndex),
board: board.board),
"Allowed Index was invalid: \(allowedIndex)")
"Allowed index was invalid: \(allowedIndex)")
}
}
@@ -52,8 +52,8 @@ class PieceMovementTests: XCTestCase {
for invalidIndex in invalidIndexes {
XCTAssertFalse(
movement.canPieceMove(fromLocation: BoardLocation(index: movingIndex),
toLocation: BoardLocation(index: invalidIndex),
movement.canPieceMove(from: BoardLocation(index: movingIndex),
to: BoardLocation(index: invalidIndex),
board: board.board),
"Invalid index was valid: \(invalidIndex)")
}
@@ -66,8 +66,8 @@ class PieceMovementTests: XCTestCase {
let movingIndex = board.indexOfCharacter(from)
let targetIndex = board.indexOfCharacter(to)
return movement.canPieceMove(fromLocation: BoardLocation(index: movingIndex),
toLocation: BoardLocation(index: targetIndex),
return movement.canPieceMove(from: BoardLocation(index: movingIndex),
to: BoardLocation(index: targetIndex),
board: board.board)
}
@@ -237,8 +237,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementStraightLine()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -257,8 +257,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementStraightLine()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -414,8 +414,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementDiagonal()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -434,8 +434,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementDiagonal()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -645,7 +645,7 @@ class PieceMovementTests: XCTestCase {
let movement = PieceMovementKnight()
XCTAssert(movement.canPieceMove(fromLocation: location, toLocation: location, board: board) == false,
XCTAssert(movement.canPieceMove(from: location, to: location, board: board) == false,
"Expected piece could not move to its current position")
}
@@ -665,8 +665,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementKnight()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -685,8 +685,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementKnight()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -776,7 +776,7 @@ class PieceMovementTests: XCTestCase {
let movement = PieceMovementKing()
XCTAssert(movement.canPieceMove(fromLocation: location, toLocation: location, board: board) == false,
XCTAssert(movement.canPieceMove(from: location, to: location, board: board) == false,
"Expected piece could not move to its current position")
}
@@ -796,8 +796,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementKing()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -816,8 +816,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementKing()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -979,7 +979,7 @@ class PieceMovementTests: XCTestCase {
let movement = PieceMovementPawn()
XCTAssert(movement.canPieceMove(fromLocation: location, toLocation: location, board: board) == false,
XCTAssert(movement.canPieceMove(from: location, to: location, board: board) == false,
"Expected piece could not move to its current position")
}
@@ -1149,8 +1149,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementPawn()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -1179,7 +1179,7 @@ class PieceMovementTests: XCTestCase {
}
do {
try whitePlayer.movePiece(fromLocation: startLocation, toLocation: targetLocation)
try whitePlayer.movePiece(from: startLocation, to: targetLocation)
} catch {
fatalError()
}
@@ -1207,7 +1207,7 @@ class PieceMovementTests: XCTestCase {
}
do {
try whitePlayer.movePiece(fromLocation: startLocation, toLocation: targetLocation)
try whitePlayer.movePiece(from: startLocation, to: targetLocation)
} catch {
fatalError()
}
@@ -1236,7 +1236,7 @@ class PieceMovementTests: XCTestCase {
}
do {
try whitePlayer.movePiece(fromLocation: startLocation, toLocation: targetLocation)
try whitePlayer.movePiece(from: startLocation, to: targetLocation)
} catch {
fatalError()
}
@@ -1251,7 +1251,7 @@ class PieceMovementTests: XCTestCase {
}
do {
try blackPlayer.movePiece(fromLocation: BoardLocation(x: 0, y: 6), toLocation: BoardLocation(x: 0, y: 5))
try blackPlayer.movePiece(from: BoardLocation(x: 0, y: 6), to: BoardLocation(x: 0, y: 5))
} catch {
fatalError()
}
@@ -1283,22 +1283,22 @@ class PieceMovementTests: XCTestCase {
// Black move two spaces
do {
try blackPlayer.movePiece(fromLocation: board.locationOfCharacter("p"),
toLocation: board.locationOfCharacter("*"))
try blackPlayer.movePiece(from: board.locationOfCharacter("p"),
to: board.locationOfCharacter("*"))
} catch {
fatalError()
}
// White should be able to take the black pawn using the en passant rule
let pieceMovement = PieceMovementPawn()
XCTAssertTrue(pieceMovement.canPieceMove(fromLocation: board.locationOfCharacter("P"),
toLocation: board.locationOfCharacter("+"),
XCTAssertTrue(pieceMovement.canPieceMove(from: board.locationOfCharacter("P"),
to: board.locationOfCharacter("+"),
board: game.board),
"Expected white to be able to make en passant move")
do {
try whitePlayer.movePiece(fromLocation: board.locationOfCharacter("P"),
toLocation: board.locationOfCharacter("+"))
try whitePlayer.movePiece(from: board.locationOfCharacter("P"),
to: board.locationOfCharacter("+"))
} catch {
XCTFail("Expected white to be able to execute en passant move")
}
@@ -1325,22 +1325,22 @@ class PieceMovementTests: XCTestCase {
// White move two spaces
do {
try whitePlayer.movePiece(fromLocation: board.locationOfCharacter("P"),
toLocation: board.locationOfCharacter("*"))
try whitePlayer.movePiece(from: board.locationOfCharacter("P"),
to: board.locationOfCharacter("*"))
} catch {
fatalError()
}
// Black should be able to take the white pawn using the en passant rule
let pieceMovement = PieceMovementPawn()
XCTAssertTrue(pieceMovement.canPieceMove(fromLocation: board.locationOfCharacter("p"),
toLocation: board.locationOfCharacter("+"),
XCTAssertTrue(pieceMovement.canPieceMove(from: board.locationOfCharacter("p"),
to: board.locationOfCharacter("+"),
board: game.board),
"Expected black to be able to make en passant move")
do {
try blackPlayer.movePiece(fromLocation: board.locationOfCharacter("p"),
toLocation: board.locationOfCharacter("+"))
try blackPlayer.movePiece(from: board.locationOfCharacter("p"),
to: board.locationOfCharacter("+"))
} catch {
XCTFail("Expected black to be able to execute en passant move")
}
@@ -1367,32 +1367,32 @@ class PieceMovementTests: XCTestCase {
// Black move two spaces
do {
try blackPlayer.movePiece(fromLocation: board.locationOfCharacter("p"),
toLocation: board.locationOfCharacter("*"))
try blackPlayer.movePiece(from: board.locationOfCharacter("p"),
to: board.locationOfCharacter("*"))
} catch {
fatalError()
}
// White moves king
do {
try whitePlayer.movePiece(fromLocation: board.locationOfCharacter("G"),
toLocation: board.locationOfCharacter("&"))
try whitePlayer.movePiece(from: board.locationOfCharacter("G"),
to: board.locationOfCharacter("&"))
} catch {
fatalError()
}
// Black moves king
do {
try blackPlayer.movePiece(fromLocation: board.locationOfCharacter("g"),
toLocation: board.locationOfCharacter("%"))
try blackPlayer.movePiece(from: board.locationOfCharacter("g"),
to: board.locationOfCharacter("%"))
} catch {
fatalError()
}
// White should not be able to take the black pawn using the en passant rule
let pieceMovement = PieceMovementPawn()
XCTAssertFalse(pieceMovement.canPieceMove(fromLocation: board.locationOfCharacter("P"),
toLocation: board.locationOfCharacter("+"),
XCTAssertFalse(pieceMovement.canPieceMove(from: board.locationOfCharacter("P"),
to: board.locationOfCharacter("+"),
board: game.board))
}
@@ -1414,32 +1414,32 @@ class PieceMovementTests: XCTestCase {
// White moves pawn two spaces
do {
try whitePlayer.movePiece(fromLocation: board.locationOfCharacter("P"),
toLocation: board.locationOfCharacter("*"))
try whitePlayer.movePiece(from: board.locationOfCharacter("P"),
to: board.locationOfCharacter("*"))
} catch {
fatalError()
}
// Black moves king
do {
try blackPlayer.movePiece(fromLocation: board.locationOfCharacter("g"),
toLocation: board.locationOfCharacter("%"))
try blackPlayer.movePiece(from: board.locationOfCharacter("g"),
to: board.locationOfCharacter("%"))
} catch {
fatalError()
}
// White moves king
do {
try whitePlayer.movePiece(fromLocation: board.locationOfCharacter("G"),
toLocation: board.locationOfCharacter("&"))
try whitePlayer.movePiece(from: board.locationOfCharacter("G"),
to: board.locationOfCharacter("&"))
} catch {
fatalError()
}
// Black should not be able to take the white pawn using the en passant rule
let pieceMovement = PieceMovementPawn()
XCTAssertFalse(pieceMovement.canPieceMove(fromLocation: board.locationOfCharacter("p"),
toLocation: board.locationOfCharacter("+"),
XCTAssertFalse(pieceMovement.canPieceMove(from: board.locationOfCharacter("p"),
to: board.locationOfCharacter("+"),
board: game.board))
}
@@ -1529,7 +1529,7 @@ class PieceMovementTests: XCTestCase {
let movement = PieceMovementQueen()
XCTAssert(movement.canPieceMove(fromLocation: location, toLocation: location, board: board) == false,
XCTAssert(movement.canPieceMove(from: location, to: location, board: board) == false,
"Expected piece could not move to its current position")
}
@@ -1549,8 +1549,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementQueen()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -1569,8 +1569,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementQueen()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -1660,7 +1660,7 @@ class PieceMovementTests: XCTestCase {
let movement = PieceMovementRook()
XCTAssert(movement.canPieceMove(fromLocation: location, toLocation: location, board: board) == false,
XCTAssert(movement.canPieceMove(from: location, to: location, board: board) == false,
"Expected piece could not move to its current position")
}
@@ -1680,8 +1680,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementRook()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -1700,8 +1700,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementRook()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
@@ -1791,7 +1791,7 @@ class PieceMovementTests: XCTestCase {
let movement = PieceMovementBishop()
XCTAssert(movement.canPieceMove(fromLocation: location, toLocation: location, board: board) == false,
XCTAssert(movement.canPieceMove(from: location, to: location, board: board) == false,
"Expected piece could not move to its current position")
}
@@ -1811,8 +1811,8 @@ class PieceMovementTests: XCTestCase {
let blackIndex = board.indexOfCharacter("B")
let movement = PieceMovementBishop()
XCTAssertTrue(movement.canPieceMove(fromLocation: BoardLocation(index: whiteIndex),
toLocation: BoardLocation(index: blackIndex),
XCTAssertTrue(movement.canPieceMove(from: BoardLocation(index: whiteIndex),
to: BoardLocation(index: blackIndex),
board: board.board))
}
@@ -1831,8 +1831,8 @@ class PieceMovementTests: XCTestCase {
let kingIndex = board.indexOfCharacter("g")
let movement = PieceMovementBishop()
XCTAssertFalse(movement.canPieceMove(fromLocation: BoardLocation(index: pieceIndex),
toLocation: BoardLocation(index: kingIndex),
XCTAssertFalse(movement.canPieceMove(from: BoardLocation(index: pieceIndex),
to: BoardLocation(index: kingIndex),
board: board.board))
}
+46 -16
View File
@@ -33,21 +33,21 @@ class PlayerTests: XCTestCase {
func testOccupliesSquareAtLocationReturnsTrueWhenOccupiedByPlayerPiece() {
let location = BoardLocation(index: 0) // <-- should be occupied by white
XCTAssert(game.whitePlayer.occupiesSquareAt(location: location),
XCTAssert(game.whitePlayer.occupiesSquare(at: location),
"Expected square to be occupied by player color")
}
func testOccupliesSquareAtLocationReturnsFalseWhenSquareEmpty() {
let location = BoardLocation(x: 0, y: 2) // <-- should be empty
XCTAssert(game.whitePlayer.occupiesSquareAt(location: location) == false,
XCTAssert(game.whitePlayer.occupiesSquare(at: location) == false,
"Expected square to not be occupied by player color")
}
func testOccupliesSquareAtLocationReturnsFalseWhenOccupiedByOppositeColor() {
let location = BoardLocation(x: 0, y: 7) // <-- should be occupied by black
XCTAssert(game.whitePlayer.occupiesSquareAt(location: location) == false,
XCTAssert(game.whitePlayer.occupiesSquare(at: location) == false,
"Expected square to not be occupied by player color")
}
@@ -55,7 +55,13 @@ class PlayerTests: XCTestCase {
func testPlayerCannotMovePieceToSameLocation() {
let location = BoardLocation(index: 0)
XCTAssert(game.whitePlayer.canMovePiece(fromLocation: location, toLocation: location) == false)
do {
let canMove = try game.whitePlayer.canMovePiece(from: location, to: location)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .movingToSameLocation)
}
}
// MARK: - Move Errors
@@ -91,8 +97,12 @@ class PlayerTests: XCTestCase {
}
// Assert that the correct error is thrown
XCTAssertTrue(player.canMovePieceWithError(fromLocation: queenLocation,
toLocation: targetLocation).error == .cannotMoveInToCheck)
do {
let canMove = try player.canMovePiece(from: queenLocation, to: targetLocation)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .cannotMoveInToCheck)
}
}
func testMoveInToCheckErrorIsThrownByMovingPawn() {
@@ -116,8 +126,12 @@ class PlayerTests: XCTestCase {
}
// Assert that the correct error is thrown
XCTAssertTrue(player.canMovePieceWithError(fromLocation: pieceLocation,
toLocation: targetLocation).error == .cannotMoveInToCheck)
do {
let canMove = try player.canMovePiece(from: pieceLocation, to: targetLocation)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .cannotMoveInToCheck)
}
}
func testMoveInToCheckErrorIsThrownByMovingKnight() {
@@ -141,8 +155,12 @@ class PlayerTests: XCTestCase {
}
// Assert that the correct error is thrown
XCTAssertTrue(player.canMovePieceWithError(fromLocation: pieceLocation,
toLocation: targetLocation).error == .cannotMoveInToCheck)
do {
let canMove = try player.canMovePiece(from: pieceLocation, to: targetLocation)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .cannotMoveInToCheck)
}
}
func testMoveInToCheckErrorIsThrownByMovingBishop() {
@@ -166,8 +184,12 @@ class PlayerTests: XCTestCase {
}
// Assert that the correct error is thrown
XCTAssertTrue(player.canMovePieceWithError(fromLocation: pieceLocation,
toLocation: targetLocation).error == .cannotMoveInToCheck)
do {
let canMove = try player.canMovePiece(from: pieceLocation, to: targetLocation)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .cannotMoveInToCheck)
}
}
func testMoveInToCheckErrorIsThrownByMovingRook() {
@@ -191,8 +213,12 @@ class PlayerTests: XCTestCase {
}
// Assert that the correct error is thrown
XCTAssertTrue(player.canMovePieceWithError(fromLocation: pieceLocation,
toLocation: targetLocation).error == .cannotMoveInToCheck)
do {
let canMove = try player.canMovePiece(from: pieceLocation, to: targetLocation)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .cannotMoveInToCheck)
}
}
func testMoveInToCheckErrorIsThrownByMovingKing() {
@@ -216,8 +242,12 @@ class PlayerTests: XCTestCase {
}
// Assert that the correct error is thrown
XCTAssertTrue(player.canMovePieceWithError(fromLocation: pieceLocation,
toLocation: targetLocation).error == .cannotMoveInToCheck)
do {
let canMove = try player.canMovePiece(from: pieceLocation, to: targetLocation)
XCTAssertNil(canMove)
} catch let error {
XCTAssert(error as! Player.MoveError == .cannotMoveInToCheck)
}
}
}
+3 -3
View File
@@ -46,12 +46,12 @@ let game = Game(firstPlayer: whitePlayer, secondPlayer: blackPlayer)
```
if let player = game.currentPlayer as? Human {
let currentLocation = BoardLocation(x: 4, y: 1)
let newLocation = BoardLocation(x: 4, y: 2)
try! player.movePiece(fromLocation: currentLocation,
toLocation: newLocation)
try! player.movePiece(from: currentLocation,
to: newLocation)
}
```
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'SwiftChess'
s.version = '0.2.0'
s.version = '0.3.0'
s.summary = 'Chess engine written in Swift'
# This description is used to generate tags and improve search results.
+24 -25
View File
@@ -12,7 +12,7 @@ import Foundation
open class AIPlayer: Player {
let boardRaters: [BoardRater]!
public var configuration: AIConfiguration!
public let configuration: AIConfiguration!
var openingMoves = [OpeningMove]()
public init(color: Color, configuration: AIConfiguration) {
@@ -31,7 +31,7 @@ open class AIPlayer: Player {
BoardRaterCenterFourOccupation(configuration: configuration)
]
openingMoves = Opening.allOpeningMoves(forColor: color)
openingMoves = Opening.allOpeningMoves(for: color)
super.init()
self.color = color
@@ -58,13 +58,13 @@ open class AIPlayer: Player {
var move: Move!
// Get an opening move
if let openingMove = openingMoveForBoard(board) {
if let openingMove = openingMove(for: board) {
//print("Playing opening move")
move = openingMove
}
// Or, get the Highest rated move
else {
move = highestRatedMoveOnBoard(board)
move = highestRatedMove(on: board)
}
// Make move
@@ -72,7 +72,7 @@ open class AIPlayer: Player {
switch move.type {
case .singlePiece(let sourceLocation, let targetLocation):
operations = game.board.movePiece(fromLocation: sourceLocation, toLocation: targetLocation)
operations = game.board.movePiece(from: sourceLocation, to: targetLocation)
case .castle(let color, let side):
operations = game.board.performCastle(color: color, side: side)
}
@@ -81,7 +81,7 @@ open class AIPlayer: Player {
let pawnsToPromoteLocations = game.board.getLocationsOfPromotablePawns(color: color)
assert(pawnsToPromoteLocations.count < 2, "There should only ever be one pawn to promote at any time")
if pawnsToPromoteLocations.count > 0 {
game.board = promotePawnsOnBoard(game.board)
game.board = promotePawns(on: game.board)
let location = pawnsToPromoteLocations.first!
let transformOperation = BoardOperation(type: .transformPiece,
@@ -96,7 +96,7 @@ open class AIPlayer: Player {
}
}
func openingMoveForBoard(_ board: Board) -> Move? {
func openingMove(for board: Board) -> Move? {
let possibleMoves = openingMoves.filter {
$0.board == board
@@ -109,12 +109,12 @@ open class AIPlayer: Player {
let index = Int(arc4random_uniform(UInt32(possibleMoves.count)))
let openingMove = possibleMoves[index]
return Move(type: .singlePiece(sourceLocation: openingMove.fromLocation,
targetLocation: openingMove.toLocation),
return Move(type: .singlePiece(from: openingMove.fromLocation,
to: openingMove.toLocation),
rating: 0)
}
func highestRatedMoveOnBoard(_ board: Board) -> Move {
func highestRatedMove(on board: Board) -> Move {
var possibleMoves = [Move]()
@@ -130,30 +130,30 @@ open class AIPlayer: Player {
for targetLocation in BoardLocation.all {
guard canAIMovePiece(fromLocation: sourceLocation, toLocation: targetLocation) else {
guard canAIMovePiece(from: sourceLocation, to: targetLocation) else {
continue
}
// Make move
var resultBoard = board
resultBoard.movePiece(fromLocation: sourceLocation, toLocation: targetLocation)
resultBoard.movePiece(from: sourceLocation, to: targetLocation)
// Promote pawns
let pawnsToPromoteLocations = resultBoard.getLocationsOfPromotablePawns(color: color)
assert(pawnsToPromoteLocations.count < 2, "There should only ever be one pawn to promote at any time")
if pawnsToPromoteLocations.count > 0 {
resultBoard = promotePawnsOnBoard(resultBoard)
resultBoard = promotePawns(on: resultBoard)
}
// Rate
var rating = ratingForBoard(resultBoard)
// reduce rating if suicide
if resultBoard.canColorMoveAnyPieceToLocation(color: color.opposite(), location: targetLocation) {
if resultBoard.canColorMoveAnyPieceToLocation(color: color.opposite, location: targetLocation) {
rating -= (abs(rating) * configuration.suicideMultipler.value)
}
let move = Move(type: .singlePiece(sourceLocation: sourceLocation, targetLocation: targetLocation),
let move = Move(type: .singlePiece(from: sourceLocation, to: targetLocation),
rating: rating)
possibleMoves.append(move)
// print("Rating: \(rating)")
@@ -202,16 +202,15 @@ open class AIPlayer: Player {
return highestRatedMove
}
func canAIMovePiece(fromLocation: BoardLocation, toLocation: BoardLocation) -> Bool {
func canAIMovePiece(from fromLocation: BoardLocation, to toLocation: BoardLocation) -> Bool {
// This is a stricter version of the canMove function, used by the AI, that returns false for errors
let canMove = canMovePieceWithError(fromLocation: fromLocation, toLocation: toLocation)
if canMove.error != nil {
do {
return try canMovePiece(from: fromLocation, to: toLocation)
} catch {
return false
}
return canMove.result
}
func ratingForBoard(_ board: Board) -> Double {
@@ -220,7 +219,7 @@ open class AIPlayer: Player {
for boardRater in boardRaters {
let result = boardRater.ratingfor(board: board, color: color)
let result = boardRater.ratingFor(board: board, color: color)
//let className = "\(boardRater)"
//print("\t\(className): \(result)")
@@ -228,14 +227,14 @@ open class AIPlayer: Player {
}
// If opponent is in check mate, set the maximum rating
if board.isColorInCheckMate(color: color.opposite()) {
if board.isColorInCheckMate(color: color.opposite) {
rating = Double.greatestFiniteMagnitude
}
return rating
}
func promotePawnsOnBoard(_ board: Board) -> Board {
func promotePawns(on board: Board) -> Board {
let pawnsToPromoteLocations = board.getLocationsOfPromotablePawns(color: color)
@@ -282,7 +281,7 @@ open class AIPlayer: Player {
struct Move {
enum MoveType {
case singlePiece(sourceLocation: BoardLocation, targetLocation: BoardLocation)
case singlePiece(from: BoardLocation, to: BoardLocation)
case castle(color: Color, side: CastleSide)
}
@@ -300,7 +299,7 @@ internal class BoardRater {
self.configuration = configuration
}
func ratingfor(board: Board, color: Color) -> Double {
func ratingFor(board: Board, color: Color) -> Double {
fatalError("Override ratingFor method in subclasses")
}
}
+22 -5
View File
@@ -18,7 +18,7 @@ func transformASCIIBoardInput(_ input: String) -> String {
for x in 0...7 {
let index = y*8 + x
transformedArt.append(boardArt[boardArt.characters.index(boardArt.startIndex, offsetBy: index)])
transformedArt.append(boardArt[boardArt.index(boardArt.startIndex, offsetBy: index)])
}
}
@@ -39,7 +39,11 @@ public struct ASCIIBoard {
artString = transformASCIIBoardInput(artString)
// Check string format
#if swift(>=3.2)
assert(artString.count == 64, "ASCII board art must be 128 characters long")
#else
assert(artString.characters.count == 64, "ASCII board art must be 128 characters long")
#endif
self.artString = artString
self.stringContainsColors = false
@@ -66,14 +70,17 @@ public struct ASCIIBoard {
// Clear all pieces on the board
BoardLocation.all.forEach {
board.removePiece(atLocation: $0)
board.removePiece(at: $0)
}
// Setup pieces from ascii art
(0..<64).forEach {
#if swift(>=3.2)
let character = boardArt[boardArt.index(boardArt.startIndex, offsetBy: $0)]
#else
let character = boardArt[boardArt.characters.index(boardArt.startIndex, offsetBy: $0)]
if let piece = pieceFromCharacter(character) {
#endif
if let piece = piece(from: character) {
board.setPiece(piece, at: BoardLocation(index: $0))
}
}
@@ -81,7 +88,7 @@ public struct ASCIIBoard {
return board
}
func pieceFromCharacter(_ character: Character) -> Piece? {
func piece(from character: Character) -> Piece? {
var piece: Piece?
@@ -121,9 +128,15 @@ public struct ASCIIBoard {
var index: Int?
#if swift(>=3.2)
if let idx = artString.index(of: character) {
index = artString.distance(from: artString.startIndex, to: idx)
}
#else
if let idx = artString.characters.index(of: character) {
index = artString.characters.distance(from: artString.startIndex, to: idx)
}
#endif
assert(index != nil, "Unable to find index of character: \(character)")
return index!
@@ -140,7 +153,11 @@ public struct ASCIIBoard {
var indexes = [Int]()
(0..<64).forEach {
#if swift(>=3.2)
let aCharacter = artString[artString.index(artString.startIndex, offsetBy: $0)]
#else
let aCharacter = artString[artString.characters.index(artString.startIndex, offsetBy: $0)]
#endif
if character == aCharacter {
indexes.append($0)
}
+33 -52
View File
@@ -29,12 +29,10 @@ public func == (lhs: Square, rhs: Square) -> Bool {
switch (lhs.piece, rhs.piece) {
case (.none, .none):
return true
case (.some, .none):
return false
case (.none, .some):
return false
case (.some(let rp), .some(let lp)):
return rp == lp
default:
return false
}
}
@@ -66,38 +64,26 @@ public struct Board: Equatable {
mutating func setupForNewGame() {
func setPieceAtIndex(_ piece: Piece, _ index: Int) {
setPiece(piece, at: BoardLocation(index: index))
}
let pieces: [Piece.PieceType] = [.rook, .knight, .bishop, .queen, .king, .bishop, .knight, .rook]
// Setup white bottom row
setPieceAtIndex(Piece(type: .rook, color: .white), 0)
setPieceAtIndex(Piece(type: .knight, color: .white), 1)
setPieceAtIndex(Piece(type: .bishop, color: .white), 2)
setPieceAtIndex(Piece(type: .queen, color: .white), 3)
setPieceAtIndex(Piece(type: .king, color: .white), 4)
setPieceAtIndex(Piece(type: .bishop, color: .white), 5)
setPieceAtIndex(Piece(type: .knight, color: .white), 6)
setPieceAtIndex(Piece(type: .rook, color: .white), 7)
for i in 0...7 {
setPiece(Piece(type: pieces[i], color: .white), at: BoardLocation(index: i))
}
// Setup white pawn row
for i in 8...15 {
setPieceAtIndex(Piece(type: .pawn, color: .white), i)
setPiece(Piece(type: .pawn, color: .white), at: BoardLocation(index: i))
}
// Setup black bottom row
setPieceAtIndex(Piece(type: .rook, color: .black), 63)
setPieceAtIndex(Piece(type: .knight, color: .black), 62)
setPieceAtIndex(Piece(type: .bishop, color: .black), 61)
setPieceAtIndex(Piece(type: .king, color: .black), 60)
setPieceAtIndex(Piece(type: .queen, color: .black), 59)
setPieceAtIndex(Piece(type: .bishop, color: .black), 58)
setPieceAtIndex(Piece(type: .knight, color: .black), 57)
setPieceAtIndex(Piece(type: .rook, color: .black), 56)
for i in 56...63 {
setPiece(Piece(type: pieces[i-56], color: .black), at: BoardLocation(index: i))
}
// Setup black pawn row
for i in 48...55 {
setPieceAtIndex(Piece(type: .pawn, color: .black), i)
setPiece(Piece(type: .pawn, color: .black), at: BoardLocation(index: i))
}
}
@@ -112,12 +98,12 @@ public struct Board: Equatable {
return squares[location.index].piece
}
public mutating func removePiece(atLocation location: BoardLocation) {
public mutating func removePiece(at location: BoardLocation) {
squares[location.index].piece = nil
}
@discardableResult internal mutating func movePiece(fromLocation: BoardLocation,
toLocation: BoardLocation) -> [BoardOperation] {
@discardableResult internal mutating func movePiece(from fromLocation: BoardLocation,
to toLocation: BoardLocation) -> [BoardOperation] {
if toLocation == fromLocation {
return []
@@ -147,13 +133,13 @@ public struct Board: Equatable {
let stride = fromLocation.strideTo(location: toLocation)
let enPassentStride = BoardStride(x: stride.x, y: 0)
let enPassentLocation = fromLocation.incrementedBy(stride: enPassentStride)
let enPassentLocation = fromLocation.incremented(by: enPassentStride)
guard let enPassentPiece = getPiece(at: enPassentLocation) else {
break IF_EN_PASSANT
}
if enPassentPiece.canBeTakenByEnPassant && enPassentPiece.color == movingPiece.color.opposite() {
if enPassentPiece.canBeTakenByEnPassant && enPassentPiece.color == movingPiece.color.opposite {
squares[enPassentLocation.index].piece = nil
let operation = BoardOperation(type: .removePiece, piece: enPassentPiece, location: enPassentLocation)
operations.append(operation)
@@ -223,7 +209,7 @@ public struct Board: Equatable {
fatalError("Couldn't find \(color) king. Kings should always exist")
}
public func getLocationsOfColor(_ color: Color) -> [BoardLocation] {
public func getLocations(of color: Color) -> [BoardLocation] {
var locations = [BoardLocation]()
@@ -306,7 +292,7 @@ public struct Board: Equatable {
}
// Work out if we're in check
let oppositionLocations = getLocationsOfColor( color.opposite() )
let oppositionLocations = getLocations(of: color.opposite)
// Pieces will not move to take the king, so change it for a pawn of the same color
var noKingBoard = self
@@ -318,7 +304,7 @@ public struct Board: Equatable {
continue
}
if piece.movement.canPieceMove(fromLocation: location, toLocation: kingLocation!, board: noKingBoard) {
if piece.movement.canPieceMove(from: location, to: kingLocation!, board: noKingBoard) {
return true
}
}
@@ -332,7 +318,7 @@ public struct Board: Equatable {
return false
}
for pieceLocation in getLocationsOfColor( color ) {
for pieceLocation in getLocations(of: color) {
guard let piece = getPiece(at: pieceLocation) else {
continue
@@ -340,13 +326,11 @@ public struct Board: Equatable {
for targetLocation in BoardLocation.all {
let canMove = piece.movement.canPieceMove(fromLocation: pieceLocation,
toLocation: targetLocation,
board: self)
let canMove = piece.movement.canPieceMove(from: pieceLocation, to: targetLocation, board: self)
if canMove {
var resultBoard = self
resultBoard.movePiece(fromLocation: pieceLocation, toLocation: targetLocation)
resultBoard.movePiece(from: pieceLocation, to: targetLocation)
if resultBoard.isColorInCheck(color: color) == false {
return false
}
@@ -368,7 +352,7 @@ public struct Board: Equatable {
func isColorAbleToMove(color: Color) -> Bool {
for pieceLocation in getLocationsOfColor(color) {
for pieceLocation in getLocations(of: color) {
guard let piece = getPiece(at: pieceLocation) else {
continue
@@ -376,16 +360,14 @@ public struct Board: Equatable {
for targetLocation in BoardLocation.all {
let canMove = piece.movement.canPieceMove(fromLocation: pieceLocation,
toLocation: targetLocation,
board: self)
let canMove = piece.movement.canPieceMove(from: pieceLocation, to: targetLocation, board: self)
guard canMove == true else {
continue
}
var resultBoard = self
resultBoard.movePiece(fromLocation: pieceLocation, toLocation: targetLocation)
resultBoard.movePiece(from: pieceLocation, to: targetLocation)
if resultBoard.isColorInCheck(color: color) == false {
return true
}
@@ -409,8 +391,7 @@ public struct Board: Equatable {
continue
}
if piece.movement.canPieceMove(fromLocation: BoardLocation(index: index),
toLocation: location, board: self) {
if piece.movement.canPieceMove(from: BoardLocation(index: index), to: location, board: self) {
return true
}
}
@@ -436,7 +417,7 @@ public struct Board: Equatable {
var locations = [BoardLocation]()
BoardLocation.all.forEach {
if piece.movement.canPieceMove(fromLocation: location, toLocation: $0, board: self) {
if piece.movement.canPieceMove(from: location, to: $0, board: self) {
locations.append($0)
}
}
@@ -561,7 +542,7 @@ public struct Board: Equatable {
var newBoard = self
let newLocation = BoardLocation(x: xPos, y: castleMove.yPos)
newBoard.movePiece(fromLocation: castleMove.kingStartLocation, toLocation: newLocation)
newBoard.movePiece(from: castleMove.kingStartLocation, to: newLocation)
if newBoard.isColorInCheck(color: color) {
return false
}
@@ -577,10 +558,10 @@ public struct Board: Equatable {
let castleMove = CastleMove(color: color, side: side)
let moveKingOperations = self.movePiece(fromLocation: castleMove.kingStartLocation,
toLocation: castleMove.kingEndLocation)
let moveRookOperations = self.movePiece(fromLocation: castleMove.rookStartLocation,
toLocation: castleMove.rookEndLocation)
let moveKingOperations = self.movePiece(from: castleMove.kingStartLocation,
to: castleMove.kingEndLocation)
let moveRookOperations = self.movePiece(from: castleMove.rookStartLocation,
to: castleMove.rookEndLocation)
return moveKingOperations + moveRookOperations
}
+3 -3
View File
@@ -80,10 +80,10 @@ public struct BoardLocation: Equatable {
return self + BoardLocation(x: x, y: y)
}
func incrementedBy(stride: BoardStride) -> BoardLocation {
func incremented(by stride: BoardStride) -> BoardLocation {
// TODO: Only call this in debug mode to increace performance!
if !canIncrementBy(stride: stride) {
if !canIncrement(by: stride) {
// swiftlint:disable line_length
print("WARNING! BoardLocation is being incremented by a stride that will result in wrapping! call canIncrementBy(stride: BoardStride) first")
// swiftlint:enable line_length
@@ -93,7 +93,7 @@ public struct BoardLocation: Equatable {
y: y + stride.y)
}
func canIncrementBy(stride: BoardStride) -> Bool {
func canIncrement(by stride: BoardStride) -> Bool {
// Check will not wrap to right
if x + stride.x > 7 {
@@ -10,7 +10,7 @@ import Foundation
class BoardRaterBoardDominance: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
let squareValue = Double(1)
@@ -24,7 +24,7 @@ class BoardRaterBoardDominance: BoardRater {
}
for targetLocation in BoardLocation.all {
if piece.movement.canPieceMove(fromLocation: sourcelocation, toLocation: targetLocation, board: board) {
if piece.movement.canPieceMove(from: sourcelocation, to: targetLocation, board: board) {
rating += (piece.color == color) ? squareValue : -squareValue
}
}
@@ -14,7 +14,7 @@ import Foundation
class BoardRaterCenterDominance: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
var rating = Double(0)
@@ -27,8 +27,8 @@ class BoardRaterCenterDominance: BoardRater {
for targetLocation in BoardLocation.all {
if sourceLocation == targetLocation ||
piece.movement.canPieceMove(fromLocation: sourceLocation,
toLocation: targetLocation,
piece.movement.canPieceMove(from: sourceLocation,
to: targetLocation,
board: board) {
let value = dominanceValueFor(location: targetLocation)
@@ -10,7 +10,7 @@ import Foundation
class BoardRaterCenterFourOccupation: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
let value = Double(1)
var rating = Double(0)
@@ -14,7 +14,7 @@ Rates the board according to which player's pieces are occupying the center of t
class BoardRaterCenterOwnership: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
var rating = Double(0)
@@ -16,7 +16,7 @@ import Foundation
class BoardRaterCheckMateOpportunity: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
let value = Double(1)
var rating = Double(0)
@@ -31,14 +31,14 @@ class BoardRaterCheckMateOpportunity: BoardRater {
let sourceLocation = BoardLocation(index: index)
if piece.movement.canPieceMove(fromLocation: sourceLocation, toLocation: location, board: board) {
if piece.movement.canPieceMove(from: sourceLocation, to: location, board: board) {
var movedBoard = board
movedBoard.movePiece(fromLocation: sourceLocation, toLocation: location)
movedBoard.movePiece(from: sourceLocation, to: location)
if piece.color == color && movedBoard.isColorInCheckMate(color: color.opposite()) {
if piece.color == color && movedBoard.isColorInCheckMate(color: color.opposite) {
rating += value
} else if piece.color == color.opposite() && movedBoard.isColorInCheckMate(color: color) {
} else if piece.color == color.opposite && movedBoard.isColorInCheckMate(color: color) {
rating -= value
}
}
@@ -10,7 +10,7 @@ import Foundation
class BoardRaterCountPieces: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
var rating: Double = 0
@@ -20,7 +20,7 @@ class BoardRaterCountPieces: BoardRater {
continue
}
rating += piece.color == color ? piece.value() : -piece.value()
rating += piece.color == color ? piece.value : -piece.value
}
return rating * configuration.boardRaterCountPiecesWeighting.value
@@ -10,18 +10,18 @@ import Foundation
class BoardRaterKingSurroundingPossession: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
let squareValue = Double(1)
var rating = Double(0)
let ownKingLocations = locationsSurroundingKing(color: color, board: board)
let opponentKingLocations = locationsSurroundingKing(color: color.opposite(), board: board)
let opponentKingLocations = locationsSurroundingKing(color: color.opposite, board: board)
// The kings will be able to move to their surrounding locations, so remove them from the board
var noKingsBoard = board
noKingsBoard.removePiece(atLocation: noKingsBoard.getKingLocation(color: .white))
noKingsBoard.removePiece(atLocation: noKingsBoard.getKingLocation(color: .black))
noKingsBoard.removePiece(at: noKingsBoard.getKingLocation(color: .white))
noKingsBoard.removePiece(at: noKingsBoard.getKingLocation(color: .black))
// we don't want to encourage the king to move out in to the open
rating += Double(8 - ownKingLocations.count) * squareValue * 3
@@ -33,14 +33,14 @@ class BoardRaterKingSurroundingPossession: BoardRater {
continue
}
if noKingsBoard.doesColorOccupyLocation(color: color.opposite(), location: location) {
if noKingsBoard.doesColorOccupyLocation(color: color.opposite, location: location) {
rating -= squareValue
continue
}
if noKingsBoard.canColorMoveAnyPieceToLocation(color: color, location: location) {
rating += squareValue
} else if noKingsBoard.canColorMoveAnyPieceToLocation(color: color.opposite(), location: location) {
} else if noKingsBoard.canColorMoveAnyPieceToLocation(color: color.opposite, location: location) {
rating -= squareValue
}
@@ -53,14 +53,14 @@ class BoardRaterKingSurroundingPossession: BoardRater {
continue
}
if noKingsBoard.doesColorOccupyLocation(color: color.opposite(), location: location) {
if noKingsBoard.doesColorOccupyLocation(color: color.opposite, location: location) {
rating -= squareValue
continue
}
if noKingsBoard.canColorMoveAnyPieceToLocation(color: color, location: location) {
rating += squareValue
} else if noKingsBoard.canColorMoveAnyPieceToLocation(color: color.opposite(), location: location) {
} else if noKingsBoard.canColorMoveAnyPieceToLocation(color: color.opposite, location: location) {
rating -= squareValue
}
}
@@ -87,8 +87,8 @@ class BoardRaterKingSurroundingPossession: BoardRater {
for stride in strides {
if kingLocation.canIncrementBy(stride: stride) {
let location = kingLocation.incrementedBy(stride: stride)
if kingLocation.canIncrement(by: stride) {
let location = kingLocation.incremented(by: stride)
surroundingLocations.append(location)
}
}
@@ -10,7 +10,7 @@ import Foundation
class BoardRaterPawnProgression: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
var rating = Double(0)
@@ -12,50 +12,50 @@ import Foundation
class BoardRaterThreatenedPieces: BoardRater {
override func ratingfor(board: Board, color: Color) -> Double {
override func ratingFor(board: Board, color: Color) -> Double {
let rating = board.getPieces(color: color)
.map { threatValue(forPiece: $0, onBoard: board) }
.map { threatValue(forPiece: $0, on: board) }
.reduce(0, +)
* configuration.boardRaterThreatenedPiecesWeighting.value
return rating
}
func threatValue(forPiece piece: Piece, onBoard board: Board) -> Double {
func threatValue(forPiece piece: Piece, on board: Board) -> Double {
let threatenedByPieces = getPieces(threatening: piece, onBoard: board)
let protectedByPieces = getPieces(protecting: piece, onBoard: board)
let threatenedByPieces = getPieces(threatening: piece, on: board)
let protectedByPieces = getPieces(protecting: piece, on: board)
let isThreatened = threatenedByPieces.count > 0
let isProtected = protectedByPieces.count > 0
// Threatened but not protected
if isThreatened && !isProtected {
return -piece.value() * 3
return -piece.value * 3
}
// Threatened, but protected (only return if the trade is not preferable)
if isThreatened && isProtected {
let lowestValueThreat = threatenedByPieces.lowestPieceValue()
let lowestValueThreat = threatenedByPieces.lowestPieceValue
if lowestValueThreat < piece.value() {
return -piece.value()
if lowestValueThreat < piece.value {
return -piece.value
}
// Here we could bump the value to encourage a good trade?
}
let targetPieces = getPieces(threatenedBy: piece, onBoard: board)
let targetPieces = getPieces(threatenedBy: piece, on: board)
for targetPiece in targetPieces {
let isTargetProtected = isPieceProtected(targetPiece, onBoard: board)
let isTargetProtected = isPieceProtected(targetPiece, on: board)
// If it's protected, is it a good trade
if isTargetProtected && targetPiece.value() < piece.value() {
if isTargetProtected && targetPiece.value < piece.value {
return 0
} else {
return targetPiece.value()
return targetPiece.value
}
}
@@ -65,33 +65,33 @@ class BoardRaterThreatenedPieces: BoardRater {
// MARK: - Helpers
func getPieces(protecting piece: Piece, onBoard board: Board) -> [Piece] {
func getPieces(protecting piece: Piece, on board: Board) -> [Piece] {
var alteredBoard = board
alteredBoard.setPiece(piece.withOppositeColor(), at: piece.location)
alteredBoard.setPiece(piece.withOppositeColor, at: piece.location)
return alteredBoard.getPieces(color: piece.color).filter {
$0.movement.canPieceMove(fromLocation: $0.location,
toLocation: piece.location,
$0.movement.canPieceMove(from: $0.location,
to: piece.location,
board: alteredBoard,
accountForCheckState: true)
}
}
func getPieces(protectedBy piece: Piece, onBoard board: Board) -> [Piece] {
func getPieces(protectedBy piece: Piece, on board: Board) -> [Piece] {
return board.getPieces(color: piece.color).filter {
piece.movement.canPieceMove(fromLocation: piece.location,
toLocation: $0.location,
piece.movement.canPieceMove(from: piece.location,
to: $0.location,
board: board,
accountForCheckState: true)
}
}
func isPieceProtected(_ piece: Piece, onBoard board: Board) -> Bool {
func isPieceProtected(_ piece: Piece, on board: Board) -> Bool {
var alteredBoard = board
alteredBoard.setPiece(piece.withOppositeColor(), at: piece.location)
alteredBoard.setPiece(piece.withOppositeColor, at: piece.location)
for square in alteredBoard.squares {
@@ -103,8 +103,8 @@ class BoardRaterThreatenedPieces: BoardRater {
continue
}
if squarePiece.movement.canPieceMove(fromLocation: squarePiece.location,
toLocation: piece.location,
if squarePiece.movement.canPieceMove(from: squarePiece.location,
to: piece.location,
board: alteredBoard,
accountForCheckState: true) {
return true
@@ -114,7 +114,7 @@ class BoardRaterThreatenedPieces: BoardRater {
return false
}
func isPieceThreatened(_ piece: Piece, onBoard board: Board) -> Bool {
func isPieceThreatened(_ piece: Piece, on board: Board) -> Bool {
for square in board.squares {
@@ -122,12 +122,12 @@ class BoardRaterThreatenedPieces: BoardRater {
continue
}
guard squarePiece.color == piece.color.opposite() else {
guard squarePiece.color == piece.color.opposite else {
continue
}
if squarePiece.movement.canPieceMove(fromLocation: squarePiece.location,
toLocation: piece.location,
if squarePiece.movement.canPieceMove(from: squarePiece.location,
to: piece.location,
board: board,
accountForCheckState: true) {
return true
@@ -137,39 +137,39 @@ class BoardRaterThreatenedPieces: BoardRater {
return false
}
func getPieces(threatening piece: Piece, onBoard board: Board) -> [Piece] {
func getPieces(threatening piece: Piece, on board: Board) -> [Piece] {
return board.getPieces(color: piece.color.opposite()).filter {
$0.movement.canPieceMove(fromLocation: $0.location,
toLocation: piece.location,
return board.getPieces(color: piece.color.opposite).filter {
$0.movement.canPieceMove(from: $0.location,
to: piece.location,
board: board,
accountForCheckState: true)
}
}
func getPieces(threatenedBy piece: Piece, onBoard board: Board) -> [Piece] {
func getPieces(threatenedBy piece: Piece, on board: Board) -> [Piece] {
return board.getPieces(color: piece.color.opposite()).filter {
piece.movement.canPieceMove(fromLocation: piece.location,
toLocation: $0.location,
return board.getPieces(color: piece.color.opposite).filter {
piece.movement.canPieceMove(from: piece.location,
to: $0.location,
board: board,
accountForCheckState: true)
}
}
func canPieceMoveToSafety(_ piece: Piece, onBoard board: Board) -> Bool {
func canPieceMoveToSafety(_ piece: Piece, on board: Board) -> Bool {
for location in BoardLocation.all {
if piece.movement.canPieceMove(fromLocation: piece.location,
toLocation: location,
if piece.movement.canPieceMove(from: piece.location,
to: location,
board: board,
accountForCheckState: true) {
var boardCopy = board
boardCopy.movePiece(fromLocation: piece.location, toLocation: location)
boardCopy.movePiece(from: piece.location, to: location)
let movedPiece = boardCopy.getPiece(at: location)!
if !isPieceThreatened(movedPiece, onBoard: boardCopy) {
if !isPieceThreatened(movedPiece, on: boardCopy) {
return true
}
}
@@ -181,17 +181,17 @@ class BoardRaterThreatenedPieces: BoardRater {
extension Collection where Iterator.Element == Piece {
func lowestPieceValue() -> Double {
var lowestPieceValue: Double {
if self.count == 0 {
return 0
}
var result = self.first!.value()
var result = self.first!.value
for piece in self {
let pieceValue = piece.value()
let pieceValue = piece.value
if pieceValue < result {
result = pieceValue
@@ -201,17 +201,17 @@ extension Collection where Iterator.Element == Piece {
return result
}
func highestPieceValue() -> Double {
var highestPieceValue: Double {
if self.count == 0 {
return 0
}
var result = self.first!.value()
var result = self.first!.value
for piece in self {
let pieceValue = piece.value()
let pieceValue = piece.value
if pieceValue > result {
result = pieceValue
+8 -8
View File
@@ -37,11 +37,11 @@ open class Game {
}
// MARK: Properties
open var board = Board(state: .newGame)
open var whitePlayer: Player!
open var blackPlayer: Player!
open var currentPlayer: Player!
open var state = Game.State.inProgress
open internal(set) var board: Board
open let whitePlayer: Player!
open let blackPlayer: Player!
open internal(set) var currentPlayer: Player!
open internal(set) var state = Game.State.inProgress
open weak var delegate: GameDelegate?
public var gameType: GameType {
@@ -99,15 +99,15 @@ extension Game: PlayerDelegate {
processBoardOperations(boardOperations: boardOperations)
// Check for game ended
if board.isColorInCheckMate(color: currentPlayer.color.opposite()) {
if board.isColorInCheckMate(color: currentPlayer.color.opposite) {
state = .won(color: currentPlayer.color)
delegate?.gameWonByPlayer(game: self, player: currentPlayer)
return
}
// Check for stalemate
if board.isColorInStalemate(color: currentPlayer.color.opposite()) {
state = .staleMate(color: currentPlayer.color.opposite())
if board.isColorInStalemate(color: currentPlayer.color.opposite) {
state = .staleMate(color: currentPlayer.color.opposite)
delegate?.gameEndedInStaleMate(game: self)
return
}
+5 -4
View File
@@ -19,7 +19,7 @@ open class Human: Player {
// MARK: - Public
public func movePiece(fromLocation: BoardLocation, toLocation: BoardLocation) throws {
public func movePiece(from fromLocation: BoardLocation, to toLocation: BoardLocation) throws {
// Check that the game is in progress
guard game.state == .inProgress else {
@@ -32,13 +32,14 @@ open class Human: Player {
}
// Check if move is allowed
let canMove = canMovePieceWithError(fromLocation: fromLocation, toLocation: toLocation)
if let error = canMove.error {
do {
_ = try canMovePiece(from: fromLocation, to: toLocation)
} catch let error {
throw error
}
// Move the piece
var operations = game.board.movePiece(fromLocation: fromLocation, toLocation: toLocation)
var operations = game.board.movePiece(from: fromLocation, to: toLocation)
// Make pawn promotions
let promotablePawnLocations = game.board.getLocationsOfPromotablePawns(color: color)
+13 -8
View File
@@ -12,6 +12,12 @@ struct OpeningMove {
let board: Board
let fromLocation: BoardLocation
let toLocation: BoardLocation
init(board: Board, from fromLocation: BoardLocation, to toLocation: BoardLocation) {
self.board = board
self.fromLocation = fromLocation
self.toLocation = toLocation
}
}
class Opening {
@@ -26,18 +32,18 @@ class Opening {
]
}
static func allOpeningMoves(forColor color: Color) -> [OpeningMove] {
static func allOpeningMoves(for color: Color) -> [OpeningMove] {
var openingMoves = [OpeningMove]()
allOpenings().forEach {
openingMoves += $0.moves(forColor: color)
openingMoves += $0.moves(for: color)
}
return openingMoves
}
public func moves(forColor color: Color) -> [OpeningMove] {
public func moves(for color: Color) -> [OpeningMove] {
var moves = [OpeningMove]()
@@ -45,12 +51,11 @@ class Opening {
for locations in moveLocations() {
let move = OpeningMove(board: board,
fromLocation: locations.fromLocation,
toLocation: locations.toLocation)
from: locations.fromLocation,
to: locations.toLocation)
moves.append(move)
board.movePiece(fromLocation: locations.fromLocation,
toLocation: locations.toLocation)
board.movePiece(from: locations.fromLocation, to: locations.toLocation)
//move.board.printBoardPieces()
@@ -62,7 +67,7 @@ class Opening {
}
}
/*
public func moveLocations(forColor color: Color) -> [(fromLocation: BoardLocation, toLocation: BoardLocation)] {
public func moveLocations(for color: Color) -> [(from fromLocation: BoardLocation, to toLocation: BoardLocation)] {
return moveLocations().enumerated().flatMap{ (index, value) in
index % 2 == (color == .white ? 0 : 1) ? value : nil
+31 -28
View File
@@ -8,20 +8,20 @@
import Foundation
public enum Color: Int {
case white
case black
public enum Color: String {
case white = "White"
case black = "Black"
public func opposite() -> Color {
public var opposite: Color {
return (self == .white) ? .black : .white
}
public func toString() -> String {
return (self == .white) ? "white" : "black"
public var string: String {
return rawValue.lowercased()
}
public func toStringWithCapital() -> String {
return (self == .white) ? "White" : "Black"
public var stringWithCapital: String {
return rawValue
}
}
@@ -37,6 +37,17 @@ public struct Piece: Equatable {
case queen
case king
var value: Double {
switch self {
case .pawn: return 1
case .rook: return 5
case .knight: return 3
case .bishop: return 3
case .queen: return 9
case .king: return 0 // King is always treated as a unique case
}
}
static func possiblePawnPromotionResultingTypes() -> [PieceType] {
return [.queen, .knight, .rook, .bishop]
}
@@ -44,13 +55,21 @@ public struct Piece: Equatable {
public let type: PieceType
public let color: Color
public var tag: Int!
public var hasMoved = false
public var canBeTakenByEnPassant = false
public internal(set) var tag: Int!
public internal(set) var hasMoved = false
public internal(set) var canBeTakenByEnPassant = false
public internal(set) var location = BoardLocation(index: 0)
var movement: PieceMovement! {
return PieceMovement.pieceMovementForPieceType(pieceType: self.type)
return PieceMovement.pieceMovement(for: self.type)
}
var withOppositeColor: Piece {
return Piece(type: type, color: color.opposite)
}
var value: Double {
return type.value
}
public init(type: PieceType, color: Color) {
@@ -67,28 +86,12 @@ public struct Piece: Equatable {
self.color = color
self.tag = tag
}
func value() -> Double {
switch type {
case .pawn: return 1
case .rook: return 5
case .knight: return 3
case .bishop: return 3
case .queen: return 9
case .king: return 0 // King is always treated as a unique case
}
}
func byChangingType(newType: PieceType) -> Piece {
let piece = Piece(type: newType, color: color, tag: tag)
return piece
}
func withOppositeColor() -> Piece {
return Piece(type: type, color: color.opposite())
}
}
public func == (left: Piece, right: Piece) -> Bool {
+52 -36
View File
@@ -21,7 +21,7 @@ let kingMovement = PieceMovementKing()
open class PieceMovement {
public class func pieceMovementForPieceType(pieceType: Piece.PieceType) -> PieceMovement {
public class func pieceMovement(for pieceType: Piece.PieceType) -> PieceMovement {
switch pieceType {
case .pawn:
@@ -42,8 +42,8 @@ open class PieceMovement {
public init() {
}
func canPieceMove(fromLocation: BoardLocation,
toLocation: BoardLocation,
func canPieceMove(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board,
accountForCheckState: Bool = false) -> Bool {
@@ -51,27 +51,27 @@ open class PieceMovement {
return false
}
let canMove = isMovementPossible(fromLocation: fromLocation, toLocation: toLocation, board: board)
let canMove = isMovementPossible(from: fromLocation, to: toLocation, board: board)
if canMove && accountForCheckState {
let color = board.getPiece(at: fromLocation)!.color
var boardCopy = board
boardCopy.movePiece(fromLocation: fromLocation, toLocation: toLocation)
boardCopy.movePiece(from: fromLocation, to: toLocation)
return boardCopy.isColorInCheck(color: color) ? false : true
} else {
return canMove
}
}
func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
func isMovementPossible(from fromLocation: BoardLocation, to toLocation: BoardLocation, board: Board) -> Bool {
return false
}
// swiftlint:disable function_body_length
func canPieceMove(fromLocation: BoardLocation,
toLocation: BoardLocation,
func canPieceMove(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board,
stride: BoardStride) -> Bool {
@@ -119,10 +119,10 @@ open class PieceMovement {
}
// Increment by stride
if !fromLocation.canIncrementBy(stride: stride) {
if !fromLocation.canIncrement(by: stride) {
return false
}
var testLocation = fromLocation.incrementedBy(stride: stride)
var testLocation = fromLocation.incremented(by: stride)
while testLocation.isInBounds() {
@@ -133,11 +133,11 @@ open class PieceMovement {
return false
}
if piece.color == movingPiece.color.opposite() && testLocation == toLocation {
if piece.color == movingPiece.color.opposite && testLocation == toLocation {
return true
}
if piece.color == movingPiece.color.opposite() && testLocation != toLocation {
if piece.color == movingPiece.color.opposite && testLocation != toLocation {
return false
}
}
@@ -147,10 +147,10 @@ open class PieceMovement {
}
// Increment by stride
if !testLocation.canIncrementBy(stride: stride) {
if !testLocation.canIncrement(by: stride) {
return false
}
testLocation = testLocation.incrementedBy(stride: stride)
testLocation = testLocation.incremented(by: stride)
}
@@ -200,7 +200,9 @@ open class PieceMovementStraightLine: PieceMovement {
BoardStride(x: 1, y: 0 ) // Right
]
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
let sameX = fromLocation.x == toLocation.x
let sameY = fromLocation.y == toLocation.y
@@ -210,7 +212,7 @@ open class PieceMovementStraightLine: PieceMovement {
}
for stride in strides {
if canPieceMove(fromLocation: fromLocation, toLocation: toLocation, board: board, stride: stride) {
if canPieceMove(from: fromLocation, to: toLocation, board: board, stride: stride) {
return true
}
}
@@ -231,14 +233,16 @@ open class PieceMovementDiagonal: PieceMovement {
BoardStride(x: -1, y: 1 ) // North West
]
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
if fromLocation.isDarkSquare != toLocation.isDarkSquare {
return false
}
for stride in strides {
if canPieceMove(fromLocation: fromLocation, toLocation: toLocation, board: board, stride: stride) {
if canPieceMove(from: fromLocation, to: toLocation, board: board, stride: stride) {
return true
}
}
@@ -255,11 +259,13 @@ open class PieceMovementQueen: PieceMovement {
let movements: [PieceMovement] = [PieceMovementStraightLine(), PieceMovementDiagonal()]
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
for pieceMovement in movements {
if pieceMovement.canPieceMove(fromLocation: fromLocation, toLocation: toLocation, board: board) {
if pieceMovement.canPieceMove(from: fromLocation, to: toLocation, board: board) {
return true
}
}
@@ -275,9 +281,11 @@ open class PieceMovementRook: PieceMovement {
let straightLineMovement = PieceMovementStraightLine()
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
return straightLineMovement.canPieceMove(fromLocation: fromLocation, toLocation: toLocation, board: board)
return straightLineMovement.canPieceMove(from: fromLocation, to: toLocation, board: board)
}
}
@@ -287,9 +295,11 @@ open class PieceMovementBishop: PieceMovement {
let diagonalMovement = PieceMovementDiagonal()
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
return diagonalMovement.canPieceMove(fromLocation: fromLocation, toLocation: toLocation, board: board)
return diagonalMovement.canPieceMove(from: fromLocation, to: toLocation, board: board)
}
}
@@ -308,7 +318,9 @@ open class PieceMovementKnight: PieceMovement {
(-1, 2)
]
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
// Make sure cannot take king
if let piece = board.getPiece(at: toLocation) {
@@ -340,7 +352,9 @@ open class PieceMovementKnight: PieceMovement {
// swiftlint:disable function_body_length
open class PieceMovementPawn: PieceMovement {
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
// Get the moving piece
guard let movingPiece = board.getPiece(at: fromLocation) else {
@@ -370,9 +384,9 @@ open class PieceMovementPawn: PieceMovement {
let oneAheadStride = (color == .white ? BoardStride(x: 0, y: 1) : BoardStride(x: 0, y: -1))
var canMoveOneAhead = true
ONE_AHEAD: if fromLocation.canIncrementBy(stride: oneAheadStride) {
ONE_AHEAD: if fromLocation.canIncrement(by: oneAheadStride) {
let location = fromLocation.incrementedBy(stride: oneAheadStride)
let location = fromLocation.incremented(by: oneAheadStride)
if board.getPiece(at: location) != nil {
canMoveOneAhead = false
@@ -397,7 +411,7 @@ open class PieceMovementPawn: PieceMovement {
TWO_AHEAD: if let twoAheadStride = twoAheadStride {
let twoAheadLocation = fromLocation.incrementedBy(stride: twoAheadStride)
let twoAheadLocation = fromLocation.incremented(by: twoAheadStride)
if toLocation != twoAheadLocation {
break TWO_AHEAD
@@ -422,11 +436,11 @@ open class PieceMovementPawn: PieceMovement {
for stride in diagonalStrides {
guard fromLocation.canIncrementBy(stride: stride) else {
guard fromLocation.canIncrement(by: stride) else {
continue
}
let location = fromLocation.incrementedBy(stride: stride)
let location = fromLocation.incremented(by: stride)
if location != toLocation {
continue
@@ -434,7 +448,7 @@ open class PieceMovementPawn: PieceMovement {
// If the target square has an opponent piece
if let piece = board.getPiece(at: location) {
if piece.color == color.opposite() {
if piece.color == color.opposite {
return true
}
}
@@ -442,17 +456,17 @@ open class PieceMovementPawn: PieceMovement {
// If can make en passent move
let enPassentStride = BoardStride(x: stride.x, y: 0)
guard fromLocation.canIncrementBy(stride: enPassentStride) else {
guard fromLocation.canIncrement(by: enPassentStride) else {
break
}
let enPassentLocation = fromLocation.incrementedBy(stride: enPassentStride)
let enPassentLocation = fromLocation.incremented(by: enPassentStride)
guard let passingPiece = board.getPiece(at: enPassentLocation) else {
break
}
if passingPiece.canBeTakenByEnPassant && passingPiece.color == color.opposite() {
if passingPiece.canBeTakenByEnPassant && passingPiece.color == color.opposite {
return true
}
@@ -478,7 +492,9 @@ open class PieceMovementKing: PieceMovement {
(-1, 1) // North- West
]
override func isMovementPossible(fromLocation: BoardLocation, toLocation: BoardLocation, board: Board) -> Bool {
override func isMovementPossible(from fromLocation: BoardLocation,
to toLocation: BoardLocation,
board: Board) -> Bool {
// Make sure cannot take king
if let piece = board.getPiece(at: toLocation) {
+16 -17
View File
@@ -18,7 +18,7 @@ open class Player {
weak var game: Game!
weak var delegate: PlayerDelegate?
public func occupiesSquareAt(location: BoardLocation) -> Bool {
public func occupiesSquare(at location: BoardLocation) -> Bool {
if let piece = self.game.board.getPiece(at: location) {
if piece.color == self.color {
@@ -29,11 +29,7 @@ open class Player {
return false
}
public func canMovePiece(fromLocation: BoardLocation, toLocation: BoardLocation) -> Bool {
return canMovePieceWithError(fromLocation: fromLocation, toLocation: toLocation).result
}
public enum MoveError: Error {
public enum MoveError: Int, Error, Equatable {
case notThisPlayersTurn
case movingToSameLocation
case noPieceToMove
@@ -42,46 +38,49 @@ open class Player {
case playerMustMoveOutOfCheck
case cannotMoveInToCheck
case gameIsNotInProgress
public static func == (lhs: MoveError, rhs: MoveError) -> Bool {
return lhs.rawValue == rhs.rawValue
}
}
public func canMovePieceWithError(fromLocation: BoardLocation, toLocation: BoardLocation) ->
(result: Bool, error: MoveError?) {
func canMovePiece(from fromLocation: BoardLocation, to toLocation: BoardLocation) throws -> Bool {
// We can't move to our current location
if fromLocation == toLocation {
return (false, .movingToSameLocation)
throw MoveError.movingToSameLocation
}
// Get the piece
guard let piece = self.game.board.getPiece(at: fromLocation) else {
return (false, .noPieceToMove)
throw MoveError.noPieceToMove
}
// Check that the piece color matches the player color
if piece.color != self.color {
return (false, .pieceColorDoesNotMatchPlayerColor)
throw MoveError.pieceColorDoesNotMatchPlayerColor
}
// Make sure the piece can move to the location
if !piece.movement.canPieceMove(fromLocation: fromLocation, toLocation: toLocation, board: game.board) {
return (false, .pieceUnableToMoveToLocation)
if !piece.movement.canPieceMove(from: fromLocation, to: toLocation, board: game.board) {
throw MoveError.pieceUnableToMoveToLocation
}
// Move the piece
let inCheckBeforeMove = self.game.board.isColorInCheck(color: self.color)
var board = self.game.board
board.movePiece(fromLocation: fromLocation, toLocation: toLocation)
board.movePiece(from: fromLocation, to: toLocation)
let inCheckAfterMove = board.isColorInCheck(color: self.color)
// Return
if inCheckBeforeMove && inCheckAfterMove {
return (false, .playerMustMoveOutOfCheck)
throw MoveError.playerMustMoveOutOfCheck
}
if !inCheckBeforeMove && inCheckAfterMove {
return (false, .cannotMoveInToCheck)
throw MoveError.cannotMoveInToCheck
}
return (true, nil)
return true
}
}