Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99c06fee3c | |||
| fb922da99b | |||
| 89d089d475 | |||
| 8f1e5f07a9 | |||
| 7865d0cee7 | |||
| 34a70295f2 | |||
| ed6444a784 | |||
| fa3580d2ce | |||
| 77a9e7f9e4 | |||
| d9b8ebace4 | |||
| 2ce751ad69 | |||
| 9b21f36f94 | |||
| 52ee0ed99a | |||
| efb982c1a7 | |||
| e6c44034aa | |||
| 921f5c6899 | |||
| f315a27db1 | |||
| f700ac2ec9 | |||
| 632765e72e | |||
| 17325af502 | |||
| 6373f189cc | |||
| 8e4e478ea3 | |||
| 7ebf83e7f4 | |||
| 612b3c7938 | |||
| faf65a02fb | |||
| 0f3cd549f6 | |||
| ce3df6cdce | |||
| 9ffafa0ee1 | |||
| 6f80d184de | |||
| 42fd768958 | |||
| f8e53472bf | |||
| ac147b5ee8 | |||
| fdf1f73ce9 | |||
| 0371a5d064 | |||
| aa31427b5f | |||
| 16c757ff1f | |||
| 88dda592b9 |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+6
-14
@@ -1,14 +1,6 @@
|
||||
# references:
|
||||
# * http://www.objc.io/issue-6/travis-ci.html
|
||||
# * https://github.com/supermarin/xcpretty#usage
|
||||
|
||||
osx_image: xcode7.3
|
||||
language: objective-c
|
||||
# cache: cocoapods
|
||||
# podfile: Example/Podfile
|
||||
# before_install:
|
||||
# - gem install cocoapods # Since Travis is not always on latest version
|
||||
# - pod install --project-directory=Example
|
||||
script:
|
||||
- set -o pipefail && xcodebuild test -workspace Example/SwiftChess.xcworkspace -scheme SwiftChess-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
|
||||
- pod lib lint
|
||||
language: swift
|
||||
osx_image: xcode12
|
||||
xcode_project: Example/Example.xcodeproj
|
||||
xcode_scheme: SwiftChessExample
|
||||
xcode_sdk: iphonesimulator14.0
|
||||
xcode_destination: platform=iOS Simulator,OS=14.0,name=iPhone 11 Pro Max
|
||||
|
||||
@@ -7,15 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
09AE32551E03D71D00A149FE /* BoardRaterPawnProgressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09AE32541E03D71D00A149FE /* BoardRaterPawnProgressionTests.swift */; };
|
||||
671989891DFFE0410053EA3D /* BoardRaterCenterOwnershipTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671989881DFFE0410053EA3D /* BoardRaterCenterOwnershipTests.swift */; };
|
||||
6719898D1DFFE0F40053EA3D /* BoardRaterBoardDominanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6719898C1DFFE0F40053EA3D /* BoardRaterBoardDominanceTests.swift */; };
|
||||
671989911DFFE8650053EA3D /* BoardRaterCenterDominanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671989901DFFE8650053EA3D /* BoardRaterCenterDominanceTests.swift */; };
|
||||
673B95191E4CE5880086CA97 /* BoardRaterThreatenedPiecesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A4C0281E013ECB000CFBF4 /* BoardRaterThreatenedPiecesTests.swift */; };
|
||||
676902581E432380007C76D7 /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676902571E432380007C76D7 /* PerformanceTests.swift */; };
|
||||
676C911C1E478A3A00985A4F /* SwiftChess.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 67A9CA0D1DE64D6500510FB8 /* SwiftChess.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
676EF7C51E15AC1700E275B4 /* BoardRaterKingSurroundingPossession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676EF7C41E15AC1700E275B4 /* BoardRaterKingSurroundingPossession.swift */; };
|
||||
67A3EB161E3A926C00F6F01B /* BoardScenarios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A3EB121E3A826800F6F01B /* BoardScenarios.swift */; };
|
||||
67A9CA341DE64DD600510FB8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
|
||||
67A9CA351DE64DD800510FB8 /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* MenuViewController.swift */; };
|
||||
67A9CA361DE64DDA00510FB8 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67AD33A61D7C67BF002730DF /* GameViewController.swift */; };
|
||||
@@ -25,20 +17,8 @@
|
||||
67A9CA3A1DE64E0E00510FB8 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
|
||||
67A9CA3C1DE64E2B00510FB8 /* SwiftChess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67A9CA0D1DE64D6500510FB8 /* SwiftChess.framework */; };
|
||||
67B73A9B1E15351900C19176 /* PromotionSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B73A9A1E15351900C19176 /* PromotionSelectionViewController.swift */; };
|
||||
67B73A9F1E154C1E00C19176 /* AIPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B73A9E1E154C1E00C19176 /* AIPlayerTests.swift */; };
|
||||
67D54A5D1DE7682D00C12258 /* BoardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A511DE7680E00C12258 /* BoardTests.swift */; };
|
||||
67D54A5E1DE7683000C12258 /* GameTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A521DE7680E00C12258 /* GameTests.swift */; };
|
||||
67D54A5F1DE7683300C12258 /* PieceMovementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A531DE7680E00C12258 /* PieceMovementTests.swift */; };
|
||||
67D54A601DE7683800C12258 /* PlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A541DE7680E00C12258 /* PlayerTests.swift */; };
|
||||
67D54A611DE7683A00C12258 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A551DE7680E00C12258 /* Tests.swift */; };
|
||||
67D54A641DE976A900C12258 /* BoardRaterCountPiecesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A631DE976A900C12258 /* BoardRaterCountPiecesTests.swift */; };
|
||||
67D54A661DE986F700C12258 /* PieceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A651DE986F700C12258 /* PieceTests.swift */; };
|
||||
67D54A681DE9A2DD00C12258 /* PieceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D54A671DE9A2DD00C12258 /* PieceView.swift */; };
|
||||
67F779261E1C32A400885B89 /* BoardRaterCenterFourOccupationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67F779251E1C32A400885B89 /* BoardRaterCenterFourOccupationTests.swift */; };
|
||||
67F9DB6E1E1AC8DC00C7EC5A /* BoardRaterCheckMateOpportunityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67F9DB6D1E1AC8DC00C7EC5A /* BoardRaterCheckMateOpportunityTests.swift */; };
|
||||
67F9DB751E1AD3BB00C7EC5A /* AIBehaviourTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67F9DB741E1AD3BB00C7EC5A /* AIBehaviourTests.swift */; };
|
||||
67FD868D1E41099B0023335C /* BoardLocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67FD868C1E41099B0023335C /* BoardLocationTests.swift */; };
|
||||
67FD86911E4128F00023335C /* OpeningsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67FD86901E4128F00023335C /* OpeningsTests.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -87,8 +67,6 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
09A4C0281E013ECB000CFBF4 /* BoardRaterThreatenedPiecesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterThreatenedPiecesTests.swift; sourceTree = "<group>"; };
|
||||
09AE32541E03D71D00A149FE /* BoardRaterPawnProgressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterPawnProgressionTests.swift; sourceTree = "<group>"; };
|
||||
607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
607FACD71AFB9204008FA782 /* MenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = "<group>"; };
|
||||
@@ -96,33 +74,14 @@
|
||||
607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
671989881DFFE0410053EA3D /* BoardRaterCenterOwnershipTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterOwnershipTests.swift; sourceTree = "<group>"; };
|
||||
6719898C1DFFE0F40053EA3D /* BoardRaterBoardDominanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterBoardDominanceTests.swift; sourceTree = "<group>"; };
|
||||
671989901DFFE8650053EA3D /* BoardRaterCenterDominanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterDominanceTests.swift; sourceTree = "<group>"; };
|
||||
676902571E432380007C76D7 /* PerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PerformanceTests.swift; sourceTree = "<group>"; };
|
||||
676EF7C41E15AC1700E275B4 /* BoardRaterKingSurroundingPossession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterKingSurroundingPossession.swift; sourceTree = "<group>"; };
|
||||
67A3EB121E3A826800F6F01B /* BoardScenarios.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardScenarios.swift; sourceTree = "<group>"; };
|
||||
67A9CA071DE64D6500510FB8 /* SwiftChess.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftChess.xcodeproj; path = ../SwiftChess/SwiftChess.xcodeproj; sourceTree = "<group>"; };
|
||||
67A9CA141DE64DAA00510FB8 /* SwiftChessExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftChessExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
67A9CA271DE64DAA00510FB8 /* SwiftChessExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftChessExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
67AD33A61D7C67BF002730DF /* GameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = "<group>"; };
|
||||
67AD33A81D7C67DF002730DF /* BoardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardView.swift; sourceTree = "<group>"; };
|
||||
67B73A9A1E15351900C19176 /* PromotionSelectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromotionSelectionViewController.swift; sourceTree = "<group>"; };
|
||||
67B73A9E1E154C1E00C19176 /* AIPlayerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AIPlayerTests.swift; sourceTree = "<group>"; };
|
||||
67D54A511DE7680E00C12258 /* BoardTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardTests.swift; sourceTree = "<group>"; };
|
||||
67D54A521DE7680E00C12258 /* GameTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameTests.swift; sourceTree = "<group>"; };
|
||||
67D54A531DE7680E00C12258 /* PieceMovementTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PieceMovementTests.swift; sourceTree = "<group>"; };
|
||||
67D54A541DE7680E00C12258 /* PlayerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerTests.swift; sourceTree = "<group>"; };
|
||||
67D54A551DE7680E00C12258 /* Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
|
||||
67D54A631DE976A900C12258 /* BoardRaterCountPiecesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCountPiecesTests.swift; sourceTree = "<group>"; };
|
||||
67D54A651DE986F700C12258 /* PieceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PieceTests.swift; sourceTree = "<group>"; };
|
||||
67D54A671DE9A2DD00C12258 /* PieceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PieceView.swift; sourceTree = "<group>"; };
|
||||
67F7791F1E1B923B00885B89 /* AIConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AIConfigurationTests.swift; sourceTree = "<group>"; };
|
||||
67F779251E1C32A400885B89 /* BoardRaterCenterFourOccupationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterFourOccupationTests.swift; sourceTree = "<group>"; };
|
||||
67F9DB6D1E1AC8DC00C7EC5A /* BoardRaterCheckMateOpportunityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCheckMateOpportunityTests.swift; sourceTree = "<group>"; };
|
||||
67F9DB741E1AD3BB00C7EC5A /* AIBehaviourTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AIBehaviourTests.swift; sourceTree = "<group>"; };
|
||||
67FD868C1E41099B0023335C /* BoardLocationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardLocationTests.swift; sourceTree = "<group>"; };
|
||||
67FD86901E4128F00023335C /* OpeningsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpeningsTests.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -198,18 +157,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
607FACE91AFB9204008FA782 /* Supporting Files */,
|
||||
67D54A651DE986F700C12258 /* PieceTests.swift */,
|
||||
67FD868C1E41099B0023335C /* BoardLocationTests.swift */,
|
||||
67D54A511DE7680E00C12258 /* BoardTests.swift */,
|
||||
67D54A521DE7680E00C12258 /* GameTests.swift */,
|
||||
67D54A531DE7680E00C12258 /* PieceMovementTests.swift */,
|
||||
67D54A541DE7680E00C12258 /* PlayerTests.swift */,
|
||||
67B73A9E1E154C1E00C19176 /* AIPlayerTests.swift */,
|
||||
67F7791F1E1B923B00885B89 /* AIConfigurationTests.swift */,
|
||||
67F9DB741E1AD3BB00C7EC5A /* AIBehaviourTests.swift */,
|
||||
676902571E432380007C76D7 /* PerformanceTests.swift */,
|
||||
67FD86901E4128F00023335C /* OpeningsTests.swift */,
|
||||
67D54A621DE9768200C12258 /* BoardRaters */,
|
||||
67D54A551DE7680E00C12258 /* Tests.swift */,
|
||||
);
|
||||
path = Tests;
|
||||
@@ -219,7 +166,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
607FACEA1AFB9204008FA782 /* Info.plist */,
|
||||
67A3EB121E3A826800F6F01B /* BoardScenarios.swift */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
@@ -233,22 +179,6 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
67D54A621DE9768200C12258 /* BoardRaters */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67D54A631DE976A900C12258 /* BoardRaterCountPiecesTests.swift */,
|
||||
671989881DFFE0410053EA3D /* BoardRaterCenterOwnershipTests.swift */,
|
||||
6719898C1DFFE0F40053EA3D /* BoardRaterBoardDominanceTests.swift */,
|
||||
671989901DFFE8650053EA3D /* BoardRaterCenterDominanceTests.swift */,
|
||||
09A4C0281E013ECB000CFBF4 /* BoardRaterThreatenedPiecesTests.swift */,
|
||||
09AE32541E03D71D00A149FE /* BoardRaterPawnProgressionTests.swift */,
|
||||
676EF7C41E15AC1700E275B4 /* BoardRaterKingSurroundingPossession.swift */,
|
||||
67F9DB6D1E1AC8DC00C7EC5A /* BoardRaterCheckMateOpportunityTests.swift */,
|
||||
67F779251E1C32A400885B89 /* BoardRaterCenterFourOccupationTests.swift */,
|
||||
);
|
||||
name = BoardRaters;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
67D54A691DE9A3C500C12258 /* Game */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -309,18 +239,18 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0800;
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 1200;
|
||||
ORGANIZATIONNAME = CocoaPods;
|
||||
TargetAttributes = {
|
||||
67A9CA131DE64DAA00510FB8 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
DevelopmentTeam = VAA3W4LPY2;
|
||||
LastSwiftMigration = 0900;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
67A9CA261DE64DAA00510FB8 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
LastSwiftMigration = 0900;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = 67A9CA131DE64DAA00510FB8;
|
||||
};
|
||||
@@ -328,7 +258,7 @@
|
||||
};
|
||||
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Example" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
@@ -437,27 +367,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
67D54A601DE7683800C12258 /* PlayerTests.swift in Sources */,
|
||||
67FD86911E4128F00023335C /* OpeningsTests.swift in Sources */,
|
||||
67D54A611DE7683A00C12258 /* Tests.swift in Sources */,
|
||||
676EF7C51E15AC1700E275B4 /* BoardRaterKingSurroundingPossession.swift in Sources */,
|
||||
67FD868D1E41099B0023335C /* BoardLocationTests.swift in Sources */,
|
||||
67D54A5D1DE7682D00C12258 /* BoardTests.swift in Sources */,
|
||||
67F9DB751E1AD3BB00C7EC5A /* AIBehaviourTests.swift in Sources */,
|
||||
671989911DFFE8650053EA3D /* BoardRaterCenterDominanceTests.swift in Sources */,
|
||||
6719898D1DFFE0F40053EA3D /* BoardRaterBoardDominanceTests.swift in Sources */,
|
||||
67D54A5E1DE7683000C12258 /* GameTests.swift in Sources */,
|
||||
673B95191E4CE5880086CA97 /* BoardRaterThreatenedPiecesTests.swift in Sources */,
|
||||
67D54A661DE986F700C12258 /* PieceTests.swift in Sources */,
|
||||
671989891DFFE0410053EA3D /* BoardRaterCenterOwnershipTests.swift in Sources */,
|
||||
67B73A9F1E154C1E00C19176 /* AIPlayerTests.swift in Sources */,
|
||||
676902581E432380007C76D7 /* PerformanceTests.swift in Sources */,
|
||||
67D54A641DE976A900C12258 /* BoardRaterCountPiecesTests.swift in Sources */,
|
||||
67A3EB161E3A926C00F6F01B /* BoardScenarios.swift in Sources */,
|
||||
09AE32551E03D71D00A149FE /* BoardRaterPawnProgressionTests.swift in Sources */,
|
||||
67D54A5F1DE7683300C12258 /* PieceMovementTests.swift in Sources */,
|
||||
67F779261E1C32A400885B89 /* BoardRaterCenterFourOccupationTests.swift in Sources */,
|
||||
67F9DB6E1E1AC8DC00C7EC5A /* BoardRaterCheckMateOpportunityTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -500,6 +410,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -508,14 +419,17 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -541,7 +455,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -553,6 +467,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -561,14 +476,17 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -587,7 +505,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
@@ -606,12 +524,12 @@
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = VAA3W4LPY2;
|
||||
INFOPLIST_FILE = SwiftChess/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChessExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -626,11 +544,11 @@
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
DEVELOPMENT_TEAM = VAA3W4LPY2;
|
||||
INFOPLIST_FILE = SwiftChess/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChessExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
@@ -645,12 +563,12 @@
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
INFOPLIST_FILE = Tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChessExampleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftChessExample.app/SwiftChessExample";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -664,11 +582,11 @@
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
INFOPLIST_FILE = Tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChessExampleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftChessExample.app/SwiftChessExample";
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0900"
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -40,8 +40,16 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
|
||||
BuildableName = "SwiftChess_Example.app"
|
||||
BlueprintName = "SwiftChess_Example"
|
||||
ReferencedContainer = "container:SwiftChess.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -54,23 +62,11 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
|
||||
BuildableName = "SwiftChess_Example.app"
|
||||
BlueprintName = "SwiftChess_Example"
|
||||
ReferencedContainer = "container:SwiftChess.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
@@ -87,8 +83,6 @@
|
||||
ReferencedContainer = "container:SwiftChess.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "67A9CA131DE64DAA00510FB8"
|
||||
BuildableName = "SwiftChessExample.app"
|
||||
BlueprintName = "SwiftChessExample"
|
||||
ReferencedContainer = "container:Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "67A9CA131DE64DAA00510FB8"
|
||||
BuildableName = "SwiftChessExample.app"
|
||||
BlueprintName = "SwiftChessExample"
|
||||
ReferencedContainer = "container:Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "67A9CA261DE64DAA00510FB8"
|
||||
BuildableName = "SwiftChessExampleTests.xctest"
|
||||
BlueprintName = "SwiftChessExampleTests"
|
||||
ReferencedContainer = "container:Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "67A9C9E61DE64CD300510FB8"
|
||||
BuildableName = "SwiftChessTests.xctest"
|
||||
BlueprintName = "SwiftChessTests"
|
||||
ReferencedContainer = "container:../SwiftChess/SwiftChess.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "67A9CA131DE64DAA00510FB8"
|
||||
BuildableName = "SwiftChessExample.app"
|
||||
BlueprintName = "SwiftChessExample"
|
||||
ReferencedContainer = "container:Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "67A9CA131DE64DAA00510FB8"
|
||||
BuildableName = "SwiftChessExample.app"
|
||||
BlueprintName = "SwiftChessExample"
|
||||
ReferencedContainer = "container:Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ class GameViewController: UIViewController {
|
||||
|
||||
func removePieceView(pieceView: PieceView) {
|
||||
|
||||
if let index = pieceViews.index(of: pieceView) {
|
||||
if let index = pieceViews.firstIndex(of: pieceView) {
|
||||
pieceViews.remove(at: index)
|
||||
}
|
||||
|
||||
@@ -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!"
|
||||
@@ -405,13 +405,13 @@ extension GameViewController: GameDelegate {
|
||||
possibleTypes: possiblePromotions) {
|
||||
|
||||
self.promotionSelectionViewController?.view.removeFromSuperview()
|
||||
self.promotionSelectionViewController?.removeFromParentViewController()
|
||||
self.promotionSelectionViewController?.removeFromParent()
|
||||
self.boardView.isUserInteractionEnabled = true
|
||||
callback($0)
|
||||
}
|
||||
|
||||
view.addSubview(viewController.view)
|
||||
addChildViewController(viewController)
|
||||
addChild(viewController)
|
||||
promotionSelectionViewController = viewController
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -72,7 +72,7 @@ class PromotionSelectionViewController: UIViewController {
|
||||
|
||||
@objc func buttonPressed(sender: UIButton) {
|
||||
|
||||
let index = buttons.index(of: sender)!
|
||||
let index = buttons.firstIndex(of: sender)!
|
||||
print("Button pressed at index: \(index)")
|
||||
|
||||
let chosenType = possibleTypes![index]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import UIKit
|
||||
import XCTest
|
||||
import SwiftChess
|
||||
|
||||
class Tests: XCTestCase {
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// swift-tools-version:5.1
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(name: "SwiftChess",
|
||||
platforms: [.macOS(.v10_14),
|
||||
.iOS(.v10),
|
||||
.tvOS(.v10)],
|
||||
products: [.library(name: "SwiftChess",
|
||||
targets: ["SwiftChess"])],
|
||||
targets: [.target(name: "SwiftChess",
|
||||
path: "SwiftChess/Source"),
|
||||
.testTarget(name: "SwiftChessTests",
|
||||
dependencies: ["SwiftChess"],
|
||||
path: "SwiftChess/SwiftChessTests")],
|
||||
swiftLanguageVersions: [.v5])
|
||||
@@ -1,8 +1,10 @@
|
||||
# SwiftChess
|
||||
|
||||
[](http://cocoapods.org/pods/SwiftChess)
|
||||
[](http://cocoapods.org/pods/SwiftChess)
|
||||
[](http://cocoapods.org/pods/SwiftChess)
|
||||
[](http://cocoapods.org/pods/SwiftChess)
|
||||
[](http://cocoapods.org/pods/SwiftChess)
|
||||
[](http://cocoapods.org/pods/SwiftChess)
|
||||
[](https://travis-ci.org/SteveBarnegren/SwiftChess)
|
||||
[](https://twitter.com/stevebarnegren)
|
||||
|
||||
SwiftChess is a chess engine written in Swift.
|
||||
|
||||
@@ -23,7 +25,7 @@ SwiftChess doesn't provide any UI, just all of the logic required to create a ch
|
||||
|
||||
## Example
|
||||
|
||||
The example application contains a complete implementation of swift chess.
|
||||
The example application contains a complete implementation of **SwiftChess**.
|
||||
|
||||
Run `Example/Example.xcodeproj`
|
||||
|
||||
@@ -46,12 +48,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)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -93,6 +95,27 @@ extension GameViewController: GameDelegate {
|
||||
}
|
||||
```
|
||||
|
||||
## Persistence
|
||||
|
||||
The entire state of a **SwiftChess** game can be converted to and initialised from a `Dictionary`.
|
||||
|
||||
Get a snapshot of the current state:
|
||||
|
||||
```
|
||||
let dictionary: [String: Any] = game.dictionaryRepresentation
|
||||
```
|
||||
|
||||
Initialise a game with a previous snapshot:
|
||||
|
||||
```
|
||||
let game = Game(dictionary: dictionary)
|
||||
```
|
||||
|
||||
The returned dictionary stores all the information required to create a 'save game' feature. The player colors, AI difficulty, piece positions etc.
|
||||
|
||||
You can serialize this to JSON, save it to disk, send it over the network etc.
|
||||
|
||||
|
||||
## Other stuff
|
||||
|
||||
##### Make a castling move
|
||||
@@ -107,15 +130,16 @@ if game.board.canColorCastle(color: .white, side: .kingSide) {
|
||||
|
||||
```
|
||||
func promotedTypeForPawn(location: BoardLocation,
|
||||
player: Human,
|
||||
possiblePromotions: [Piece.PieceType],
|
||||
callback: @escaping (Piece.PieceType) -> Void) {
|
||||
player: Human,
|
||||
possiblePromotions: [Piece.PieceType],
|
||||
callback: @escaping (Piece.PieceType) -> Void) {
|
||||
|
||||
// Show UI for the user to select one of the possible promotion types
|
||||
// then call the handler
|
||||
|
||||
// ...or some games just promote to a queen
|
||||
callback(.queen)
|
||||
}
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
+3
-2
@@ -8,7 +8,7 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'SwiftChess'
|
||||
s.version = '0.2.0'
|
||||
s.version = '1.1.1'
|
||||
s.summary = 'Chess engine written in Swift'
|
||||
|
||||
# This description is used to generate tags and improve search results.
|
||||
@@ -18,7 +18,7 @@ Pod::Spec.new do |s|
|
||||
# * Finally, don't worry about the indent, CocoaPods strips it!
|
||||
|
||||
s.description = <<-DESC
|
||||
Chess engine written in Swift
|
||||
Chess engine written in Swift, support player vs player, and player vs AI games.
|
||||
DESC
|
||||
|
||||
s.homepage = 'https://github.com/SteveBarnegren/SwiftChess'
|
||||
@@ -26,6 +26,7 @@ Chess engine written in Swift
|
||||
s.author = { 'Steve Barnegren' => 'steve.barnegren@gmail.com' }
|
||||
s.source = { :git => 'https://github.com/SteveBarnegren/SwiftChess.git', :tag => s.version.to_s }
|
||||
s.social_media_url = 'https://twitter.com/stevebarnegren'
|
||||
s.swift_version = '5.0'
|
||||
|
||||
s.ios.deployment_target = '8.0'
|
||||
|
||||
|
||||
@@ -27,16 +27,16 @@ public struct AIConfiguration {
|
||||
}
|
||||
|
||||
public let difficulty: Difficulty!
|
||||
var suicideMultipler: ConfigurationValue!
|
||||
var boardRaterCountPiecesWeighting: ConfigurationValue!
|
||||
var boardRaterBoardDominanceWeighting: ConfigurationValue!
|
||||
var boardRaterCenterOwnershipWeighting: ConfigurationValue!
|
||||
var boardRaterCenterDominanceWeighting: ConfigurationValue!
|
||||
var boardRaterThreatenedPiecesWeighting: ConfigurationValue!
|
||||
var boardRaterPawnProgressionWeighting: ConfigurationValue!
|
||||
var boardRaterKingSurroundingPossessionWeighting: ConfigurationValue!
|
||||
var boardRaterCheckMateOpportunityWeighting: ConfigurationValue!
|
||||
var boardRaterCenterFourOccupationWeighting: ConfigurationValue!
|
||||
internal var suicideMultipler: ConfigurationValue
|
||||
internal var boardRaterCountPiecesWeighting: ConfigurationValue
|
||||
internal var boardRaterBoardDominanceWeighting: ConfigurationValue
|
||||
internal var boardRaterCenterOwnershipWeighting: ConfigurationValue
|
||||
internal var boardRaterCenterDominanceWeighting: ConfigurationValue
|
||||
internal var boardRaterThreatenedPiecesWeighting: ConfigurationValue
|
||||
internal var boardRaterPawnProgressionWeighting: ConfigurationValue
|
||||
internal var boardRaterKingSurroundingPossessionWeighting: ConfigurationValue
|
||||
internal var boardRaterCheckMateOpportunityWeighting: ConfigurationValue
|
||||
internal var boardRaterCenterFourOccupationWeighting: ConfigurationValue
|
||||
|
||||
public init(difficulty: Difficulty) {
|
||||
|
||||
@@ -66,4 +66,49 @@ public struct AIConfiguration {
|
||||
boardRaterCenterFourOccupationWeighting = makeValue(0.1, 0.3)
|
||||
}
|
||||
|
||||
internal init() {
|
||||
|
||||
let zeroValue = ConfigurationValue(easyValue: 0, difficultValue: 0, multiplier: 0)
|
||||
|
||||
difficulty = .easy
|
||||
suicideMultipler = zeroValue
|
||||
boardRaterCountPiecesWeighting = zeroValue
|
||||
boardRaterBoardDominanceWeighting = zeroValue
|
||||
boardRaterCenterOwnershipWeighting = zeroValue
|
||||
boardRaterCenterDominanceWeighting = zeroValue
|
||||
boardRaterThreatenedPiecesWeighting = zeroValue
|
||||
boardRaterPawnProgressionWeighting = zeroValue
|
||||
boardRaterKingSurroundingPossessionWeighting = zeroValue
|
||||
boardRaterCheckMateOpportunityWeighting = zeroValue
|
||||
boardRaterCenterFourOccupationWeighting = zeroValue
|
||||
}
|
||||
}
|
||||
|
||||
extension AIConfiguration: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let difficulty = "difficulty"
|
||||
}
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
|
||||
if let raw = dictionary[Keys.difficulty] as? Int, let difficulty = Difficulty(rawValue: raw) {
|
||||
self.init(difficulty: difficulty)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
dictionary[Keys.difficulty] = difficulty.rawValue
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
extension AIConfiguration: Equatable {
|
||||
public static func == (lhs: AIConfiguration, rhs: AIConfiguration) -> Bool {
|
||||
return lhs.difficulty == rhs.difficulty
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
// swiftlint:disable for_where
|
||||
import Foundation
|
||||
|
||||
open class AIPlayer: Player {
|
||||
public final 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)
|
||||
|
||||
@@ -279,10 +278,45 @@ open class AIPlayer: Player {
|
||||
}
|
||||
}
|
||||
|
||||
extension AIPlayer: Equatable {
|
||||
public static func == (lhs: AIPlayer, rhs: AIPlayer) -> Bool {
|
||||
return lhs.color == rhs.color && lhs.configuration == rhs.configuration
|
||||
}
|
||||
}
|
||||
|
||||
extension AIPlayer: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let color = "color"
|
||||
static let configuration = "configuration"
|
||||
}
|
||||
|
||||
convenience init?(dictionary: [String: Any]) {
|
||||
|
||||
guard
|
||||
let colorRaw = dictionary[Keys.color] as? String,
|
||||
let color = Color(rawValue: colorRaw),
|
||||
let configurationDict = dictionary[Keys.configuration] as? [String: Any],
|
||||
let configuration = AIConfiguration(dictionary: configurationDict) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.init(color: color, configuration: configuration)
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
dictionary[Keys.color] = color.rawValue
|
||||
dictionary[Keys.configuration] = configuration.dictionaryRepresentation
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
struct Move {
|
||||
|
||||
enum MoveType {
|
||||
case singlePiece(sourceLocation: BoardLocation, targetLocation: BoardLocation)
|
||||
case singlePiece(from: BoardLocation, to: BoardLocation)
|
||||
case castle(color: Color, side: CastleSide)
|
||||
}
|
||||
|
||||
@@ -300,7 +334,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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.firstIndex(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)
|
||||
}
|
||||
|
||||
@@ -29,12 +29,35 @@ 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
|
||||
return rp.isSameTypeAndColor(asPiece: lp)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
extension Square: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let piece = "piece"
|
||||
}
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
|
||||
if let dict = dictionary[Keys.piece] as? [String: Any], let piece = Piece(dictionary: dict) {
|
||||
self.piece = piece
|
||||
}
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
|
||||
if let piece = self.piece {
|
||||
dictionary[Keys.piece] = piece.dictionaryRepresentation
|
||||
}
|
||||
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +71,7 @@ public struct Board: Equatable {
|
||||
}
|
||||
|
||||
public private(set) var squares = [Square]()
|
||||
private var lastAssignedPieceTag = 0
|
||||
|
||||
// MARK: - Init
|
||||
public init(state: InitialState) {
|
||||
@@ -61,43 +85,35 @@ public struct Board: Equatable {
|
||||
if state == .newGame {
|
||||
setupForNewGame()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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]
|
||||
|
||||
func makePiece(type: Piece.PieceType, color: Color) -> Piece {
|
||||
lastAssignedPieceTag += 1
|
||||
return Piece(type: type, color: color, tag: lastAssignedPieceTag)
|
||||
}
|
||||
|
||||
// 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(makePiece(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(makePiece(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(makePiece(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(makePiece(type: .pawn, color: .black), at: BoardLocation(index: i))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +128,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 +163,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)
|
||||
@@ -196,7 +212,7 @@ public struct Board: Equatable {
|
||||
continue
|
||||
}
|
||||
|
||||
if piece == Piece(type: .king, color: color) {
|
||||
if piece.isSameTypeAndColor(asPiece: Piece(type: .king, color: color)) {
|
||||
king = piece
|
||||
break
|
||||
}
|
||||
@@ -223,7 +239,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 +322,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 +334,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 +348,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 +356,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 +382,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 +390,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 +421,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 +447,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 +572,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 +588,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
|
||||
}
|
||||
@@ -641,7 +652,7 @@ public struct Board: Equatable {
|
||||
case .queen:
|
||||
character = piece.color == .white ? "Q" : "q"
|
||||
case .king:
|
||||
character = piece.color == .white ? "K" : "k"
|
||||
character = piece.color == .white ? "G" : "g"
|
||||
case .pawn:
|
||||
character = piece.color == .white ? "P" : "p"
|
||||
}
|
||||
@@ -673,3 +684,35 @@ public struct Board: Equatable {
|
||||
public func == (lhs: Board, rhs: Board) -> Bool {
|
||||
return lhs.squares == rhs.squares
|
||||
}
|
||||
|
||||
extension Board: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let squares = "squares"
|
||||
}
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
|
||||
guard let squaresDicts = dictionary[Keys.squares] as? [[String: Any]] else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let squares = squaresDicts.compactMap { Square(dictionary: $0) }
|
||||
if squares.count == 64 {
|
||||
self.squares = squares
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
lastAssignedPieceTag = squares.compactMap { $0.piece }.map { $0.tag }.max() ?? 0
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
let squares = self.squares.map { $0.dictionaryRepresentation }
|
||||
dictionary[Keys.squares] = squares
|
||||
return dictionary
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,20 +80,18 @@ 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) {
|
||||
// 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
|
||||
}
|
||||
// swiftlint:disable line_length
|
||||
assert(canIncrement(by: stride),
|
||||
"BoardLocation is being incremented by a stride that will result in wrapping! call canIncrementBy(stride: BoardStride) first")
|
||||
// swiftlint:enable line_length
|
||||
|
||||
return BoardLocation(x: x + stride.x,
|
||||
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 {
|
||||
@@ -138,3 +136,26 @@ public func == (lhs: BoardLocation, rhs: BoardLocation) -> Bool {
|
||||
public func + (left: BoardLocation, right: BoardLocation) -> BoardLocation {
|
||||
return BoardLocation(index: left.index + right.index)
|
||||
}
|
||||
|
||||
extension BoardLocation: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let index = "index"
|
||||
}
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
|
||||
guard let index = dictionary[Keys.index] as? Int else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.index = index
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
dictionary[Keys.index] = index
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// DictionaryRepresentable.swift
|
||||
// SwiftChess
|
||||
//
|
||||
// Created by Steve Barnegren on 13/01/2018.
|
||||
// Copyright © 2018 Steve Barnegren. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol DictionaryRepresentable {
|
||||
|
||||
init?(dictionary: [String: Any])
|
||||
var dictionaryRepresentation: [String: Any] {get}
|
||||
}
|
||||
+186
-11
@@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
open class Game {
|
||||
public final class Game {
|
||||
|
||||
// MARK: Types
|
||||
public enum State: Equatable {
|
||||
@@ -30,19 +30,19 @@ open class Game {
|
||||
}
|
||||
}
|
||||
|
||||
public enum GameType {
|
||||
public enum GameType: Int {
|
||||
case humanVsHuman
|
||||
case humanVsComputer
|
||||
case computerVsComputer
|
||||
}
|
||||
|
||||
// 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 weak var delegate: GameDelegate?
|
||||
public internal(set) var board: Board
|
||||
public let whitePlayer: Player!
|
||||
public let blackPlayer: Player!
|
||||
public internal(set) var currentPlayer: Player!
|
||||
public internal(set) var state = Game.State.inProgress
|
||||
public 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
|
||||
}
|
||||
@@ -151,6 +151,181 @@ extension Game: PlayerDelegate {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - DictionaryRepresentable
|
||||
|
||||
extension Game.State: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let type = "type"
|
||||
static let type_inProgress = "inProgress"
|
||||
static let type_stalemate = "stalemate"
|
||||
static let type_won = "won"
|
||||
static let color = "color"
|
||||
}
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
|
||||
guard let type = dictionary[Keys.type] as? String else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch type {
|
||||
case Keys.type_inProgress:
|
||||
self = .inProgress
|
||||
case Keys.type_stalemate:
|
||||
guard let raw = dictionary[Keys.color] as? String, let color = Color(rawValue: raw) else {
|
||||
return nil
|
||||
}
|
||||
self = .staleMate(color: color)
|
||||
case Keys.type_won:
|
||||
guard let raw = dictionary[Keys.color] as? String, let color = Color(rawValue: raw) else {
|
||||
return nil
|
||||
}
|
||||
self = .won(color: color)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
|
||||
switch self {
|
||||
case .inProgress:
|
||||
dictionary[Keys.type] = Keys.type_inProgress
|
||||
case .staleMate(let color):
|
||||
dictionary[Keys.type] = Keys.type_stalemate
|
||||
dictionary[Keys.color] = color.rawValue
|
||||
case .won(let color):
|
||||
dictionary[Keys.type] = Keys.type_won
|
||||
dictionary[Keys.color] = color.rawValue
|
||||
}
|
||||
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
extension Game: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let state = "state"
|
||||
static let board = "board"
|
||||
static let whitePlayerType = "whitePlayerType"
|
||||
static let blackPlayerType = "blackPlayerType"
|
||||
static let playerType_human = "playerType_human"
|
||||
static let playerType_ai = "playerType_ai"
|
||||
static let whitePlayer = "PlayerOne"
|
||||
static let blackPlayer = "PlayerTwo"
|
||||
static let currentPlayerColor = "currentPlayerColor"
|
||||
}
|
||||
|
||||
public convenience init?(dictionary: [String: Any]) {
|
||||
|
||||
// State
|
||||
guard let stateDict = dictionary[Keys.state] as? [String: Any],
|
||||
let state = State(dictionary: stateDict),
|
||||
let boardDict = dictionary[Keys.board] as? [String: Any],
|
||||
let board = Board(dictionary: boardDict),
|
||||
let currentPlayerColorRaw = dictionary[Keys.currentPlayerColor] as? String,
|
||||
let currentPlayerColor = Color(rawValue: currentPlayerColorRaw)
|
||||
else {
|
||||
print("Unable to recreate game, missing values")
|
||||
return nil
|
||||
}
|
||||
|
||||
func makePlayer(type: String, dictionary: [String: Any]) -> Player? {
|
||||
|
||||
switch type {
|
||||
case Keys.playerType_human:
|
||||
return Human(dictionary: dictionary)
|
||||
case Keys.playerType_ai:
|
||||
return AIPlayer(dictionary: dictionary)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// White Player
|
||||
guard let whitePlayerType = dictionary[Keys.whitePlayerType] as? String,
|
||||
let whitePlayerDict = dictionary[Keys.whitePlayer] as? [String: Any],
|
||||
let whitePlayer = makePlayer(type: whitePlayerType, dictionary: whitePlayerDict) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Black Player
|
||||
guard let blackPlayerType = dictionary[Keys.blackPlayerType] as? String,
|
||||
let blackPlayerDict = dictionary[Keys.blackPlayer] as? [String: Any],
|
||||
let blackPlayer = makePlayer(type: blackPlayerType, dictionary: blackPlayerDict) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.init(firstPlayer: whitePlayer,
|
||||
secondPlayer: blackPlayer,
|
||||
board: board,
|
||||
colorToMove: currentPlayerColor)
|
||||
self.state = state
|
||||
}
|
||||
|
||||
public var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
dictionary[Keys.state] = state.dictionaryRepresentation
|
||||
dictionary[Keys.board] = board.dictionaryRepresentation
|
||||
|
||||
// White Player
|
||||
if let whiteHuman = self.whitePlayer as? Human {
|
||||
dictionary[Keys.whitePlayerType] = Keys.playerType_human
|
||||
dictionary[Keys.whitePlayer] = whiteHuman.dictionaryRepresentation
|
||||
} else if let whiteAI = self.whitePlayer as? AIPlayer {
|
||||
dictionary[Keys.whitePlayerType] = Keys.playerType_ai
|
||||
dictionary[Keys.whitePlayer] = whiteAI.dictionaryRepresentation
|
||||
} else {
|
||||
fatalError("Cannot determine white player type")
|
||||
}
|
||||
|
||||
// Black Player
|
||||
if let blackHuman = self.blackPlayer as? Human {
|
||||
dictionary[Keys.blackPlayerType] = Keys.playerType_human
|
||||
dictionary[Keys.blackPlayer] = blackHuman.dictionaryRepresentation
|
||||
} else if let blackAI = self.blackPlayer as? AIPlayer {
|
||||
dictionary[Keys.blackPlayerType] = Keys.playerType_ai
|
||||
dictionary[Keys.blackPlayer] = blackAI.dictionaryRepresentation
|
||||
} else {
|
||||
fatalError("Cannot determine black player type")
|
||||
}
|
||||
|
||||
dictionary[Keys.currentPlayerColor] = currentPlayer.color.rawValue
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
extension Game: Equatable {
|
||||
public static func == (lhs: Game, rhs: Game) -> Bool {
|
||||
|
||||
func arePlayersEqual(p1: Player, p2: Player) -> Bool {
|
||||
|
||||
if let h1 = p1 as? Human, let h2 = p2 as? Human {
|
||||
return h1 == h2
|
||||
} else if let ai1 = p1 as? AIPlayer, let ai2 = p2 as? AIPlayer {
|
||||
return ai1 == ai2
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if arePlayersEqual(p1: lhs.whitePlayer, p2: rhs.whitePlayer)
|
||||
&& arePlayersEqual(p1: lhs.blackPlayer, p2: rhs.blackPlayer)
|
||||
&& arePlayersEqual(p1: lhs.currentPlayer, p2: rhs.currentPlayer)
|
||||
&& lhs.board == rhs.board
|
||||
&& lhs.state == rhs.state {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - GameDelegate
|
||||
public protocol GameDelegate: class {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
open class Human: Player {
|
||||
public final class Human: Player {
|
||||
|
||||
public init(color: Color) {
|
||||
super.init()
|
||||
@@ -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)
|
||||
@@ -93,3 +94,32 @@ open class Human: Player {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Human: Equatable {
|
||||
public static func == (lhs: Human, rhs: Human) -> Bool {
|
||||
return lhs.color == rhs.color
|
||||
}
|
||||
}
|
||||
|
||||
extension Human: DictionaryRepresentable {
|
||||
|
||||
struct Keys {
|
||||
static let color = "color"
|
||||
}
|
||||
|
||||
convenience init?(dictionary: [String: Any]) {
|
||||
|
||||
if let raw = dictionary[Keys.color] as? String, let color = Color(rawValue: raw) {
|
||||
self.init(color: color)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
dictionary[Keys.color] = color.rawValue
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,30 +51,22 @@ 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()
|
||||
|
||||
}
|
||||
|
||||
// Filter for color
|
||||
return moves.enumerated().flatMap { (index, value) in
|
||||
return moves.enumerated().compactMap { (index, value) in
|
||||
index % 2 == (color == .white ? 0 : 1) ? value : nil
|
||||
}
|
||||
}
|
||||
/*
|
||||
public func moveLocations(forColor color: Color) -> [(fromLocation: BoardLocation, toLocation: BoardLocation)] {
|
||||
|
||||
return moveLocations().enumerated().flatMap{ (index, value) in
|
||||
index % 2 == (color == .white ? 0 : 1) ? value : nil
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func moveLocations() -> [(fromLocation: BoardLocation, toLocation: BoardLocation)] {
|
||||
|
||||
return moveGridPositions().map {
|
||||
|
||||
+112
-39
@@ -8,27 +8,25 @@
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
public struct Piece: Equatable {
|
||||
|
||||
static private var lastAssignedTag = 0
|
||||
|
||||
public enum PieceType: Int {
|
||||
case pawn
|
||||
case rook
|
||||
@@ -37,6 +35,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,41 +53,28 @@ 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)
|
||||
}
|
||||
|
||||
public init(type: PieceType, color: Color) {
|
||||
self.type = type
|
||||
self.color = color
|
||||
|
||||
// assign the next tag
|
||||
Piece.lastAssignedTag += 1
|
||||
self.tag = Piece.lastAssignedTag
|
||||
return PieceMovement.pieceMovement(for: self.type)
|
||||
}
|
||||
|
||||
public init(type: PieceType, color: Color, tag: Int) {
|
||||
var withOppositeColor: Piece {
|
||||
return Piece(type: type, color: color.opposite)
|
||||
}
|
||||
|
||||
var value: Double {
|
||||
return type.value
|
||||
}
|
||||
|
||||
public init(type: PieceType, color: Color, tag: Int = 0) {
|
||||
self.type = type
|
||||
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 {
|
||||
|
||||
@@ -86,16 +82,93 @@ public struct Piece: Equatable {
|
||||
return piece
|
||||
}
|
||||
|
||||
func withOppositeColor() -> Piece {
|
||||
return Piece(type: type, color: color.opposite())
|
||||
func isSameTypeAndColor(asPiece other: Piece) -> Bool {
|
||||
|
||||
if self.type == other.type && self.color == other.color {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func == (left: Piece, right: Piece) -> Bool {
|
||||
|
||||
if left.type == right.type && left.color == right.color {
|
||||
if left.type == right.type
|
||||
&& left.color == right.color
|
||||
&& left.tag == right.tag
|
||||
&& left .hasMoved == right.hasMoved
|
||||
&& left.canBeTakenByEnPassant == right.canBeTakenByEnPassant
|
||||
&& left.location == right.location {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
extension Piece: DictionaryRepresentable {
|
||||
|
||||
private struct Keys {
|
||||
static let type = "type"
|
||||
static let color = "color"
|
||||
static let tag = "tag"
|
||||
static let hasMoved = "hasMoved"
|
||||
static let canBeTakenByEnPassant = "canBeTakenByEnPassant"
|
||||
static let location = "location"
|
||||
}
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
|
||||
// Type
|
||||
if let raw = dictionary[Keys.type] as? Int, let type = PieceType(rawValue: raw) {
|
||||
self.type = type
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Color
|
||||
if let raw = dictionary[Keys.color] as? String, let color = Color(rawValue: raw) {
|
||||
self.color = color
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tag
|
||||
if let tag = dictionary[Keys.tag] as? Int {
|
||||
self.tag = tag
|
||||
}
|
||||
|
||||
// Has Moved
|
||||
if let hasMoved = dictionary[Keys.hasMoved] as? Bool {
|
||||
self.hasMoved = hasMoved
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Can be taken by en passent
|
||||
if let canBeTakenByEnPassent = dictionary[Keys.canBeTakenByEnPassant] as? Bool {
|
||||
self.canBeTakenByEnPassant = canBeTakenByEnPassent
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Location
|
||||
if let dict = dictionary[Keys.location] as? [String: Any], let location = BoardLocation(dictionary: dict) {
|
||||
self.location = location
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var dictionaryRepresentation: [String: Any] {
|
||||
|
||||
var dictionary = [String: Any]()
|
||||
dictionary[Keys.type] = type.rawValue
|
||||
dictionary[Keys.color] = color.rawValue
|
||||
if let tag = self.tag { dictionary[Keys.tag] = tag }
|
||||
dictionary[Keys.hasMoved] = hasMoved
|
||||
dictionary[Keys.canBeTakenByEnPassant] = canBeTakenByEnPassant
|
||||
dictionary[Keys.location] = location.dictionaryRepresentation
|
||||
return dictionary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,31 @@
|
||||
671989831DEB11900053EA3D /* BoardRaterCenterOwnership.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671989821DEB11900053EA3D /* BoardRaterCenterOwnership.swift */; };
|
||||
6719898B1DFFE0D80053EA3D /* BoardRaterBoardDominance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6719898A1DFFE0D80053EA3D /* BoardRaterBoardDominance.swift */; };
|
||||
6719898F1DFFE7550053EA3D /* BoardRaterCenterDominance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6719898E1DFFE7550053EA3D /* BoardRaterCenterDominance.swift */; };
|
||||
673596B922A1B43A003086FF /* AIPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596AD22A1B43A003086FF /* AIPlayerTests.swift */; };
|
||||
673596BA22A1B43A003086FF /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596AE22A1B43A003086FF /* PerformanceTests.swift */; };
|
||||
673596BB22A1B43A003086FF /* AIBehaviourTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596AF22A1B43A003086FF /* AIBehaviourTests.swift */; };
|
||||
673596BC22A1B43A003086FF /* GameTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B022A1B43A003086FF /* GameTests.swift */; };
|
||||
673596BD22A1B43A003086FF /* BoardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B122A1B43A003086FF /* BoardTests.swift */; };
|
||||
673596BE22A1B43A003086FF /* OpeningsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B222A1B43A003086FF /* OpeningsTests.swift */; };
|
||||
673596BF22A1B43A003086FF /* PieceMovementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B322A1B43A003086FF /* PieceMovementTests.swift */; };
|
||||
673596C022A1B43A003086FF /* BoardLocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B422A1B43A003086FF /* BoardLocationTests.swift */; };
|
||||
673596C122A1B43A003086FF /* PlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B522A1B43A003086FF /* PlayerTests.swift */; };
|
||||
673596C222A1B43A003086FF /* PieceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B622A1B43A003086FF /* PieceTests.swift */; };
|
||||
673596C322A1B43A003086FF /* AIConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B722A1B43A003086FF /* AIConfigurationTests.swift */; };
|
||||
673596C422A1B43A003086FF /* SquareTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596B822A1B43A003086FF /* SquareTests.swift */; };
|
||||
673596C822A1B448003086FF /* DictionaryRepresentableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596C622A1B448003086FF /* DictionaryRepresentableExtensions.swift */; };
|
||||
673596C922A1B448003086FF /* BoardScenarios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596C722A1B448003086FF /* BoardScenarios.swift */; };
|
||||
673596D422A1B45A003086FF /* BoardRaterCountPiecesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596CB22A1B459003086FF /* BoardRaterCountPiecesTests.swift */; };
|
||||
673596D522A1B45A003086FF /* BoardRaterCheckMateOpportunityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596CC22A1B459003086FF /* BoardRaterCheckMateOpportunityTests.swift */; };
|
||||
673596D622A1B45A003086FF /* BoardRaterCenterDominanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596CD22A1B459003086FF /* BoardRaterCenterDominanceTests.swift */; };
|
||||
673596D722A1B45A003086FF /* BoardRaterCenterOwnershipTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596CE22A1B459003086FF /* BoardRaterCenterOwnershipTests.swift */; };
|
||||
673596D822A1B45A003086FF /* BoardRaterKingSurroundingPossession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596CF22A1B459003086FF /* BoardRaterKingSurroundingPossession.swift */; };
|
||||
673596D922A1B45A003086FF /* BoardRaterCenterFourOccupationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596D022A1B459003086FF /* BoardRaterCenterFourOccupationTests.swift */; };
|
||||
673596DA22A1B45A003086FF /* BoardRaterBoardDominanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596D122A1B45A003086FF /* BoardRaterBoardDominanceTests.swift */; };
|
||||
673596DB22A1B45A003086FF /* BoardRaterThreatenedPiecesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596D222A1B45A003086FF /* BoardRaterThreatenedPiecesTests.swift */; };
|
||||
673596DC22A1B45A003086FF /* BoardRaterPawnProgressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673596D322A1B45A003086FF /* BoardRaterPawnProgressionTests.swift */; };
|
||||
676EF7C31E15A8A500E275B4 /* BoardRaterKingSurroundingPossession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676EF7C21E15A8A500E275B4 /* BoardRaterKingSurroundingPossession.swift */; };
|
||||
677BE817200A2D78004B27DB /* DictionaryRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 677BE816200A2D78004B27DB /* DictionaryRepresentable.swift */; };
|
||||
67A9C9E81DE64CD300510FB8 /* SwiftChess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67A9C9DE1DE64CD200510FB8 /* SwiftChess.framework */; };
|
||||
67A9C9EF1DE64CD300510FB8 /* SwiftChess.h in Headers */ = {isa = PBXBuildFile; fileRef = 67A9C9E11DE64CD200510FB8 /* SwiftChess.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
67A9CA011DE64D2500510FB8 /* AIPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A9C9FA1DE64D2500510FB8 /* AIPlayer.swift */; };
|
||||
@@ -49,7 +73,31 @@
|
||||
671989821DEB11900053EA3D /* BoardRaterCenterOwnership.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterOwnership.swift; sourceTree = "<group>"; };
|
||||
6719898A1DFFE0D80053EA3D /* BoardRaterBoardDominance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterBoardDominance.swift; sourceTree = "<group>"; };
|
||||
6719898E1DFFE7550053EA3D /* BoardRaterCenterDominance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterDominance.swift; sourceTree = "<group>"; };
|
||||
673596AD22A1B43A003086FF /* AIPlayerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AIPlayerTests.swift; sourceTree = "<group>"; };
|
||||
673596AE22A1B43A003086FF /* PerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PerformanceTests.swift; sourceTree = "<group>"; };
|
||||
673596AF22A1B43A003086FF /* AIBehaviourTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AIBehaviourTests.swift; sourceTree = "<group>"; };
|
||||
673596B022A1B43A003086FF /* GameTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameTests.swift; sourceTree = "<group>"; };
|
||||
673596B122A1B43A003086FF /* BoardTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardTests.swift; sourceTree = "<group>"; };
|
||||
673596B222A1B43A003086FF /* OpeningsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpeningsTests.swift; sourceTree = "<group>"; };
|
||||
673596B322A1B43A003086FF /* PieceMovementTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PieceMovementTests.swift; sourceTree = "<group>"; };
|
||||
673596B422A1B43A003086FF /* BoardLocationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardLocationTests.swift; sourceTree = "<group>"; };
|
||||
673596B522A1B43A003086FF /* PlayerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerTests.swift; sourceTree = "<group>"; };
|
||||
673596B622A1B43A003086FF /* PieceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PieceTests.swift; sourceTree = "<group>"; };
|
||||
673596B722A1B43A003086FF /* AIConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AIConfigurationTests.swift; sourceTree = "<group>"; };
|
||||
673596B822A1B43A003086FF /* SquareTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SquareTests.swift; sourceTree = "<group>"; };
|
||||
673596C622A1B448003086FF /* DictionaryRepresentableExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryRepresentableExtensions.swift; sourceTree = "<group>"; };
|
||||
673596C722A1B448003086FF /* BoardScenarios.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardScenarios.swift; sourceTree = "<group>"; };
|
||||
673596CB22A1B459003086FF /* BoardRaterCountPiecesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCountPiecesTests.swift; sourceTree = "<group>"; };
|
||||
673596CC22A1B459003086FF /* BoardRaterCheckMateOpportunityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCheckMateOpportunityTests.swift; sourceTree = "<group>"; };
|
||||
673596CD22A1B459003086FF /* BoardRaterCenterDominanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterDominanceTests.swift; sourceTree = "<group>"; };
|
||||
673596CE22A1B459003086FF /* BoardRaterCenterOwnershipTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterOwnershipTests.swift; sourceTree = "<group>"; };
|
||||
673596CF22A1B459003086FF /* BoardRaterKingSurroundingPossession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterKingSurroundingPossession.swift; sourceTree = "<group>"; };
|
||||
673596D022A1B459003086FF /* BoardRaterCenterFourOccupationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterCenterFourOccupationTests.swift; sourceTree = "<group>"; };
|
||||
673596D122A1B45A003086FF /* BoardRaterBoardDominanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterBoardDominanceTests.swift; sourceTree = "<group>"; };
|
||||
673596D222A1B45A003086FF /* BoardRaterThreatenedPiecesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterThreatenedPiecesTests.swift; sourceTree = "<group>"; };
|
||||
673596D322A1B45A003086FF /* BoardRaterPawnProgressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterPawnProgressionTests.swift; sourceTree = "<group>"; };
|
||||
676EF7C21E15A8A500E275B4 /* BoardRaterKingSurroundingPossession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoardRaterKingSurroundingPossession.swift; sourceTree = "<group>"; };
|
||||
677BE816200A2D78004B27DB /* DictionaryRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryRepresentable.swift; sourceTree = "<group>"; };
|
||||
67A9C9DE1DE64CD200510FB8 /* SwiftChess.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftChess.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
67A9C9E11DE64CD200510FB8 /* SwiftChess.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftChess.h; sourceTree = "<group>"; };
|
||||
67A9C9E21DE64CD200510FB8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@@ -92,6 +140,39 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
673596C522A1B43E003086FF /* Supporting */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
673596C722A1B448003086FF /* BoardScenarios.swift */,
|
||||
673596C622A1B448003086FF /* DictionaryRepresentableExtensions.swift */,
|
||||
);
|
||||
path = Supporting;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
673596CA22A1B44B003086FF /* Board Raters */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
673596D122A1B45A003086FF /* BoardRaterBoardDominanceTests.swift */,
|
||||
673596CD22A1B459003086FF /* BoardRaterCenterDominanceTests.swift */,
|
||||
673596D022A1B459003086FF /* BoardRaterCenterFourOccupationTests.swift */,
|
||||
673596CE22A1B459003086FF /* BoardRaterCenterOwnershipTests.swift */,
|
||||
673596CC22A1B459003086FF /* BoardRaterCheckMateOpportunityTests.swift */,
|
||||
673596CB22A1B459003086FF /* BoardRaterCountPiecesTests.swift */,
|
||||
673596CF22A1B459003086FF /* BoardRaterKingSurroundingPossession.swift */,
|
||||
673596D322A1B45A003086FF /* BoardRaterPawnProgressionTests.swift */,
|
||||
673596D222A1B45A003086FF /* BoardRaterThreatenedPiecesTests.swift */,
|
||||
);
|
||||
path = "Board Raters";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
677BE815200A2D54004B27DB /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
677BE816200A2D78004B27DB /* DictionaryRepresentable.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
67A9C9D41DE64CD200510FB8 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -123,6 +204,20 @@
|
||||
67A9C9EB1DE64CD300510FB8 /* SwiftChessTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
673596C522A1B43E003086FF /* Supporting */,
|
||||
673596CA22A1B44B003086FF /* Board Raters */,
|
||||
673596AF22A1B43A003086FF /* AIBehaviourTests.swift */,
|
||||
673596B722A1B43A003086FF /* AIConfigurationTests.swift */,
|
||||
673596AD22A1B43A003086FF /* AIPlayerTests.swift */,
|
||||
673596B422A1B43A003086FF /* BoardLocationTests.swift */,
|
||||
673596B122A1B43A003086FF /* BoardTests.swift */,
|
||||
673596B022A1B43A003086FF /* GameTests.swift */,
|
||||
673596B222A1B43A003086FF /* OpeningsTests.swift */,
|
||||
673596AE22A1B43A003086FF /* PerformanceTests.swift */,
|
||||
673596B322A1B43A003086FF /* PieceMovementTests.swift */,
|
||||
673596B622A1B43A003086FF /* PieceTests.swift */,
|
||||
673596B522A1B43A003086FF /* PlayerTests.swift */,
|
||||
673596B822A1B43A003086FF /* SquareTests.swift */,
|
||||
67A9C9EE1DE64CD300510FB8 /* Info.plist */,
|
||||
);
|
||||
path = SwiftChessTests;
|
||||
@@ -131,6 +226,7 @@
|
||||
67A9C9F81DE64D2500510FB8 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
677BE815200A2D54004B27DB /* Extensions */,
|
||||
67F9DB791E2438EC00C7EC5A /* ASCIIBoard.swift */,
|
||||
67FD86881E4105B80023335C /* BoardStride.swift */,
|
||||
67FD868A1E4105D40023335C /* BoardLocation.swift */,
|
||||
@@ -247,27 +343,28 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0800;
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 1200;
|
||||
ORGANIZATIONNAME = "Steve Barnegren";
|
||||
TargetAttributes = {
|
||||
67A9C9DD1DE64CD200510FB8 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
LastSwiftMigration = 0900;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
67A9C9E61DE64CD300510FB8 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
LastSwiftMigration = 0900;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 67A9C9D81DE64CD200510FB8 /* Build configuration list for PBXProject "SwiftChess" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 67A9C9D41DE64CD200510FB8;
|
||||
productRefGroup = 67A9C9DF1DE64CD200510FB8 /* Products */;
|
||||
@@ -341,6 +438,7 @@
|
||||
67F779241E1C326D00885B89 /* BoardRaterCenterFourOccupation.swift in Sources */,
|
||||
67A9CA011DE64D2500510FB8 /* AIPlayer.swift in Sources */,
|
||||
6719898F1DFFE7550053EA3D /* BoardRaterCenterDominance.swift in Sources */,
|
||||
677BE817200A2D78004B27DB /* DictionaryRepresentable.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -348,6 +446,29 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
673596D622A1B45A003086FF /* BoardRaterCenterDominanceTests.swift in Sources */,
|
||||
673596C422A1B43A003086FF /* SquareTests.swift in Sources */,
|
||||
673596DB22A1B45A003086FF /* BoardRaterThreatenedPiecesTests.swift in Sources */,
|
||||
673596C222A1B43A003086FF /* PieceTests.swift in Sources */,
|
||||
673596BA22A1B43A003086FF /* PerformanceTests.swift in Sources */,
|
||||
673596BF22A1B43A003086FF /* PieceMovementTests.swift in Sources */,
|
||||
673596D822A1B45A003086FF /* BoardRaterKingSurroundingPossession.swift in Sources */,
|
||||
673596BD22A1B43A003086FF /* BoardTests.swift in Sources */,
|
||||
673596D922A1B45A003086FF /* BoardRaterCenterFourOccupationTests.swift in Sources */,
|
||||
673596DC22A1B45A003086FF /* BoardRaterPawnProgressionTests.swift in Sources */,
|
||||
673596BB22A1B43A003086FF /* AIBehaviourTests.swift in Sources */,
|
||||
673596C822A1B448003086FF /* DictionaryRepresentableExtensions.swift in Sources */,
|
||||
673596C122A1B43A003086FF /* PlayerTests.swift in Sources */,
|
||||
673596B922A1B43A003086FF /* AIPlayerTests.swift in Sources */,
|
||||
673596C322A1B43A003086FF /* AIConfigurationTests.swift in Sources */,
|
||||
673596BE22A1B43A003086FF /* OpeningsTests.swift in Sources */,
|
||||
673596D422A1B45A003086FF /* BoardRaterCountPiecesTests.swift in Sources */,
|
||||
673596BC22A1B43A003086FF /* GameTests.swift in Sources */,
|
||||
673596C922A1B448003086FF /* BoardScenarios.swift in Sources */,
|
||||
673596C022A1B43A003086FF /* BoardLocationTests.swift in Sources */,
|
||||
673596DA22A1B45A003086FF /* BoardRaterBoardDominanceTests.swift in Sources */,
|
||||
673596D722A1B45A003086FF /* BoardRaterCenterOwnershipTests.swift in Sources */,
|
||||
673596D522A1B45A003086FF /* BoardRaterCheckMateOpportunityTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -366,6 +487,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@@ -375,6 +497,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -382,8 +505,10 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -410,7 +535,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -426,6 +551,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@@ -435,6 +561,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -442,8 +569,10 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -464,7 +593,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
@@ -485,12 +614,13 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = SwiftChess/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 1.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChess;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -504,12 +634,13 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = SwiftChess/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 1.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChess;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -517,12 +648,13 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
INFOPLIST_FILE = SwiftChessTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChessTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -530,12 +662,12 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
INFOPLIST_FILE = SwiftChessTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = SteveBarnegren.SwiftChessTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
+99
-41
@@ -6,6 +6,8 @@
|
||||
// Copyright © 2017 CocoaPods. All rights reserved.
|
||||
//
|
||||
|
||||
//swiftlint:disable type_body_length
|
||||
|
||||
import XCTest
|
||||
@testable import SwiftChess
|
||||
|
||||
@@ -35,14 +37,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"R K B Q G B K R" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterCountPiecesWeighting = 1
|
||||
lowValueConfig.boardRaterCountPiecesWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterCountPiecesWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
@@ -61,14 +67,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"R K B Q G B K R" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterBoardDominanceWeighting = 1
|
||||
lowValueConfig.boardRaterBoardDominanceWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterBoardDominanceWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
@@ -87,14 +97,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"R K B Q G B K R" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterCenterOwnershipWeighting = 1
|
||||
lowValueConfig.boardRaterCenterOwnershipWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterCenterOwnershipWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
@@ -113,14 +127,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"R K B Q G B K R" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterCenterDominanceWeighting = 1
|
||||
lowValueConfig.boardRaterCenterDominanceWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterCenterDominanceWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
@@ -140,19 +158,23 @@ class AIConfigurationTests: XCTestCase {
|
||||
"- - - - G - - B" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterThreatenedPiecesWeighting = 1
|
||||
lowValueConfig.boardRaterThreatenedPiecesWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterThreatenedPiecesWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
|
||||
func testBoardRaterThreatenedPiecesOwnPiecesMultiplierAffectsRating() {
|
||||
func testBoardRaterThreatenedPiecesOwnPiecesWeightingAffectsRating() {
|
||||
|
||||
// White and black rook are threatening each other, so advantage is neutral
|
||||
let board = ASCIIBoard(pieces: "- - - - g - - -" +
|
||||
@@ -165,14 +187,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"- - - - G - - -" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterThreatenedPiecesOwnPiecesMultiplier = 1
|
||||
lowValueConfig.boardRaterThreatenedPiecesWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterThreatenedPiecesWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
@@ -192,14 +218,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"- - - - G - - -" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterPawnProgressionWeighting = 1
|
||||
lowValueConfig.boardRaterPawnProgressionWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterPawnProgressionWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
@@ -218,14 +248,20 @@ class AIConfigurationTests: XCTestCase {
|
||||
"- - - P G P - -" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterKingSurroundingPossessionWeighting = 1
|
||||
lowValueConfig.boardRaterKingSurroundingPossessionWeighting =
|
||||
AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 10)
|
||||
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
|
||||
highValueConfig.boardRaterKingSurroundingPossessionWeighting =
|
||||
AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 10)
|
||||
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)
|
||||
}
|
||||
@@ -245,14 +281,18 @@ class AIConfigurationTests: XCTestCase {
|
||||
"R - - P G P - -" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterCheckMateOpportunityWeighting = 1
|
||||
lowValueConfig.boardRaterCheckMateOpportunityWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 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
|
||||
highValueConfig.boardRaterCheckMateOpportunityWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 1)
|
||||
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)
|
||||
|
||||
@@ -272,15 +312,33 @@ class AIConfigurationTests: XCTestCase {
|
||||
"- - - P G P - -" )
|
||||
|
||||
var lowValueConfig = AIConfiguration()
|
||||
lowValueConfig.boardRaterCenterFourOccupationWeighting = 1
|
||||
lowValueConfig.boardRaterCenterFourOccupationWeighting = AIConfiguration.ConfigurationValue(easyValue: 1,
|
||||
difficultValue: 1,
|
||||
multiplier: 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
|
||||
highValueConfig.boardRaterCenterFourOccupationWeighting = AIConfiguration.ConfigurationValue(easyValue: 2,
|
||||
difficultValue: 2,
|
||||
multiplier: 1)
|
||||
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)
|
||||
}
|
||||
|
||||
// MARK: - AIConfiguration Dictionary Representable
|
||||
|
||||
func testDictionaryRepresentable() {
|
||||
|
||||
let easy = AIConfiguration(difficulty: .easy)
|
||||
XCTAssertEqual(easy, easy.toDictionaryAndBack)
|
||||
|
||||
let medium = AIConfiguration(difficulty: .medium)
|
||||
XCTAssertEqual(medium, medium.toDictionaryAndBack)
|
||||
|
||||
let hard = AIConfiguration(difficulty: .hard)
|
||||
XCTAssertEqual(hard, hard.toDictionaryAndBack)
|
||||
}
|
||||
}
|
||||
@@ -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,19 @@ class AIPlayerTests: XCTestCase {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
XCTAssertFalse(player.canAIMovePiece(fromLocation: bishopLocation, toLocation: testLocation))
|
||||
XCTAssertFalse(player.canAIMovePiece(from: bishopLocation, to: testLocation))
|
||||
}
|
||||
|
||||
// MARK: - Dictionary Representable
|
||||
|
||||
func testDictionaryRepresentable() {
|
||||
|
||||
let whiteEasy = AIPlayer(color: .white,
|
||||
configuration: AIConfiguration(difficulty: .easy))
|
||||
XCTAssertEqual(whiteEasy, whiteEasy.toDictionaryAndBack)
|
||||
|
||||
let blackHard = AIPlayer(color: .black,
|
||||
configuration: AIConfiguration(difficulty: .hard))
|
||||
XCTAssertEqual(blackHard, blackHard.toDictionaryAndBack)
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -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)
|
||||
}
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
+6
-6
@@ -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)
|
||||
}
|
||||
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
+6
-6
@@ -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)
|
||||
}
|
||||
+7
-7
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -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)
|
||||
}
|
||||
|
||||
+10
-10
@@ -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)
|
||||
}
|
||||
+13
-13
@@ -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)
|
||||
}
|
||||
+10
-3
@@ -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 {
|
||||
@@ -182,5 +182,12 @@ class BoardLocationTests: XCTestCase {
|
||||
XCTAssertFalse($0.isDarkSquare, "Expected \($0) to be light")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Dictionary Representable
|
||||
|
||||
func testDictionaryRepresentable() {
|
||||
|
||||
let location = BoardLocation(index: 14)
|
||||
XCTAssertEqual(location, location.toDictionaryAndBack)
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ class BoardTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssert(returnedPiece == piece, "Expected pieces to be the same")
|
||||
XCTAssert(returnedPiece.isSameTypeAndColor(asPiece: piece), "Expected pieces to be the same")
|
||||
|
||||
}
|
||||
|
||||
@@ -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,14 +164,14 @@ 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")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssert(returnedPiece == piece, "Expected pieces to be the same")
|
||||
XCTAssert(returnedPiece.isSameTypeAndColor(asPiece: piece), "Expected pieces to be the same")
|
||||
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
@@ -233,7 +233,7 @@ class BoardTests: XCTestCase {
|
||||
func verifyPieceExistance(piece: Piece) {
|
||||
|
||||
let matchingPieces = pieces.filter {
|
||||
return $0 == piece
|
||||
return $0.isSameTypeAndColor(asPiece: piece)
|
||||
}
|
||||
|
||||
XCTAssert(matchingPieces.count != 0,
|
||||
@@ -277,8 +277,8 @@ class BoardTests: XCTestCase {
|
||||
board.setPiece(whiteKing, at: BoardLocation(index: 0))
|
||||
board.setPiece(blackKing, at: BoardLocation(index: 1))
|
||||
|
||||
XCTAssert(board.getKing(color: .white) == whiteKing, "Unable to find white king")
|
||||
XCTAssert(board.getKing(color: .black) == blackKing, "Unable to find black king")
|
||||
XCTAssert(board.getKing(color: .white).isSameTypeAndColor(asPiece: whiteKing), "Unable to find white king")
|
||||
XCTAssert(board.getKing(color: .black).isSameTypeAndColor(asPiece: blackKing), "Unable to find black king")
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1104,5 +1104,22 @@ class BoardTests: XCTestCase {
|
||||
XCTAssertEqual(piece.location, location)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Dictionary Representable
|
||||
|
||||
func testDictionaryRepresentable() {
|
||||
|
||||
let asciiBoard = ASCIIBoard(pieces: "r - - - g - - r" +
|
||||
"p p p p p p p p" +
|
||||
"- - - - - - - -" +
|
||||
"- K - - - b - -" +
|
||||
"- - B - - - k -" +
|
||||
"- - - - - - - -" +
|
||||
"P P P P P P P P" +
|
||||
"R - - - G - - R" )
|
||||
|
||||
let board = asciiBoard.board
|
||||
XCTAssertEqual(board, board.toDictionaryAndBack)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -107,4 +107,45 @@ class GameTests: XCTestCase {
|
||||
XCTAssertTrue(game.state == Game.State.won(color: .black))
|
||||
}
|
||||
|
||||
// MARK: - Game State Dictionary Representable
|
||||
|
||||
func testGameStateDictionaryRepresentable() {
|
||||
|
||||
let inProgress = Game.State.inProgress
|
||||
XCTAssertEqual(inProgress, inProgress.toDictionaryAndBack)
|
||||
|
||||
let whiteStalemate = Game.State.staleMate(color: .white)
|
||||
XCTAssertEqual(whiteStalemate, whiteStalemate.toDictionaryAndBack)
|
||||
|
||||
let blackStalemate = Game.State.staleMate(color: .black)
|
||||
XCTAssertEqual(blackStalemate, blackStalemate.toDictionaryAndBack)
|
||||
|
||||
let whiteWon = Game.State.won(color: .white)
|
||||
XCTAssertEqual(whiteWon, whiteWon.toDictionaryAndBack)
|
||||
|
||||
let blackWon = Game.State.won(color: .black)
|
||||
XCTAssertEqual(blackWon, blackWon.toDictionaryAndBack)
|
||||
}
|
||||
|
||||
// MARK: - Game Dictionary Representable
|
||||
|
||||
func testGameDictionaryRepresentable() {
|
||||
|
||||
do {
|
||||
let whitePlayer = Human(color: .white)
|
||||
let blackPlayer = Human(color: .black)
|
||||
let board = Board(state: .newGame)
|
||||
let game = Game(firstPlayer: whitePlayer, secondPlayer: blackPlayer, board: board, colorToMove: .white)
|
||||
XCTAssertEqual(game, game.toDictionaryAndBack)
|
||||
}
|
||||
|
||||
do {
|
||||
let whitePlayer = Human(color: .white)
|
||||
let blackPlayer = AIPlayer(color: .black, configuration: AIConfiguration(difficulty: .hard))
|
||||
let board = Board(state: .newGame)
|
||||
let game = Game(firstPlayer: whitePlayer, secondPlayer: blackPlayer, board: board, colorToMove: .black)
|
||||
XCTAssertEqual(game, game.toDictionaryAndBack)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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))
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import SwiftChess
|
||||
@testable import SwiftChess
|
||||
|
||||
class PieceTests: XCTestCase {
|
||||
|
||||
@@ -38,4 +38,23 @@ class PieceTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - DictionaryRepresentable
|
||||
|
||||
func testPieceDictionaryRepresentable() {
|
||||
|
||||
var piece1 = Piece(type: .pawn, color: .white)
|
||||
piece1.tag = 0
|
||||
piece1.hasMoved = false
|
||||
piece1.canBeTakenByEnPassant = false
|
||||
piece1.location = BoardLocation(index: 0)
|
||||
XCTAssertEqual(piece1, piece1.toDictionaryAndBack)
|
||||
|
||||
var piece2 = Piece(type: .bishop, color: .black)
|
||||
piece2.tag = 15
|
||||
piece2.hasMoved = true
|
||||
piece2.canBeTakenByEnPassant = true
|
||||
piece2.location = BoardLocation(index: 15)
|
||||
XCTAssertEqual(piece2, piece2.toDictionaryAndBack)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,20 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Human dictionary Representable
|
||||
|
||||
func testHumanDictionaryRepresentable() {
|
||||
|
||||
let whiteHuman = Human(color: .white)
|
||||
XCTAssertEqual(whiteHuman, whiteHuman.toDictionaryAndBack)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// SquareTests.swift
|
||||
// SwiftChessExampleTests
|
||||
//
|
||||
// Created by Steve Barnegren on 13/01/2018.
|
||||
// Copyright © 2018 CocoaPods. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SwiftChess
|
||||
|
||||
class SquareTests: XCTestCase {
|
||||
|
||||
func testDictionaryRepresentable() {
|
||||
|
||||
let piece = Piece(type: .bishop, color: .black)
|
||||
let squareWithPiece = Square(piece: piece)
|
||||
XCTAssertEqual(squareWithPiece, squareWithPiece.toDictionaryAndBack)
|
||||
|
||||
let squareWithoutPiece = Square(piece: nil)
|
||||
XCTAssertEqual(squareWithoutPiece, squareWithoutPiece.toDictionaryAndBack)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// DictionaryRepresentableExtensions.swift
|
||||
// SwiftChessExampleTests
|
||||
//
|
||||
// Created by Steve Barnegren on 13/01/2018.
|
||||
// Copyright © 2018 CocoaPods. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@testable import SwiftChess
|
||||
|
||||
extension DictionaryRepresentable {
|
||||
|
||||
var toDictionaryAndBack: Self? {
|
||||
|
||||
let dictionary = self.dictionaryRepresentation
|
||||
return Self(dictionary: dictionary)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user