├── .gitignore
├── LICENSE
├── Podfile
├── Podfile.lock
├── Pods
├── Local Podspecs
│ └── Sage.podspec.json
├── Manifest.lock
├── Pods.xcodeproj
│ ├── project.pbxproj
│ └── xcuserdata
│ │ └── javiers.xcuserdatad
│ │ └── xcschemes
│ │ ├── Pods-SwiftChessEngine.xcscheme
│ │ ├── Sage.xcscheme
│ │ └── xcschememanagement.plist
├── Sage
│ ├── LICENSE.txt
│ ├── README.md
│ └── Sources
│ │ ├── Bitboard.swift
│ │ ├── Board.swift
│ │ ├── CastlingRights.swift
│ │ ├── Color.swift
│ │ ├── File.swift
│ │ ├── Game.swift
│ │ ├── InternalTypes.swift
│ │ ├── Move.swift
│ │ ├── PGN.swift
│ │ ├── Piece.swift
│ │ ├── Player.swift
│ │ ├── Rank.swift
│ │ ├── Sequence+Sage.swift
│ │ ├── Square.swift
│ │ └── Variant.swift
└── Target Support Files
│ ├── Pods-SwiftChessEngine
│ ├── Info.plist
│ ├── Pods-SwiftChessEngine-acknowledgements.markdown
│ ├── Pods-SwiftChessEngine-acknowledgements.plist
│ ├── Pods-SwiftChessEngine-dummy.m
│ ├── Pods-SwiftChessEngine-frameworks.sh
│ ├── Pods-SwiftChessEngine-resources.sh
│ ├── Pods-SwiftChessEngine-umbrella.h
│ ├── Pods-SwiftChessEngine.debug.xcconfig
│ ├── Pods-SwiftChessEngine.modulemap
│ └── Pods-SwiftChessEngine.release.xcconfig
│ └── Sage
│ ├── Info.plist
│ ├── Sage-dummy.m
│ ├── Sage-prefix.pch
│ ├── Sage-umbrella.h
│ ├── Sage.modulemap
│ └── Sage.xcconfig
├── README.md
├── SwiftChessEngine.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── javiers.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── javiers.xcuserdatad
│ └── xcschemes
│ ├── SwiftChessEngine.xcscheme
│ └── xcschememanagement.plist
├── SwiftChessEngine.xcworkspace
├── contents.xcworkspacedata
└── xcuserdata
│ └── javiers.xcuserdatad
│ ├── UserInterfaceState.xcuserstate
│ └── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
└── SwiftChessEngine
├── AppDelegate.swift
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── ChessEngine
└── ChessEngine.swift
├── Info.plist
└── ViewController.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Javier Soto
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '10.0'
2 | swift_version="3"
3 | use_frameworks!
4 |
5 | target 'SwiftChessEngine' do
6 | pod 'Sage', :git => 'https://github.com/nvzqz/Sage.git', :branch => 'master'
7 | end
8 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Sage (2.0.0)
3 |
4 | DEPENDENCIES:
5 | - Sage (from `https://github.com/nvzqz/Sage.git`, branch `master`)
6 |
7 | EXTERNAL SOURCES:
8 | Sage:
9 | :branch: master
10 | :git: https://github.com/nvzqz/Sage.git
11 |
12 | CHECKOUT OPTIONS:
13 | Sage:
14 | :commit: 3c447476ec73920f46f81fe99b10c1c83127c92a
15 | :git: https://github.com/nvzqz/Sage.git
16 |
17 | SPEC CHECKSUMS:
18 | Sage: 0f22bee8c3b2310a55ffa27c118f6be6a0097edd
19 |
20 | PODFILE CHECKSUM: e4a17ad4bb9f13f1465d8ad370eff75b98e98c7c
21 |
22 | COCOAPODS: 1.1.0.beta.1
23 |
--------------------------------------------------------------------------------
/Pods/Local Podspecs/Sage.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Sage",
3 | "version": "2.0.0",
4 | "summary": "A cross-platform chess library for Swift.",
5 | "homepage": "https://github.com/nvzqz/Sage",
6 | "license": {
7 | "type": "Apache License, Version 2.0",
8 | "file": "LICENSE.txt"
9 | },
10 | "authors": "Nikolai Vazquez",
11 | "platforms": {
12 | "ios": "8.0",
13 | "osx": "10.9",
14 | "watchos": "2.0",
15 | "tvos": "9.0"
16 | },
17 | "source": {
18 | "git": "https://github.com/nvzqz/Sage.git",
19 | "tag": "v2.0.0"
20 | },
21 | "source_files": "Sources/*.swift"
22 | }
23 |
--------------------------------------------------------------------------------
/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Sage (2.0.0)
3 |
4 | DEPENDENCIES:
5 | - Sage (from `https://github.com/nvzqz/Sage.git`, branch `master`)
6 |
7 | EXTERNAL SOURCES:
8 | Sage:
9 | :branch: master
10 | :git: https://github.com/nvzqz/Sage.git
11 |
12 | CHECKOUT OPTIONS:
13 | Sage:
14 | :commit: 3c447476ec73920f46f81fe99b10c1c83127c92a
15 | :git: https://github.com/nvzqz/Sage.git
16 |
17 | SPEC CHECKSUMS:
18 | Sage: 0f22bee8c3b2310a55ffa27c118f6be6a0097edd
19 |
20 | PODFILE CHECKSUM: e4a17ad4bb9f13f1465d8ad370eff75b98e98c7c
21 |
22 | COCOAPODS: 1.1.0.beta.1
23 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/javiers.xcuserdatad/xcschemes/Pods-SwiftChessEngine.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
66 |
67 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/javiers.xcuserdatad/xcschemes/Sage.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/javiers.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Pods-SwiftChessEngine.xcscheme
8 |
9 | isShown
10 |
11 |
12 | Sage.xcscheme
13 |
14 | isShown
15 |
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | C7A03F0B962ACC7E028441A557BE1D1D
21 |
22 | primary
23 |
24 |
25 | CF5459EF9BFDF3B4F2D419EF54DA0910
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Pods/Sage/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/Pods/Sage/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/nvzqz/Sage)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Sage is a cross-platform chess library for Swift.
17 |
18 | - [Features](#features)
19 | - [Installation](#installation)
20 | - [Compatibility](#compatibility)
21 | - [Swift Package Manager](#install-using-swift-package-manager)
22 | - [CocoaPods](#install-using-cocoapods)
23 | - [Carthage](#install-using-carthage)
24 | - [Manually](#install-manually)
25 | - [Usage](#usage)
26 | - [Game Management](#game-management)
27 | - [Move Generation](#move-generation)
28 | - [Move Validation](#move-validation)
29 | - [Undo and Redo Moves](#undo-and-redo-moves)
30 | - [Promotion Handling](#promotion-handling)
31 | - [Pretty Printing](#pretty-printing)
32 | - [Forsyth–Edwards Notation](#forsythedwards-notation)
33 | - [Iterating Through a Board](#iterating-through-a-board)
34 | - [Squares to Moves](#squares-to-moves)
35 | - [Playground Usage](#playground-usage)
36 | - [Board Quick Look](#board-quick-look)
37 | - [License](#license)
38 |
39 | ## Features
40 |
41 | - [x] Chess game management
42 | - [x] Chess board structuring
43 | - [x] Move generation / validation
44 | - [x] En passant and castling
45 | - [x] Pawn promotions
46 | - [x] FEN for games and boards
47 | - [x] PGN parsing and exporting
48 | - [x] [Documentation](https://nvzqz.github.io/Sage/docs/)
49 |
50 | ## Installation
51 |
52 | ### Compatibility
53 |
54 | - Platforms:
55 | - macOS 10.9+
56 | - iOS 8.0+
57 | - watchOS 2.0+
58 | - tvOS 9.0+
59 | - Linux
60 | - Xcode 7.3 and 8.0
61 | - Swift 2.2 and 3.0
62 |
63 | ### Install Using Swift Package Manager
64 | The [Swift Package Manager](https://swift.org/package-manager/) is a
65 | decentralized dependency manager for Swift.
66 |
67 | 1. Add the project to your `Package.swift`.
68 |
69 | ```swift
70 | import PackageDescription
71 |
72 | let package = Package(
73 | name: "MyAwesomeProject",
74 | dependencies: [
75 | .Package(url: "https://github.com/nvzqz/Sage.git",
76 | majorVersion: 1)
77 | ]
78 | )
79 | ```
80 |
81 | 2. Import the Sage module.
82 |
83 | ```swift
84 | import Sage
85 | ```
86 |
87 | ### Install Using CocoaPods
88 | [CocoaPods](https://cocoapods.org/) is a centralized dependency manager for
89 | Objective-C and Swift. Go [here](https://guides.cocoapods.org/using/index.html)
90 | to learn more.
91 |
92 | 1. Add the project to your [Podfile](https://guides.cocoapods.org/using/the-podfile.html).
93 |
94 | ```ruby
95 | use_frameworks!
96 |
97 | pod 'Sage', '~> 2.0.0'
98 | ```
99 |
100 | If you want to be on the bleeding edge, replace the last line with:
101 |
102 | ```ruby
103 | pod 'Sage', :git => 'https://github.com/nvzqz/Sage.git'
104 | ```
105 |
106 | 2. Run `pod install` and open the `.xcworkspace` file to launch Xcode.
107 |
108 | 3. Import the Sage framework.
109 |
110 | ```swift
111 | import Sage
112 | ```
113 |
114 | ### Install Using Carthage
115 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency
116 | manager for Objective-C and Swift.
117 |
118 | 1. Add the project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile).
119 |
120 | ```
121 | github "nvzqz/Sage"
122 | ```
123 |
124 | 2. Run `carthage update` and follow [the additional steps](https://github.com/Carthage/Carthage#getting-started)
125 | in order to add Sage to your project.
126 |
127 | 3. Import the Sage framework.
128 |
129 | ```swift
130 | import Sage
131 | ```
132 |
133 | ### Install Manually
134 |
135 | 1. Download and drop the `/Sources` folder into your project.
136 |
137 | 2. Congratulations!
138 |
139 | ## Usage
140 |
141 | ### Game Management
142 |
143 | Running a chess game can be as simple as setting up a loop.
144 |
145 | ```swift
146 | import Sage
147 |
148 | let game = Game()
149 |
150 | while !game.isFinished {
151 | let move = ...
152 | try game.execute(move: move)
153 | }
154 | ```
155 |
156 | ### Move Generation
157 |
158 | Sage is capable of generating legal moves for the current player with full
159 | support for special moves such as en passant and castling.
160 |
161 | - `availableMoves()` will return all moves currently available.
162 |
163 | - `movesForPiece(at:)` will return all moves for a piece at a square.
164 |
165 | - `movesBitboardForPiece(at:)` will return a `Bitboard` containing all of the
166 | squares a piece at a square can move to.
167 |
168 | ### Move Validation
169 |
170 | Sage can also validate whether a move is legal with the `isLegal(move:)`
171 | method for a `Game` state.
172 |
173 | The `execute(move:)` family of methods calls this method, so it would be faster
174 | to execute the move directly and catch any error from an illegal move.
175 |
176 | ### Undo and Redo Moves
177 |
178 | Move undo and redo operations are done with the `undoMove()` and `redoMove()`
179 | methods. The undone or redone move is returned.
180 |
181 | To just check what moves are to be undone or redone, the `moveToUndo()` and
182 | `moveToRedo()` methods are available.
183 |
184 | ### Promotion Handling
185 |
186 | The `execute(move:promotion:)` method takes a closure that returns a promotion
187 | piece kind. This allows for the app to prompt the user for a promotion piece or
188 | perform any other operations before choosing a promotion piece kind.
189 |
190 | ```swift
191 | try game.execute(move: move) {
192 | ...
193 | return .queen
194 | }
195 | ```
196 |
197 | The closure is only executed if the move is a pawn promotion. An error is thrown
198 | if the promotion piece kind cannot promote a pawn, such as with a king or pawn.
199 |
200 | A piece kind can also be given without a closure. The default is a queen.
201 |
202 | ```swift
203 | try game.execute(move: move, promotion: .queen)
204 | ```
205 |
206 | ### Pretty Printing
207 |
208 | The `Board` and `Bitboard` types both have an `ascii` property that can be used
209 | to print a visual board.
210 |
211 | ```swift
212 | let board = Board()
213 |
214 | print(board.ascii)
215 | // +-----------------+
216 | // 8 | r n b q k b n r |
217 | // 7 | p p p p p p p p |
218 | // 6 | . . . . . . . . |
219 | // 5 | . . . . . . . . |
220 | // 4 | . . . . . . . . |
221 | // 3 | . . . . . . . . |
222 | // 2 | P P P P P P P P |
223 | // 1 | R N B Q K B N R |
224 | // +-----------------+
225 | // a b c d e f g h
226 |
227 | print(board.occupiedSpaces.ascii)
228 | // +-----------------+
229 | // 8 | 1 1 1 1 1 1 1 1 |
230 | // 7 | 1 1 1 1 1 1 1 1 |
231 | // 6 | . . . . . . . . |
232 | // 5 | . . . . . . . . |
233 | // 4 | . . . . . . . . |
234 | // 3 | . . . . . . . . |
235 | // 2 | 1 1 1 1 1 1 1 1 |
236 | // 1 | 1 1 1 1 1 1 1 1 |
237 | // +-----------------+
238 | // a b c d e f g h
239 | ```
240 |
241 | ### Forsyth–Edwards Notation
242 |
243 | The `Game.Position` and `Board` types can both generate a FEN string.
244 |
245 | ```swift
246 | let game = Game()
247 |
248 | print(game.position.fen())
249 | // rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
250 |
251 | print(game.board.fen())
252 | // rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
253 | ```
254 |
255 | They can also be initialized from a FEN string.
256 |
257 | ```swift
258 | assert(Board(fen: game.board.fen()) == game.board)
259 |
260 | assert(Game.Position(fen: game.position.fen()) == game.position)
261 | ```
262 |
263 | ### Iterating Through a Board
264 |
265 | The `Board` type conforms to `Sequence`, making iterating through its spaces
266 | seamless.
267 |
268 | ```swift
269 | for space in Board() {
270 | if let piece = space.piece {
271 | print("\(piece) at \(space.square)")
272 | }
273 | }
274 | ```
275 |
276 | ### Squares to Moves
277 |
278 | `Sequence` and `Square` have two methods that return an array of moves that go
279 | from/to `self` to/from the parameter.
280 |
281 | ```swift
282 | print([.a1, .h3, .b5].moves(from: .b4))
283 | // [b4 >>> a1, b4 >>> h3, b4 >>> b5]
284 |
285 | print([.c3, .d2, .f1].moves(to: .a6))
286 | // [c3 >>> a6, d2 >>> a6, f1 >>> a6]
287 |
288 | print(Square.d4.moves(from: [.c2, .f8, .h2]))
289 | // [c2 >>> d4, f8 >>> d4, h2 >>> d4]
290 |
291 | print(Square.a4.moves(to: [.c3, .d4, .f6]))
292 | // [a4 >>> c3, a4 >>> d4, a4 >>> f6]
293 | ```
294 |
295 | ### Playground Usage
296 |
297 | To use `Sage.playground`, first open `Sage.xcodeproj` and build the OS X target.
298 | You can then use the playground from within the project.
299 |
300 | #### Board Quick Look
301 |
302 | `Board` conforms to the `CustomPlaygroundQuickLookable` protocol.
303 |
304 | 
305 |
306 | ## License
307 |
308 | Sage is published under [version 2.0 of the Apache License](https://www.apache.org/licenses/LICENSE-2.0).
309 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/CastlingRights.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CastlingRights.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// Castling rights of a `Game`.
21 | ///
22 | /// Defines whether a `Color` has the right to castle for a `Board.Side`.
23 | public struct CastlingRights: CustomStringConvertible {
24 |
25 | /// A castling right.
26 | public enum Right: String, CustomStringConvertible {
27 |
28 | #if swift(>=3)
29 |
30 | /// White can castle kingside.
31 | case whiteKingside
32 |
33 | /// White can castle queenside.
34 | case whiteQueenside
35 |
36 | /// Black can castle kingside.
37 | case blackKingside
38 |
39 | /// Black can castle queenside.
40 | case blackQueenside
41 |
42 | /// All rights.
43 | public static let all: [Right] = [.whiteKingside, .whiteQueenside, .blackKingside, .blackQueenside]
44 |
45 | #else
46 |
47 | /// White can castle kingside.
48 | case WhiteKingside
49 |
50 | /// White can castle queenside.
51 | case WhiteQueenside
52 |
53 | /// Black can castle kingside.
54 | case BlackKingside
55 |
56 | /// Black can castle queenside.
57 | case BlackQueenside
58 |
59 | /// All rights.
60 | public static let all: [Right] = [.WhiteKingside, .WhiteQueenside, .BlackKingside, .BlackQueenside]
61 |
62 | #endif
63 |
64 | /// The color for `self`.
65 | public var color: Color {
66 | get {
67 | #if swift(>=3)
68 | switch self {
69 | case .whiteKingside, .whiteQueenside:
70 | return .white
71 | default:
72 | return .black
73 | }
74 | #else
75 | switch self {
76 | case .WhiteKingside, .WhiteQueenside:
77 | return .White
78 | default:
79 | return .Black
80 | }
81 | #endif
82 | }
83 | set {
84 | self = Right(color: newValue, side: side)
85 | }
86 | }
87 |
88 | /// The board side for `self`.
89 | public var side: Board.Side {
90 | get {
91 | #if swift(>=3)
92 | switch self {
93 | case .whiteKingside, .blackKingside:
94 | return .kingside
95 | default:
96 | return .queenside
97 | }
98 | #else
99 | switch self {
100 | case .WhiteKingside, .BlackKingside:
101 | return .Kingside
102 | default:
103 | return .Queenside
104 | }
105 | #endif
106 | }
107 | set {
108 | self = Right(color: color, side: side)
109 | }
110 | }
111 |
112 | /// The squares expected to be empty for a castle.
113 | public var emptySquares: Bitboard {
114 | #if swift(>=3)
115 | switch self {
116 | case .whiteKingside:
117 | return 0b01100000
118 | case .whiteQueenside:
119 | return 0b00001110
120 | case .blackKingside:
121 | return 0b01100000 << 56
122 | case .blackQueenside:
123 | return 0b00001110 << 56
124 | }
125 | #else
126 | switch self {
127 | case .WhiteKingside:
128 | return 0b01100000
129 | case .WhiteQueenside:
130 | return 0b00001110
131 | case .BlackKingside:
132 | return 0b01100000 << 56
133 | case .BlackQueenside:
134 | return 0b00001110 << 56
135 | }
136 | #endif
137 | }
138 |
139 | /// The castle destination square of a king.
140 | public var castleSquare: Square {
141 | #if swift(>=3)
142 | switch self {
143 | case .whiteKingside:
144 | return .g1
145 | case .whiteQueenside:
146 | return .c1
147 | case .blackKingside:
148 | return .g8
149 | case .blackQueenside:
150 | return .c8
151 | }
152 | #else
153 | switch self {
154 | case .WhiteKingside:
155 | return .G1
156 | case .WhiteQueenside:
157 | return .C1
158 | case .BlackKingside:
159 | return .G8
160 | case .BlackQueenside:
161 | return .C8
162 | }
163 | #endif
164 | }
165 |
166 | /// The character for `self`.
167 | public var character: Character {
168 | #if swift(>=3)
169 | switch self {
170 | case .whiteKingside: return "K"
171 | case .whiteQueenside: return "Q"
172 | case .blackKingside: return "k"
173 | case .blackQueenside: return "q"
174 | }
175 | #else
176 | switch self {
177 | case .WhiteKingside: return "K"
178 | case .WhiteQueenside: return "Q"
179 | case .BlackKingside: return "k"
180 | case .BlackQueenside: return "q"
181 | }
182 | #endif
183 | }
184 |
185 | /// A textual representation of `self`.
186 | public var description: String {
187 | return rawValue
188 | }
189 |
190 | private var _bit: Int {
191 | #if swift(>=3)
192 | switch self {
193 | case .whiteKingside: return 0b0001
194 | case .whiteQueenside: return 0b0010
195 | case .blackKingside: return 0b0100
196 | case .blackQueenside: return 0b1000
197 | }
198 | #else
199 | switch self {
200 | case .WhiteKingside: return 0b0001
201 | case .WhiteQueenside: return 0b0010
202 | case .BlackKingside: return 0b0100
203 | case .BlackQueenside: return 0b1000
204 | }
205 | #endif
206 | }
207 |
208 | /// Create a `Right` from `color` and `side`.
209 | public init(color: Color, side: Board.Side) {
210 | #if swift(>=3)
211 | switch (color, side) {
212 | case (.white, .kingside): self = .whiteKingside
213 | case (.white, .queenside): self = .whiteQueenside
214 | case (.black, .kingside): self = .blackKingside
215 | case (.black, .queenside): self = .blackQueenside
216 | }
217 | #else
218 | switch (color, side) {
219 | case (.White, .Kingside): self = .WhiteKingside
220 | case (.White, .Queenside): self = .WhiteQueenside
221 | case (.Black, .Kingside): self = .BlackKingside
222 | case (.Black, .Queenside): self = .BlackQueenside
223 | }
224 | #endif
225 | }
226 |
227 | /// Create a `Right` from a `Character`.
228 | public init?(character: Character) {
229 | #if swift(>=3)
230 | switch character {
231 | case "K": self = .whiteKingside
232 | case "Q": self = .whiteQueenside
233 | case "k": self = .blackKingside
234 | case "q": self = .blackQueenside
235 | default: return nil
236 | }
237 | #else
238 | switch character {
239 | case "K": self = .WhiteKingside
240 | case "Q": self = .WhiteQueenside
241 | case "k": self = .BlackKingside
242 | case "q": self = .BlackQueenside
243 | default: return nil
244 | }
245 | #endif
246 | }
247 |
248 | }
249 |
250 | #if swift(>=3)
251 |
252 | /// An iterator over the members of `CastlingRights`.
253 | public struct Iterator: IteratorProtocol {
254 |
255 | private var _base: SetIterator
256 |
257 | /// Advance to the next element and return it, or `nil` if no next element exists.
258 | public mutating func next() -> Right? {
259 | return _base.next()
260 | }
261 |
262 | }
263 |
264 | #else
265 |
266 | /// A generator over the members of `CastlingRights`.
267 | public struct Generator: GeneratorType {
268 |
269 | private var _base: SetGenerator
270 |
271 | /// Advance to the next element and return it, or `nil` if no next element exists.
272 | public mutating func next() -> Right? {
273 | return _base.next()
274 | }
275 |
276 | }
277 |
278 | #endif
279 |
280 | /// All castling rights.
281 | public static let all = CastlingRights(Right.all)
282 |
283 | /// The rights.
284 | private var _rights: Set
285 |
286 | /// A textual representation of `self`.
287 | public var description: String {
288 | if !_rights.isEmpty {
289 | #if swift(>=3)
290 | return String(_rights.map({ $0.character }).sorted())
291 | #else
292 | return String(_rights.map({ $0.character }).sort())
293 | #endif
294 | } else {
295 | return "-"
296 | }
297 | }
298 |
299 | /// Creates empty rights.
300 | public init() {
301 | _rights = Set()
302 | }
303 |
304 | /// Creates a `CastlingRights` from a `String`.
305 | ///
306 | /// - returns: `nil` if `string` is empty or invalid.
307 | public init?(string: String) {
308 | guard !string.isEmpty else {
309 | return nil
310 | }
311 | if string == "-" {
312 | _rights = Set()
313 | } else {
314 | var rights = Set()
315 | for char in string.characters {
316 | guard let right = Right(character: char) else {
317 | return nil
318 | }
319 | rights.insert(right)
320 | }
321 | _rights = rights
322 | }
323 | }
324 |
325 | #if swift(>=3)
326 |
327 | /// Creates a set of rights from a sequence.
328 | public init(_ sequence: S) {
329 | if let set = sequence as? Set {
330 | _rights = set
331 | } else {
332 | _rights = Set(sequence)
333 | }
334 | }
335 |
336 | #else
337 |
338 | /// Creates a set of rights from a sequence.
339 | public init(_ sequence: S) {
340 | if let set = sequence as? Set {
341 | _rights = set
342 | } else {
343 | _rights = Set(sequence)
344 | }
345 | }
346 |
347 | #endif
348 |
349 | }
350 |
351 | #if swift(>=3)
352 |
353 | extension CastlingRights: Sequence {
354 |
355 | /// Returns an iterator over the members.
356 | public func makeIterator() -> Iterator {
357 | return Iterator(_base: _rights.makeIterator())
358 | }
359 |
360 | }
361 |
362 | extension CastlingRights: SetAlgebra {
363 |
364 | /// A Boolean value that indicates whether the set has no elements.
365 | public var isEmpty: Bool {
366 | return _rights.isEmpty
367 | }
368 |
369 | /// Returns a Boolean value that indicates whether the given element exists
370 | /// in the set.
371 | public func contains(_ member: Right) -> Bool {
372 | return _rights.contains(member)
373 | }
374 |
375 | /// Returns a new set with the elements of both this and the given set.
376 | public func union(_ other: CastlingRights) -> CastlingRights {
377 | return CastlingRights(_rights.union(other._rights))
378 | }
379 |
380 | /// Returns a new set with the elements that are common to both this set and
381 | /// the given set.
382 | public func intersection(_ other: CastlingRights) -> CastlingRights {
383 | return CastlingRights(_rights.intersection(other._rights))
384 | }
385 |
386 | /// Returns a new set with the elements that are either in this set or in the
387 | /// given set, but not in both.
388 | public func symmetricDifference(_ other: CastlingRights) -> CastlingRights {
389 | return CastlingRights(_rights.symmetricDifference(other._rights))
390 | }
391 |
392 | /// Inserts the given element in the set if it is not already present.
393 | @discardableResult
394 | public mutating func insert(_ newMember: Right) -> (inserted: Bool, memberAfterInsert: Right) {
395 | return _rights.insert(newMember)
396 | }
397 |
398 | /// Removes the given element and any elements subsumed by the given element.
399 | @discardableResult
400 | public mutating func remove(_ member: Right) -> Right? {
401 | return _rights.remove(member)
402 | }
403 |
404 | /// Inserts the given element into the set unconditionally.
405 | @discardableResult
406 | public mutating func update(with newMember: Right) -> Right? {
407 | return _rights.update(with: newMember)
408 | }
409 |
410 | /// Adds the elements of the given set to the set.
411 | public mutating func formUnion(_ other: CastlingRights) {
412 | _rights.formUnion(other._rights)
413 | }
414 |
415 | /// Removes the elements of this set that aren't also in the given set.
416 | public mutating func formIntersection(_ other: CastlingRights) {
417 | _rights.formIntersection(other._rights)
418 | }
419 |
420 | /// Removes the elements of the set that are also in the given set and
421 | /// adds the members of the given set that are not already in the set.
422 | public mutating func formSymmetricDifference(_ other: CastlingRights) {
423 | _rights.formSymmetricDifference(other._rights)
424 | }
425 |
426 | /// Returns a new set containing the elements of this set that do not occur
427 | /// in the given set.
428 | public func subtracting(_ other: CastlingRights) -> CastlingRights {
429 | return CastlingRights(_rights.subtracting(other._rights))
430 | }
431 |
432 | /// Returns a Boolean value that indicates whether the set is a subset of
433 | /// another set.
434 | public func isSubset(of other: CastlingRights) -> Bool {
435 | return _rights.isSubset(of: other._rights)
436 | }
437 |
438 | /// Returns a Boolean value that indicates whether the set has no members in
439 | /// common with the given set.
440 | public func isDisjoint(with other: CastlingRights) -> Bool {
441 | return _rights.isDisjoint(with: other._rights)
442 | }
443 |
444 | /// Returns a Boolean value that indicates whether the set is a superset of
445 | /// the given set.
446 | public func isSuperset(of other: CastlingRights) -> Bool {
447 | return _rights.isSuperset(of: other._rights)
448 | }
449 |
450 | /// Removes the elements of the given set from this set.
451 | public mutating func subtract(_ other: CastlingRights) {
452 | _rights.subtract(other)
453 | }
454 |
455 | }
456 |
457 | #else
458 |
459 | extension CastlingRights: SequenceType {
460 |
461 | /// Returns a generator over the members.
462 | ///
463 | /// - complexity: O(1).
464 | public func generate() -> Generator {
465 | return Generator(_base: _rights.generate())
466 | }
467 |
468 | }
469 |
470 | extension CastlingRights: SetAlgebraType {
471 |
472 | /// Returns `true` if `self` contains `member`.
473 | public func contains(member: Right) -> Bool {
474 | return _rights.contains(member)
475 | }
476 |
477 | /// Returns the set of elements contained in `self`, in `other`, or in both `self` and `other`.
478 | @warn_unused_result(mutable_variant="unionInPlace")
479 | public func union(other: CastlingRights) -> CastlingRights {
480 | return CastlingRights(_rights.union(other._rights))
481 | }
482 |
483 | /// Returns the set of elements contained in both `self` and `other`.
484 | @warn_unused_result(mutable_variant="intersectInPlace")
485 | public func intersect(other: CastlingRights) -> CastlingRights {
486 | return CastlingRights(_rights.intersect(other._rights))
487 | }
488 |
489 | /// Returns the set of elements contained in `self` or in `other`, but not in both `self` and `other`.
490 | @warn_unused_result(mutable_variant="exclusiveOrInPlace")
491 | public func exclusiveOr(other: CastlingRights) -> CastlingRights {
492 | return CastlingRights(_rights.exclusiveOr(other._rights))
493 | }
494 |
495 | /// Insert all elements of `other` into `self`.
496 | public mutating func unionInPlace(other: CastlingRights) {
497 | _rights.unionInPlace(other._rights)
498 | }
499 |
500 | /// Removes all elements of `self` that are not also present in `other`.
501 | public mutating func intersectInPlace(other: CastlingRights) {
502 | _rights.intersectInPlace(other._rights)
503 | }
504 |
505 | /// Replaces `self` with a set containing all elements contained in either `self` or `other`, but not both.
506 | public mutating func exclusiveOrInPlace(other: CastlingRights) {
507 | _rights.exclusiveOrInPlace(other._rights)
508 | }
509 |
510 | /// If `member` is not already contained in `self`, inserts it.
511 | public mutating func insert(member: Right) {
512 | _rights.insert(member)
513 | }
514 |
515 | /// Remove the member from the set and return it if it was present.
516 | public mutating func remove(member: Right) -> Right? {
517 | return _rights.remove(member)
518 | }
519 |
520 | }
521 |
522 | #endif
523 |
524 | extension CastlingRights: Hashable {
525 | /// The hash value.
526 | public var hashValue: Int {
527 | return _rights.reduce(0, combine: { $0 | $1._bit })
528 | }
529 | }
530 |
531 | /// Returns `true` if both have the same rights.
532 | public func == (lhs: CastlingRights, rhs: CastlingRights) -> Bool {
533 | return lhs._rights == rhs._rights
534 | }
535 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Color.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Color.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess color.
21 | public enum Color: String, CustomStringConvertible {
22 |
23 | #if swift(>=3)
24 |
25 | /// White chess color.
26 | case white
27 |
28 | /// Black chess color.
29 | case black
30 |
31 | /// White color regardless of Swift version.
32 | internal static let _white = Color.white
33 |
34 | /// Black color regardless of Swift version.
35 | internal static let _black = Color.black
36 |
37 | /// An array of all colors.
38 | public static let all: [Color] = [.white, .black]
39 |
40 | #else
41 |
42 | /// White chess color.
43 | case White
44 |
45 | /// Black chess color.
46 | case Black
47 |
48 | /// White color regardless of Swift version.
49 | internal static let _white = Color.White
50 |
51 | /// Black color regardless of Swift version.
52 | internal static let _black = Color.Black
53 |
54 | /// An array of all colors.
55 | public static let all: [Color] = [.White, .Black]
56 |
57 | #endif
58 |
59 | /// Whether the color is white or not.
60 | public var isWhite: Bool {
61 | return self == ._white
62 | }
63 |
64 | /// Whether the color is black or not.
65 | public var isBlack: Bool {
66 | return self == ._black
67 | }
68 |
69 | /// A textual representation of `self`.
70 | public var description: String {
71 | return rawValue
72 | }
73 |
74 | /// The lowercase character for the color. `White` is "w", `Black` is "b".
75 | public var character: Character {
76 | return self.isWhite ? "w" : "b"
77 | }
78 |
79 | /// Create a color from a character of any case.
80 | public init?(character: Character) {
81 | switch character {
82 | case "W", "w": self = ._white
83 | case "B", "b": self = ._black
84 | default: return nil
85 | }
86 | }
87 |
88 | /// Returns the inverse of `self`.
89 | public func inverse() -> Color {
90 | return self.isWhite ? ._black : ._white
91 | }
92 |
93 | /// Inverts the color of `self`.
94 | public mutating func invert() {
95 | self = inverse()
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/File.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess board file.
21 | ///
22 | /// Files refer to the eight columns of a chess board, beginning with A and ending with H from left to right.
23 | public enum File: Int, Comparable, CustomStringConvertible {
24 |
25 | /// A direction in file.
26 | public enum Direction {
27 |
28 | #if swift(>=3)
29 |
30 | /// Left direction.
31 | case left
32 |
33 | /// Right direction.
34 | case right
35 |
36 | #else
37 |
38 | /// Left direction.
39 | case Left
40 |
41 | /// Right direction.
42 | case Right
43 |
44 | #endif
45 |
46 | }
47 |
48 | #if swift(>=3)
49 |
50 | /// File "A".
51 | case a = 1
52 |
53 | /// File "B".
54 | case b = 2
55 |
56 | /// File "C".
57 | case c = 3
58 |
59 | /// File "D".
60 | case d = 4
61 |
62 | /// File "E".
63 | case e = 5
64 |
65 | /// File "F".
66 | case f = 6
67 |
68 | /// File "G".
69 | case g = 7
70 |
71 | /// File "H".
72 | case h = 8
73 |
74 | #else
75 |
76 | /// File "A".
77 | case A = 1
78 |
79 | /// File "B".
80 | case B = 2
81 |
82 | /// File "C".
83 | case C = 3
84 |
85 | /// File "D".
86 | case D = 4
87 |
88 | /// File "E".
89 | case E = 5
90 |
91 | /// File "F".
92 | case F = 6
93 |
94 | /// File "G".
95 | case G = 7
96 |
97 | /// File "H".
98 | case H = 8
99 |
100 | #endif
101 |
102 | }
103 |
104 | extension File {
105 |
106 | #if swift(>=3)
107 |
108 | /// An array of all files.
109 | public static let all: [File] = [.a, .b, .c, .d, .e, .f, .g, .h]
110 |
111 | #else
112 |
113 | /// An array of all files.
114 | public static let all: [File] = [.A, .B, .C, .D, .E, .F, .G, .H]
115 |
116 | #endif
117 |
118 | /// The column index of `self`.
119 | public var index: Int {
120 | return rawValue - 1
121 | }
122 |
123 | /// A textual representation of `self`.
124 | public var description: String {
125 | return String(character)
126 | }
127 |
128 | /// The character value of `self`.
129 | public var character: Character {
130 | #if swift(>=3)
131 | switch self {
132 | case .a: return "a"
133 | case .b: return "b"
134 | case .c: return "c"
135 | case .d: return "d"
136 | case .e: return "e"
137 | case .f: return "f"
138 | case .g: return "g"
139 | case .h: return "h"
140 | }
141 | #else
142 | switch self {
143 | case .A: return "a"
144 | case .B: return "b"
145 | case .C: return "c"
146 | case .D: return "d"
147 | case .E: return "e"
148 | case .F: return "f"
149 | case .G: return "g"
150 | case .H: return "h"
151 | }
152 | #endif
153 | }
154 |
155 | /// Create an instance from a character value.
156 | public init?(_ character: Character) {
157 | #if swift(>=3)
158 | switch character {
159 | case "A", "a": self = .a
160 | case "B", "b": self = .b
161 | case "C", "c": self = .c
162 | case "D", "d": self = .d
163 | case "E", "e": self = .e
164 | case "F", "f": self = .f
165 | case "G", "g": self = .g
166 | case "H", "h": self = .h
167 | default: return nil
168 | }
169 | #else
170 | switch character {
171 | case "A", "a": self = .A
172 | case "B", "b": self = .B
173 | case "C", "c": self = .C
174 | case "D", "d": self = .D
175 | case "E", "e": self = .E
176 | case "F", "f": self = .F
177 | case "G", "g": self = .G
178 | case "H", "h": self = .H
179 | default: return nil
180 | }
181 | #endif
182 | }
183 |
184 | /// Create a `File` from a zero-based column index.
185 | public init?(index: Int) {
186 | self.init(rawValue: index + 1)
187 | }
188 |
189 | /// Returns a rank from advancing `self` by `value`.
190 | public func advanced(by value: Int) -> File? {
191 | return File(rawValue: rawValue + value)
192 | }
193 |
194 | /// The next file after `self`.
195 | public func next() -> File? {
196 | return File(rawValue: (rawValue + 1))
197 | }
198 |
199 | /// The previous file to `self`.
200 | public func previous() -> File? {
201 | return File(rawValue: (rawValue - 1))
202 | }
203 |
204 | /// The opposite file of `self`.
205 | public func opposite() -> File {
206 | return File(rawValue: 9 - rawValue)!
207 | }
208 |
209 | /// The files from `self` to `other`.
210 | public func to(_ other: File) -> [File] {
211 | if other > self {
212 | return (rawValue...other.rawValue).flatMap(File.init(rawValue:))
213 | } else if other < self {
214 | #if swift(>=3)
215 | let values = (other.rawValue...rawValue).reversed()
216 | #else
217 | let values = (other.rawValue...rawValue).reverse()
218 | #endif
219 | return values.flatMap(File.init(rawValue:))
220 | } else {
221 | return [self]
222 | }
223 | }
224 |
225 | /// The files between `self` and `other`.
226 | public func between(_ other: File) -> [File] {
227 | if other > self {
228 | return (rawValue + 1 ..< other.rawValue).flatMap(File.init(rawValue:))
229 | } else if other < self {
230 | #if swift(>=3)
231 | let values = (other.rawValue + 1 ..< rawValue).reversed()
232 | #else
233 | let values = (other.rawValue + 1 ..< rawValue).reverse()
234 | #endif
235 | return values.flatMap(File.init(rawValue:))
236 | } else {
237 | return []
238 | }
239 | }
240 |
241 | }
242 |
243 | extension File: ExtendedGraphemeClusterLiteralConvertible {
244 |
245 | /// Create an instance initialized to `value`.
246 | public init(unicodeScalarLiteral value: Character) {
247 | guard let file = File(value) else {
248 | fatalError("File value not within \"A\" and \"H\" or \"a\" and \"h\", inclusive")
249 | }
250 | self = file
251 | }
252 |
253 | /// Create an instance initialized to `value`.
254 | public init(extendedGraphemeClusterLiteral value: Character) {
255 | self.init(unicodeScalarLiteral: value)
256 | }
257 |
258 | }
259 |
260 | /// Returns `true` if one file is further left than the other.
261 | public func < (lhs: File, rhs: File) -> Bool {
262 | return lhs.rawValue < rhs.rawValue
263 | }
264 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/InternalTypes.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InternalTypes.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #if os(OSX)
21 | import Cocoa
22 | internal typealias _View = NSView
23 | internal typealias _Color = NSColor
24 | #elseif os(iOS) || os(tvOS)
25 | import UIKit
26 | internal typealias _View = UIView
27 | internal typealias _Color = UIColor
28 | #endif
29 |
30 | internal extension Optional {
31 |
32 | var _altDescription: String {
33 | return self.map({ String($0) }) ?? "nil"
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Move.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Move.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess move from a start `Square` to an end `Square`.
21 | public struct Move: Hashable, CustomStringConvertible {
22 |
23 | /// The move's start square.
24 | public var start: Square
25 |
26 | /// The move's end square.
27 | public var end: Square
28 |
29 | /// The move's change in file.
30 | public var fileChange: Int {
31 | return end.file.rawValue - start.file.rawValue
32 | }
33 |
34 | /// The move's change in rank.
35 | public var rankChange: Int {
36 | return end.rank.rawValue - start.rank.rawValue
37 | }
38 |
39 | /// The move is a real change in location.
40 | public var isChange: Bool {
41 | return start != end
42 | }
43 |
44 | /// The move is diagonal.
45 | public var isDiagonal: Bool {
46 | let fileChange = self.fileChange
47 | return fileChange != 0 && abs(fileChange) == abs(rankChange)
48 | }
49 |
50 | /// The move is horizontal.
51 | public var isHorizontal: Bool {
52 | return start.file != end.file && start.rank == end.rank
53 | }
54 |
55 | /// The move is vertical.
56 | public var isVertical: Bool {
57 | return start.file == end.file && start.rank != end.rank
58 | }
59 |
60 | /// The move is horizontal or vertical.
61 | public var isAxial: Bool {
62 | return isHorizontal || isVertical
63 | }
64 |
65 | /// The move is leftward.
66 | public var isLeftward: Bool {
67 | return end.file < start.file
68 | }
69 |
70 | /// The move is rightward.
71 | public var isRightward: Bool {
72 | return end.file > start.file
73 | }
74 |
75 | /// The move is downward.
76 | public var isDownward: Bool {
77 | return end.rank < start.rank
78 | }
79 |
80 | /// The move is upward.
81 | public var isUpward: Bool {
82 | return end.rank > start.rank
83 | }
84 |
85 | /// The move is a knight jump two spaces horizontally and one space vertically, or two spaces vertically and one
86 | /// space horizontally.
87 | public var isKnightJump: Bool {
88 | let fileChange = abs(self.fileChange)
89 | let rankChange = abs(self.rankChange)
90 | return (fileChange == 2 && rankChange == 1)
91 | || (rankChange == 2 && fileChange == 1)
92 | }
93 |
94 | /// The move's direction in file, if any.
95 | public var fileDirection: File.Direction? {
96 | #if swift(>=3)
97 | if self.isLeftward {
98 | return .left
99 | } else if self.isRightward {
100 | return .right
101 | } else {
102 | return .none
103 | }
104 | #else
105 | if self.isLeftward {
106 | return .Left
107 | } else if self.isRightward {
108 | return .Right
109 | } else {
110 | return .None
111 | }
112 | #endif
113 | }
114 |
115 | /// The move's direction in rank, if any.
116 | public var rankDirection: Rank.Direction? {
117 | #if swift(>=3)
118 | if self.isUpward {
119 | return .up
120 | } else if self.isDownward {
121 | return .down
122 | } else {
123 | return .none
124 | }
125 | #else
126 | if self.isUpward {
127 | return .Up
128 | } else if self.isDownward {
129 | return .Down
130 | } else {
131 | return .None
132 | }
133 | #endif
134 | }
135 |
136 | /// A textual representation of `self`.
137 | public var description: String {
138 | return "\(start) >>> \(end)"
139 | }
140 |
141 | /// The hash value.
142 | public var hashValue: Int {
143 | return start.hashValue + (end.hashValue << 6)
144 | }
145 |
146 | /// Create a move with start and end squares.
147 | public init(start: Square, end: Square) {
148 | self.start = start
149 | self.end = end
150 | }
151 |
152 | /// Create a move with start and end locations.
153 | public init(start: Location, end: Location) {
154 | self.start = Square(location: start)
155 | self.end = Square(location: end)
156 | }
157 |
158 | /// A castle move for `color` in `direction`.
159 | public init(castle color: Color, direction: File.Direction) {
160 | let rank: Rank = color.isWhite ? 1 : 8
161 | #if swift(>=3)
162 | self = Move(start: Square(file: .e, rank: rank),
163 | end: Square(file: direction == .left ? .c : .g, rank: rank))
164 | #else
165 | self = Move(start: Square(file: .E, rank: rank),
166 | end: Square(file: direction == .Left ? .C : .G, rank: rank))
167 | #endif
168 | }
169 |
170 | /// Returns the castle squares for a rook.
171 | internal func _castleSquares() -> (old: Square, new: Square) {
172 | let rank = start.rank
173 | let movedLeft = self.isLeftward
174 | #if swift(>=3)
175 | let old = Square(file: movedLeft ? .a : .h, rank: rank)
176 | let new = Square(file: movedLeft ? .d : .f, rank: rank)
177 | #else
178 | let old = Square(file: movedLeft ? .A : .H, rank: rank)
179 | let new = Square(file: movedLeft ? .D : .F, rank: rank)
180 | #endif
181 | return (old, new)
182 | }
183 |
184 | /// Returns a move with the end and start of `self` reversed.
185 | public func reversed() -> Move {
186 | return Move(start: end, end: start)
187 | }
188 |
189 | /// Returns the result of rotating `self` 180 degrees.
190 | public func rotated() -> Move {
191 | let start = Square(file: self.start.file.opposite(),
192 | rank: self.start.rank.opposite())
193 | let end = Square(file: self.end.file.opposite(),
194 | rank: self.end.rank.opposite())
195 | return start >>> end
196 | }
197 |
198 | /// Returns `true` if `self` is castle move for `color`.
199 | ///
200 | /// - parameter color: The color to check the rank against. If `nil`, the rank can be either 1 or 8. The default
201 | /// value is `nil`.
202 | public func isCastle(for color: Color? = nil) -> Bool {
203 | #if swift(>=3)
204 | let e = File.e
205 | #else
206 | let e = File.E
207 | #endif
208 | let startRank = start.rank
209 | if let color = color {
210 | guard startRank == Rank(startFor: color) else { return false }
211 | } else {
212 | guard startRank == 1 || startRank == 8 else { return false }
213 | }
214 | return startRank == end.rank
215 | && start.file == e
216 | && abs(fileChange) == 2
217 | }
218 |
219 | }
220 |
221 | infix operator >>> { }
222 |
223 | /// Returns `true` if both moves are the same.
224 | public func == (lhs: Move, rhs: Move) -> Bool {
225 | return lhs.start == rhs.start && lhs.end == rhs.end
226 | }
227 |
228 | /// Returns a `Move` from the two squares.
229 | public func >>> (start: Square, end: Square) -> Move {
230 | return Move(start: start, end: end)
231 | }
232 |
233 | /// Returns a `Move` from the two locations.
234 | public func >>> (start: Location, rhs: Location) -> Move {
235 | return Square(location: start) >>> Square(location: rhs)
236 | }
237 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/PGN.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PGN.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// Portable game notation data.
21 | ///
22 | /// - seealso: [Portable Game Notation (Wikipedia)](https://en.wikipedia.org/wiki/Portable_Game_Notation),
23 | /// [PGN Specification](https://www.chessclub.com/user/help/PGN-spec)
24 | public struct PGN: Equatable {
25 |
26 | /// PGN tag.
27 | public enum Tag: String, CustomStringConvertible {
28 |
29 | #if swift(>=3)
30 |
31 | /// Event tag.
32 | case event = "Event"
33 |
34 | /// Site tag.
35 | case site = "Site"
36 |
37 | /// Date tag.
38 | case date = "Date"
39 |
40 | /// Round tag.
41 | case round = "Round"
42 |
43 | /// White tag.
44 | case white = "White"
45 |
46 | /// Black tag.
47 | case black = "Black"
48 |
49 | /// Result tag.
50 | case result = "Result"
51 |
52 | /// Annotator tag.
53 | case annotator = "Annotator"
54 |
55 | /// Ply (moves) count tag.
56 | case plyCount = "PlyCount"
57 |
58 | /// TimeControl tag.
59 | case timeControl = "TimeControl"
60 |
61 | /// Time tag.
62 | case time = "Time"
63 |
64 | /// Termination tag.
65 | case termination = "Termination"
66 |
67 | /// Playing mode tag.
68 | case mode = "Mode"
69 |
70 | /// FEN tag.
71 | case fen = "FEN"
72 |
73 | /// White player's title tag.
74 | case whiteTitle = "WhiteTitle"
75 |
76 | /// Black player's title tag.
77 | case blackTitle = "BlackTitle"
78 |
79 | /// White player's elo rating tag.
80 | case whiteElo = "WhiteElo"
81 |
82 | /// Black player's elo rating tag.
83 | case blackElo = "BlackElo"
84 |
85 | /// White player's United States Chess Federation rating tag.
86 | case whiteUSCF = "WhiteUSCF"
87 |
88 | /// Black player's United States Chess Federation rating tag.
89 | case blackUSCF = "BlackUSCF"
90 |
91 | /// White player's network or email address tag.
92 | case whiteNA = "WhiteNA"
93 |
94 | /// Black player's network or email address tag.
95 | case blackNA = "BlackNA"
96 |
97 | /// White player's type tag; either human or program.
98 | case whiteType = "WhiteType"
99 |
100 | /// Black player's type tag; either human or program.
101 | case blackType = "BlackType"
102 |
103 | /// The starting date tag of the event.
104 | case eventDate = "EventDate"
105 |
106 | /// Tag for the name of the sponsor of the event.
107 | case eventSponsor = "EventSponsor"
108 |
109 | /// The playing section tag of a tournament.
110 | case section = "Section"
111 |
112 | /// Tag for the stage of a multistage event.
113 | case stage = "Stage"
114 |
115 | /// The board number tag in a team event or in a simultaneous exhibition.
116 | case board = "Board"
117 |
118 | /// The traditional opening name tag.
119 | case opening = "Opening"
120 |
121 | /// Tag used to further refine the opening tag.
122 | case variation = "Variation"
123 |
124 | /// Used to further refine the variation tag.
125 | case subVariation = "SubVariation"
126 |
127 | /// Tag used for an opening designation from the five volume *Encyclopedia of Chess Openings*.
128 | case eco = "ECO"
129 |
130 | /// Tag used for an opening designation from the *New in Chess* database.
131 | case nic = "NIC"
132 |
133 | /// Tag similar to the Time tag but given according to the Universal Coordinated Time standard.
134 | case utcTime = "UTCTime"
135 |
136 | /// Tag similar to the Date tag but given according to the Universal Coordinated Time standard.
137 | case utcDate = "UTCDate"
138 |
139 | /// Tag for the "set-up" status of the game.
140 | case setUp = "SetUp"
141 |
142 | #else
143 |
144 | /// Event tag.
145 | case Event
146 |
147 | /// Site tag.
148 | case Site
149 |
150 | /// Date tag.
151 | case Date
152 |
153 | /// Round tag.
154 | case Round
155 |
156 | /// White tag.
157 | case White
158 |
159 | /// Black tag.
160 | case Black
161 |
162 | /// Result tag.
163 | case Result
164 |
165 | /// Annotator tag.
166 | case Annotator
167 |
168 | /// Ply (moves) count tag.
169 | case PlyCount
170 |
171 | /// TimeControl tag.
172 | case TimeControl
173 |
174 | /// Time tag.
175 | case Time
176 |
177 | /// Termination tag.
178 | case Termination
179 |
180 | /// Playing mode tag.
181 | case Mode
182 |
183 | /// FEN tag.
184 | case FEN
185 |
186 | /// White player's title tag.
187 | case WhiteTitle
188 |
189 | /// Black player's title tag.
190 | case BlackTitle
191 |
192 | /// White player's elo rating tag.
193 | case WhiteElo
194 |
195 | /// Black player's elo rating tag.
196 | case BlackElo
197 |
198 | /// White player's United States Chess Federation rating tag.
199 | case WhiteUSCF
200 |
201 | /// Black player's United States Chess Federation rating tag.
202 | case BlackUSCF
203 |
204 | /// White player's network or email address tag.
205 | case WhiteNA
206 |
207 | /// Black player's network or email address tag.
208 | case BlackNA
209 |
210 | /// White player's type tag; either human or program.
211 | case WhiteType
212 |
213 | /// Black player's type tag; either human or program.
214 | case BlackType
215 |
216 | /// The starting date tag of the event.
217 | case EventDate
218 |
219 | /// Tag for the name of the sponsor of the event.
220 | case EventSponsor
221 |
222 | /// The playing section tag of a tournament.
223 | case Section
224 |
225 | /// Tag for the stage of a multistage event.
226 | case Stage
227 |
228 | /// The board number tag in a team event or in a simultaneous exhibition.
229 | case Board
230 |
231 | /// The traditional opening name tag.
232 | case Opening
233 |
234 | /// Tag used to further refine the opening tag.
235 | case Variation
236 |
237 | /// Used to further refine the variation tag.
238 | case SubVariation
239 |
240 | /// Tag used for an opening designation from the five volume *Encyclopedia of Chess Openings*.
241 | case ECO
242 |
243 | /// Tag used for an opening designation from the *New in Chess* database.
244 | case NIC
245 |
246 | /// Tag similar to the Time tag but given according to the Universal Coordinated Time standard.
247 | case UTCTime
248 |
249 | /// Tag similar to the Date tag but given according to the Universal Coordinated Time standard.
250 | case UTCDate
251 |
252 | /// Tag for the "set-up" status of the game.
253 | case SetUp
254 |
255 | #endif
256 |
257 | /// A textual representation of `self`.
258 | public var description: String {
259 | return rawValue
260 | }
261 |
262 | }
263 |
264 | #if swift(>=3)
265 |
266 | /// An error thrown by `PGN.init(parse:)`.
267 | public enum ParseError: ErrorProtocol {
268 |
269 | /// Unexpected quote found in move text.
270 | case unexpectedQuote(String)
271 |
272 | /// Unexpected closing brace found outside of comment.
273 | case unexpectedClosingBrace(String)
274 |
275 | /// No closing brace for comment.
276 | case noClosingBrace(String)
277 |
278 | /// No closing quote for tag value.
279 | case noClosingQuote(String)
280 |
281 | /// No closing bracket for tag pair.
282 | case noClosingBracket(String)
283 |
284 | /// Wrong number of tokens for tag pair.
285 | case tagPairTokenCount([String])
286 |
287 | /// Incorrect count of parenthesis for recursive annotation variation.
288 | case parenthesisCountForRAV(String)
289 |
290 | }
291 |
292 | #else
293 |
294 | /// An error thrown by `PGN.init(parse:)`.
295 | public enum ParseError: ErrorType {
296 |
297 | /// Unexpected quote found in move text.
298 | case UnexpectedQuote(String)
299 |
300 | /// Unexpected closing brace found outside of comment.
301 | case UnexpectedClosingBrace(String)
302 |
303 | /// No closing brace for comment.
304 | case NoClosingBrace(String)
305 |
306 | /// No closing quote for tag value.
307 | case NoClosingQuote(String)
308 |
309 | /// No closing bracket for tag pair.
310 | case NoClosingBracket(String)
311 |
312 | /// Wrong number of tokens for tag pair.
313 | case TagPairTokenCount([String])
314 |
315 | /// Incorrect count of parenthesis for recursive annotation variation.
316 | case ParenthesisCountForRAV(String)
317 |
318 | }
319 |
320 | #endif
321 |
322 | /// The tag pairs for `self`.
323 | public var tagPairs: [String: String]
324 |
325 | /// The moves in standard algebraic notation.
326 | public var moves: [String]
327 |
328 | /// The game outcome.
329 | public var outcome: Game.Outcome? {
330 | get {
331 | #if swift(>=3)
332 | let resultTag = Tag.result
333 | #else
334 | let resultTag = Tag.Result
335 | #endif
336 | return self[resultTag].flatMap(Game.Outcome.init)
337 | }
338 | set {
339 | #if swift(>=3)
340 | let resultTag = Tag.result
341 | #else
342 | let resultTag = Tag.Result
343 | #endif
344 | self[resultTag] = newValue?.description
345 | }
346 | }
347 |
348 | /// Create PGN with `tagPairs` and `moves`.
349 | public init(tagPairs: [String: String] = [:], moves: [String] = []) {
350 | self.tagPairs = tagPairs
351 | self.moves = moves
352 | }
353 |
354 | /// Create PGN with `tagPairs` and `moves`.
355 | public init(tagPairs: [Tag: String], moves: [String] = []) {
356 | self.init(moves: moves)
357 | for (tag, value) in tagPairs {
358 | self[tag] = value
359 | }
360 | }
361 |
362 | /// Create PGN by parsing `string`.
363 | ///
364 | /// - throws: `ParseError` if an error occured while parsing.
365 | public init(parse string: String) throws {
366 | self.init()
367 | if string.isEmpty { return }
368 | for line in string._splitByNewlines() {
369 | if line.characters.first == "[" {
370 | let commentsStripped = try line._commentsStripped(strings: true)
371 | let (tag, value) = try commentsStripped._tagPair()
372 | tagPairs[tag] = value
373 | } else if line.characters.first != "%" {
374 | let commentsStripped = try line._commentsStripped(strings: false)
375 | let (moves, outcome) = try commentsStripped._moves()
376 | self.moves += moves
377 | if let outcome = outcome {
378 | self.outcome = outcome
379 | }
380 | }
381 | }
382 | }
383 |
384 | /// Get or set the value for `tag`.
385 | public subscript(tag: Tag) -> String? {
386 | get {
387 | return tagPairs[tag.rawValue]
388 | }
389 | set {
390 | tagPairs[tag.rawValue] = newValue
391 | }
392 | }
393 |
394 | /// Returns `self` in export string format.
395 | public func exported() -> String {
396 | var result = ""
397 | var tagPairs = self.tagPairs
398 | let sevenTags = [("Event", "?"),
399 | ("Site", "?"),
400 | ("Date", "????.??.??"),
401 | ("Round", "?"),
402 | ("White", "?"),
403 | ("Black", "?"),
404 | ("Result", "*")]
405 | for (tag, defaultValue) in sevenTags {
406 | if let value = tagPairs[tag] {
407 | tagPairs[tag] = nil
408 | result += "[\(tag) \"\(value)\"]\n"
409 | } else {
410 | result += "[\(tag) \"\(defaultValue)\"]\n"
411 | }
412 | }
413 | for (tag, value) in tagPairs {
414 | result += "[\(tag) \"\(value)\"]\n"
415 | }
416 | #if swift(>=3)
417 | let strideTo = stride(from: 0, to: moves.endIndex, by: 2)
418 | #else
419 | let strideTo = 0.stride(to: moves.endIndex, by: 2)
420 | #endif
421 | var moveLine = ""
422 | for num in strideTo {
423 | let moveNumber = (num + 2) / 2
424 | var moveString = "\(moveNumber). \(moves[num])"
425 | if num + 1 < moves.endIndex {
426 | moveString += " \(moves[num + 1])"
427 | }
428 | if moveString.characters.count + moveLine.characters.count < 80 {
429 | if !moveLine.isEmpty {
430 | moveString = " \(moveString)"
431 | }
432 | moveLine += moveString
433 | } else {
434 | result += "\n\(moveLine)"
435 | moveLine = moveString
436 | }
437 | }
438 | if !moveLine.isEmpty {
439 | result += "\n\(moveLine)"
440 | }
441 | if let outcomeString = outcome?.description {
442 | if moveLine.isEmpty {
443 | result += "\n\(outcomeString)"
444 | } else if outcomeString.characters.count + moveLine.characters.count < 80 {
445 | result += " \(outcomeString)"
446 | } else {
447 | result += "\n\(outcomeString)"
448 | }
449 | }
450 | return result
451 | }
452 |
453 | }
454 |
455 | private extension Character {
456 |
457 | static let newlines: Set = ["\u{000A}", "\u{000B}", "\u{000C}", "\u{000D}",
458 | "\u{0085}", "\u{2028}", "\u{2029}"]
459 |
460 | static let whitespaces: Set = ["\u{0020}", "\u{00A0}", "\u{1680}", "\u{180E}", "\u{2000}",
461 | "\u{2001}", "\u{2002}", "\u{2003}", "\u{2004}", "\u{2005}",
462 | "\u{2006}", "\u{2007}", "\u{2008}", "\u{2009}", "\u{200A}",
463 | "\u{200B}", "\u{202F}", "\u{205F}", "\u{3000}", "\u{FEFF}"]
464 |
465 | static let digits: Set = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
466 |
467 | var isDigit: Bool {
468 | return Character.digits.contains(self)
469 | }
470 |
471 | }
472 |
473 | private extension String {
474 |
475 | var _lastIndex: Index {
476 | #if swift(>=3)
477 | return index(before: endIndex)
478 | #else
479 | return endIndex.predecessor()
480 | #endif
481 | }
482 |
483 | @inline(__always)
484 | func _split(by set: Set) -> [String] {
485 | return characters.split(isSeparator: set.contains).map(String.init)
486 | }
487 |
488 | @inline(__always)
489 | func _splitByNewlines() -> [String] {
490 | return _split(by: Character.newlines)
491 | }
492 |
493 | @inline(__always)
494 | func _splitByWhitespaces() -> [String] {
495 | return _split(by: Character.whitespaces)
496 | }
497 |
498 | @inline(__always)
499 | func _tagPair() throws -> (String, String) {
500 | guard characters.last == "]" else {
501 | #if swift(>=3)
502 | throw PGN.ParseError.noClosingBracket(self)
503 | #else
504 | throw PGN.ParseError.NoClosingBracket(self)
505 | #endif
506 | }
507 | #if swift(>=3)
508 | let startIndex = index(after: self.startIndex)
509 | let endIndex = index(before: self.endIndex)
510 | #else
511 | let startIndex = self.startIndex.successor()
512 | let endIndex = self.endIndex.predecessor()
513 | #endif
514 | let tokens = self[startIndex ..< endIndex]._split(by: ["\""])
515 | guard tokens.count == 2 else {
516 | #if swift(>=3)
517 | throw PGN.ParseError.tagPairTokenCount(tokens)
518 | #else
519 | throw PGN.ParseError.TagPairTokenCount(tokens)
520 | #endif
521 | }
522 | let tagParts = tokens[0]._splitByWhitespaces()
523 | guard tagParts.count == 1 else {
524 | #if swift(>=3)
525 | throw PGN.ParseError.tagPairTokenCount(tagParts)
526 | #else
527 | throw PGN.ParseError.TagPairTokenCount(tagParts)
528 | #endif
529 | }
530 | return (tagParts[0], tokens[1])
531 | }
532 |
533 | @inline(__always)
534 | func _moves() throws -> (moves: [String], outcome: Game.Outcome?) {
535 | var stripped = ""
536 | var ravDepth = 0
537 | var startIndex = self.startIndex
538 | let lastIndex = _lastIndex
539 | for (index, character) in zip(characters.indices, characters) {
540 | if character == "(" {
541 | if ravDepth == 0 {
542 | stripped += self[startIndex ..< index]
543 | }
544 | ravDepth += 1
545 | } else if character == ")" {
546 | ravDepth -= 1
547 | if ravDepth == 0 {
548 | #if swift(>=3)
549 | startIndex = self.index(after: index)
550 | #else
551 | startIndex = index.successor()
552 | #endif
553 | }
554 | } else if index == lastIndex && ravDepth == 0 {
555 | stripped += self[startIndex ... index]
556 | }
557 | }
558 | guard ravDepth == 0 else {
559 | #if swift(>=3)
560 | throw PGN.ParseError.parenthesisCountForRAV(self)
561 | #else
562 | throw PGN.ParseError.ParenthesisCountForRAV(self)
563 | #endif
564 | }
565 | let tokens = stripped._split(by: [" ", "."])
566 | let moves = tokens.filter({ $0.characters.first?.isDigit == false })
567 | let outcome = tokens.last.flatMap(Game.Outcome.init)
568 | return (moves, outcome)
569 | }
570 |
571 | @inline(__always)
572 | func _commentsStripped(strings consideringStrings: Bool) throws -> String {
573 | var stripped = ""
574 | var startIndex = self.startIndex
575 | let lastIndex = _lastIndex
576 | var afterEscape = false
577 | var inString = false
578 | var inComment = false
579 | for (index, character) in zip(characters.indices, characters) {
580 | if character == "\\" {
581 | afterEscape = true
582 | continue
583 | }
584 | if character == "\"" {
585 | if !inComment {
586 | guard consideringStrings else {
587 | #if swift(>=3)
588 | throw PGN.ParseError.unexpectedQuote(self)
589 | #else
590 | throw PGN.ParseError.UnexpectedQuote(self)
591 | #endif
592 | }
593 | if !inString {
594 | inString = true
595 | } else if !afterEscape {
596 | inString = false
597 | }
598 | }
599 | } else if !inString {
600 | if character == ";" && !inComment {
601 | stripped += self[startIndex ..< index]
602 | break
603 | } else if character == "{" && !inComment {
604 | inComment = true
605 | stripped += self[startIndex ..< index]
606 | } else if character == "}" {
607 | guard inComment else {
608 | #if swift(>=3)
609 | throw PGN.ParseError.unexpectedClosingBrace(self)
610 | #else
611 | throw PGN.ParseError.UnexpectedClosingBrace(self)
612 | #endif
613 | }
614 | inComment = false
615 | #if swift(>=3)
616 | startIndex = self.index(after: index)
617 | #else
618 | startIndex = index.successor()
619 | #endif
620 | }
621 | }
622 | if index >= startIndex && index == lastIndex && !inComment {
623 | stripped += self[startIndex ... index]
624 | }
625 | afterEscape = false
626 | }
627 | guard !inString else {
628 | #if swift(>=3)
629 | throw PGN.ParseError.noClosingQuote(self)
630 | #else
631 | throw PGN.ParseError.NoClosingQuote(self)
632 | #endif
633 | }
634 | guard !inComment else {
635 | #if swift(>=3)
636 | throw PGN.ParseError.noClosingBrace(self)
637 | #else
638 | throw PGN.ParseError.NoClosingBrace(self)
639 | #endif
640 | }
641 | return stripped
642 | }
643 |
644 | }
645 |
646 | /// Returns a Boolean value indicating whether two values are equal.
647 | public func == (lhs: PGN, rhs: PGN) -> Bool {
648 | return lhs.tagPairs == rhs.tagPairs
649 | && lhs.moves == rhs.moves
650 | }
651 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Piece.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Piece.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess piece.
21 | public struct Piece: Hashable, CustomStringConvertible {
22 |
23 | /// A piece kind.
24 | public enum Kind: Int {
25 |
26 | #if swift(>=3)
27 |
28 | /// Pawn piece kind.
29 | case pawn
30 |
31 | /// Knight piece kind.
32 | case knight
33 |
34 | /// Bishop piece kind.
35 | case bishop
36 |
37 | /// Rook piece kind.
38 | case rook
39 |
40 | /// Queen piece kind.
41 | case queen
42 |
43 | /// King piece kind.
44 | case king
45 |
46 | /// Pawn regardless of Swift veersion.
47 | internal static let _pawn = Kind.pawn
48 |
49 | /// Knight regardless of Swift veersion.
50 | internal static let _knight = Kind.knight
51 |
52 | /// Bishop regardless of Swift veersion.
53 | internal static let _bishop = Kind.bishop
54 |
55 | /// Rook regardless of Swift veersion.
56 | internal static let _rook = Kind.rook
57 |
58 | /// Queen regardless of Swift veersion.
59 | internal static let _queen = Kind.queen
60 |
61 | /// King regardless of Swift veersion.
62 | internal static let _king = Kind.king
63 |
64 | /// An array of all piece kinds.
65 | public static let all: [Kind] = [.pawn, .knight, .bishop, .rook, .queen, .king]
66 |
67 | #else
68 |
69 | /// Pawn piece kind.
70 | case Pawn
71 |
72 | /// Knight piece kind.
73 | case Knight
74 |
75 | /// Bishop piece kind.
76 | case Bishop
77 |
78 | /// Rook piece kind.
79 | case Rook
80 |
81 | /// Queen piece kind.
82 | case Queen
83 |
84 | /// King piece kind.
85 | case King
86 |
87 | /// Pawn regardless of Swift veersion.
88 | internal static let _pawn = Kind.Pawn
89 |
90 | /// Knight regardless of Swift veersion.
91 | internal static let _knight = Kind.Knight
92 |
93 | /// Bishop regardless of Swift veersion.
94 | internal static let _bishop = Kind.Bishop
95 |
96 | /// Rook regardless of Swift veersion.
97 | internal static let _rook = Kind.Rook
98 |
99 | /// Queen regardless of Swift veersion.
100 | internal static let _queen = Kind.Queen
101 |
102 | /// King regardless of Swift veersion.
103 | internal static let _king = Kind.King
104 |
105 | /// An array of all piece kinds.
106 | public static let all: [Kind] = [.Pawn, .Knight, .Bishop, .Rook, .Queen, .King]
107 |
108 | #endif
109 |
110 | /// The piece kind's name.
111 | public var name: String {
112 | #if swift(>=3)
113 | switch self {
114 | case .pawn: return "Pawn"
115 | case .knight: return "Knight"
116 | case .bishop: return "Bishop"
117 | case .rook: return "Rook"
118 | case .queen: return "Queen"
119 | case .king: return "King"
120 | }
121 | #else
122 | switch self {
123 | case .Pawn: return "Pawn"
124 | case .Knight: return "Knight"
125 | case .Bishop: return "Bishop"
126 | case .Rook: return "Rook"
127 | case .Queen: return "Queen"
128 | case .King: return "King"
129 | }
130 | #endif
131 | }
132 |
133 | /// The piece kind's relative value. Can be used to determine how valuable a piece or combination of pieces is.
134 | public var relativeValue: Double {
135 | #if swift(>=3)
136 | switch self {
137 | case .pawn: return 1
138 | case .knight: return 3
139 | case .bishop: return 3.25
140 | case .rook: return 5
141 | case .queen: return 9
142 | case .king: return .infinity
143 | }
144 | #else
145 | switch self {
146 | case .Pawn: return 1
147 | case .Knight: return 3
148 | case .Bishop: return 3.25
149 | case .Rook: return 5
150 | case .Queen: return 9
151 | case .King: return .infinity
152 | }
153 | #endif
154 | }
155 |
156 | /// The piece is `Pawn`.
157 | public var isPawn: Bool {
158 | return self == ._pawn
159 | }
160 |
161 | /// The piece `Knight`.
162 | public var isKnight: Bool {
163 | return self == ._knight
164 | }
165 |
166 | /// The piece is `Bishop`.
167 | public var isBishop: Bool {
168 | return self == ._bishop
169 | }
170 |
171 | /// The piece is `Rook`.
172 | public var isRook: Bool {
173 | return self == ._rook
174 | }
175 |
176 | /// The piece is `Queen`.
177 | public var isQueen: Bool {
178 | return self == ._queen
179 | }
180 |
181 | /// The piece is `King`.
182 | public var isKing: Bool {
183 | return self == ._king
184 | }
185 |
186 | /// Returns `true` if `self` can be a promotion for a pawn.
187 | public func canPromote() -> Bool {
188 | return !(isPawn || isKing)
189 | }
190 |
191 | /// Returns `true` if `self` can be a promotion for `other`.
192 | public func canPromote(_ other: Kind) -> Bool {
193 | return canPromote() ? other.isPawn : false
194 | }
195 |
196 | }
197 |
198 | /// An array of all pieces.
199 | public static let all: [Piece] = {
200 | return [._white, ._black].reduce([]) { pieces, color in
201 | return pieces + Kind.all.map({ Piece(kind: $0, color: color) })
202 | }
203 | }()
204 |
205 |
206 | /// An array of all white pieces.
207 | public static let whitePieces: [Piece] = all.filter({ $0.color.isWhite })
208 |
209 | /// An array of all black pieces.
210 | public static let blackPieces: [Piece] = all.filter({ $0.color.isBlack })
211 |
212 | /// Returns an array of all pieces for `color`.
213 | public static func pieces(for color: Color) -> [Piece] {
214 | return color.isWhite ? whitePieces : blackPieces
215 | }
216 |
217 | /// The piece's kind.
218 | public var kind: Kind
219 |
220 | /// The piece's color.
221 | public var color: Color
222 |
223 | /// The character for the piece. Uppercase if white or lowercase if black.
224 | public var character: Character {
225 | #if swift(>=3)
226 | switch kind {
227 | case .pawn: return color.isWhite ? "P" : "p"
228 | case .knight: return color.isWhite ? "N" : "n"
229 | case .bishop: return color.isWhite ? "B" : "b"
230 | case .rook: return color.isWhite ? "R" : "r"
231 | case .queen: return color.isWhite ? "Q" : "q"
232 | case .king: return color.isWhite ? "K" : "k"
233 | }
234 | #else
235 | switch kind {
236 | case .Pawn: return color.isWhite ? "P" : "p"
237 | case .Knight: return color.isWhite ? "N" : "n"
238 | case .Bishop: return color.isWhite ? "B" : "b"
239 | case .Rook: return color.isWhite ? "R" : "r"
240 | case .Queen: return color.isWhite ? "Q" : "q"
241 | case .King: return color.isWhite ? "K" : "k"
242 | }
243 | #endif
244 | }
245 |
246 | /// A textual representation of `self`.
247 | public var description: String {
248 | return "\(kind.name)(\(color))"
249 | }
250 |
251 | /// The hash value.
252 | public var hashValue: Int {
253 | return (kind.hashValue << 1) | color.hashValue
254 | }
255 |
256 | /// Create a piece from an integer value.
257 | internal init?(value: Int) {
258 | guard let kind = Kind(rawValue: value >> 1) else {
259 | return nil
260 | }
261 | self.init(kind: kind, color: value & 1 == 0 ? ._white : ._black)
262 | }
263 |
264 | /// Create a piece from `kind` and `color`.
265 | public init(kind: Kind, color: Color) {
266 | self.kind = kind
267 | self.color = color
268 | }
269 |
270 | /// Create a pawn piece with `color`.
271 | public init(pawn color: Color) {
272 | #if swift(>=3)
273 | self.init(kind: .pawn, color: color)
274 | #else
275 | self.init(kind: .Pawn, color: color)
276 | #endif
277 | }
278 |
279 | /// Create a knight piece with `color`.
280 | public init(knight color: Color) {
281 | #if swift(>=3)
282 | self.init(kind: .knight, color: color)
283 | #else
284 | self.init(kind: .Knight, color: color)
285 | #endif
286 | }
287 |
288 | /// Create a bishop piece with `color`.
289 | public init(bishop color: Color) {
290 | #if swift(>=3)
291 | self.init(kind: .bishop, color: color)
292 | #else
293 | self.init(kind: .Bishop, color: color)
294 | #endif
295 | }
296 |
297 | /// Create a rook piece with `color`.
298 | public init(rook color: Color) {
299 | #if swift(>=3)
300 | self.init(kind: .rook, color: color)
301 | #else
302 | self.init(kind: .Rook, color: color)
303 | #endif
304 | }
305 |
306 | /// Create a queen piece with `color`.
307 | public init(queen color: Color) {
308 | #if swift(>=3)
309 | self.init(kind: .queen, color: color)
310 | #else
311 | self.init(kind: .Queen, color: color)
312 | #endif
313 | }
314 |
315 | /// Create a king piece with `color`.
316 | public init(king color: Color) {
317 | #if swift(>=3)
318 | self.init(kind: .king, color: color)
319 | #else
320 | self.init(kind: .King, color: color)
321 | #endif
322 | }
323 |
324 | /// Create a piece from a character.
325 | public init?(character: Character) {
326 | switch character {
327 | case "P": self.init(pawn: ._white)
328 | case "p": self.init(pawn: ._black)
329 | case "N": self.init(knight: ._white)
330 | case "n": self.init(knight: ._black)
331 | case "B": self.init(bishop: ._white)
332 | case "b": self.init(bishop: ._black)
333 | case "R": self.init(rook: ._white)
334 | case "r": self.init(rook: ._black)
335 | case "Q": self.init(queen: ._white)
336 | case "q": self.init(queen: ._black)
337 | case "K": self.init(king: ._white)
338 | case "k": self.init(king: ._black)
339 | default:
340 | return nil
341 | }
342 | }
343 |
344 | /// Returns `true` if `self` can be a promotion for `other`.
345 | public func canPromote(_ other: Piece) -> Bool {
346 | return kind.canPromote(other.kind) && color == other.color
347 | }
348 |
349 | /// Returns `true` if `self` can be a promotion for `color`.
350 | public func canPromote(_ color: Color) -> Bool {
351 | return kind.canPromote() ? self.color == color : false
352 | }
353 |
354 | /// The special character for the piece.
355 | public func specialCharacter(background color: Color = ._white) -> Character {
356 | #if swift(>=3)
357 | switch kind {
358 | case .pawn: return color == self.color ? "♙" : "♟"
359 | case .knight: return color == self.color ? "♘" : "♞"
360 | case .bishop: return color == self.color ? "♗" : "♝"
361 | case .rook: return color == self.color ? "♖" : "♜"
362 | case .queen: return color == self.color ? "♕" : "♛"
363 | case .king: return color == self.color ? "♔" : "♚"
364 | }
365 | #else
366 | switch kind {
367 | case .Pawn: return color == self.color ? "♙" : "♟"
368 | case .Knight: return color == self.color ? "♘" : "♞"
369 | case .Bishop: return color == self.color ? "♗" : "♝"
370 | case .Rook: return color == self.color ? "♖" : "♜"
371 | case .Queen: return color == self.color ? "♕" : "♛"
372 | case .King: return color == self.color ? "♔" : "♚"
373 | }
374 | #endif
375 | }
376 |
377 | }
378 |
379 | /// Returns `true` if both pieces are the same.
380 | public func == (lhs: Piece, rhs: Piece) -> Bool {
381 | return lhs.kind == rhs.kind
382 | && lhs.color == rhs.color
383 | }
384 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Player.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Player.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess game player.
21 | public struct Player: Equatable, CustomStringConvertible {
22 |
23 | /// A player kind.
24 | public enum Kind: String, CustomStringConvertible {
25 |
26 | #if swift(>=3)
27 |
28 | /// Human player kind.
29 | case human = "Human"
30 |
31 | /// Computer player kind.
32 | case computer = "Computer"
33 |
34 | /// Human regardless of Swift version.
35 | internal static let _human = Kind.human
36 |
37 | /// Computer regardless of Swift version.
38 | internal static let _computer = Kind.computer
39 |
40 | #else
41 |
42 | /// Human player kind.
43 | case Human
44 |
45 | /// Computer player kind.
46 | case Computer
47 |
48 | /// Human regardless of Swift version.
49 | internal static let _human = Kind.Human
50 |
51 | /// Computer regardless of Swift version.
52 | internal static let _computer = Kind.Computer
53 |
54 | #endif
55 |
56 | /// Boolean indicating `self` is a human.
57 | public var isHuman: Bool {
58 | return self == ._human
59 | }
60 |
61 | /// Boolean indicating `self` is a computer.
62 | public var isComputer: Bool {
63 | return self == ._computer
64 | }
65 |
66 | /// A textual representation of this instance.
67 | public var description: String {
68 | return rawValue
69 | }
70 |
71 | }
72 |
73 | /// The the player's kind.
74 | public var kind: Kind
75 |
76 | /// The player's name.
77 | public var name: String?
78 |
79 | /// The player's elo rating.
80 | public var elo: UInt?
81 |
82 | /// A textual representation of this instance.
83 | public var description: String {
84 | return "Player(kind: \(kind), name: \(name._altDescription), elo: \(elo._altDescription))"
85 | }
86 |
87 | /// Create a player with `kind` and `name`.
88 | ///
89 | /// - parameter kind: The player's kind. Default is human.
90 | /// - parameter name: The player's name. Default is `nil`.
91 | /// - parameter elo: The player's elo rating. Default is `nil`.
92 | public init(kind: Kind = ._human, name: String? = nil, elo: UInt? = nil) {
93 | self.kind = kind
94 | self.name = name
95 | self.elo = elo
96 | }
97 |
98 | }
99 |
100 | /// Returns `true` if the players are the same.
101 | public func == (lhs: Player, rhs: Player) -> Bool {
102 | return lhs.kind == rhs.kind
103 | && lhs.name == rhs.name
104 | && lhs.elo == rhs.elo
105 | }
106 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Rank.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Rank.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess board rank.
21 | ///
22 | /// `Rank`s refer to the eight rows of a chess board, beginning with 1 at the bottom and ending with 8 at the top.
23 | public enum Rank: Int, Comparable, CustomStringConvertible {
24 |
25 | /// A direction in rank.
26 | public enum Direction {
27 |
28 | #if swift(>=3)
29 |
30 | /// Up direction.
31 | case up
32 |
33 | /// Down direction.
34 | case down
35 |
36 | #else
37 |
38 | /// Up direction.
39 | case Up
40 |
41 | /// Down direction.
42 | case Down
43 |
44 | #endif
45 |
46 | }
47 |
48 | #if swift(>=3)
49 |
50 | /// Rank 1.
51 | case one = 1
52 |
53 | /// Rank 2.
54 | case two = 2
55 |
56 | /// Rank 3.
57 | case three = 3
58 |
59 | /// Rank 4.
60 | case four = 4
61 |
62 | /// Rank 5.
63 | case five = 5
64 |
65 | /// Rank 6.
66 | case six = 6
67 |
68 | /// Rank 7.
69 | case seven = 7
70 |
71 | /// Rank 8.
72 | case eight = 8
73 |
74 | #else
75 |
76 | /// Rank 1.
77 | case One = 1
78 |
79 | /// Rank 2.
80 | case Two = 2
81 |
82 | /// Rank 3.
83 | case Three = 3
84 |
85 | /// Rank 4.
86 | case Four = 4
87 |
88 | /// Rank 5.
89 | case Five = 5
90 |
91 | /// Rank 6.
92 | case Six = 6
93 |
94 | /// Rank 7.
95 | case Seven = 7
96 |
97 | /// Rank 8.
98 | case Eight = 8
99 |
100 | #endif
101 |
102 | }
103 |
104 | extension Rank {
105 |
106 | /// An array of all ranks.
107 | public static let all: [Rank] = [1, 2, 3, 4, 5, 6, 7, 8]
108 |
109 | /// The row index of `self`.
110 | public var index: Int {
111 | return rawValue - 1
112 | }
113 |
114 | /// A textual representation of `self`.
115 | public var description: String {
116 | return String(rawValue)
117 | }
118 |
119 | /// Create an instance from an integer value.
120 | public init?(_ value: Int) {
121 | self.init(rawValue: value)
122 | }
123 |
124 | /// Create a `Rank` from a zero-based row index.
125 | public init?(index: Int) {
126 | self.init(rawValue: index + 1)
127 | }
128 |
129 | /// Creates the starting `Rank` for the color.
130 | public init(startFor color: Color) {
131 | self = color.isWhite ? 1 : 8
132 | }
133 |
134 | /// Creates the ending `Rank` for the color.
135 | public init(endFor color: Color) {
136 | self = color.isWhite ? 8 : 1
137 | }
138 |
139 | /// Returns a rank from advancing `self` by `value` with respect to `color`.
140 | public func advanced(by value: Int, for color: Color = ._white) -> Rank? {
141 | return Rank(rawValue: rawValue + (color.isWhite ? value : -value))
142 | }
143 |
144 | /// The next rank after `self`.
145 | public func next() -> Rank? {
146 | return Rank(rawValue: (rawValue + 1))
147 | }
148 |
149 | /// The previous rank to `self`.
150 | public func previous() -> Rank? {
151 | return Rank(rawValue: (rawValue - 1))
152 | }
153 |
154 | /// The opposite rank of `self`.
155 | public func opposite() -> Rank {
156 | return Rank(rawValue: 9 - rawValue)!
157 | }
158 |
159 | /// The files from `self` to `other`.
160 | public func to(_ other: Rank) -> [Rank] {
161 | if other > self {
162 | return (rawValue...other.rawValue).flatMap(Rank.init(rawValue:))
163 | } else if other < self {
164 | #if swift(>=3)
165 | let values = (other.rawValue...rawValue).reversed()
166 | #else
167 | let values = (other.rawValue...rawValue).reverse()
168 | #endif
169 | return values.flatMap(Rank.init(rawValue:))
170 | } else {
171 | return [self]
172 | }
173 | }
174 |
175 | /// The files between `self` and `other`.
176 | public func between(_ other: Rank) -> [Rank] {
177 | if other > self {
178 | return (rawValue + 1 ..< other.rawValue).flatMap(Rank.init(rawValue:))
179 | } else if other < self {
180 | #if swift(>=3)
181 | let values = (other.rawValue + 1 ..< rawValue).reversed()
182 | #else
183 | let values = (other.rawValue + 1 ..< rawValue).reverse()
184 | #endif
185 | return values.flatMap(Rank.init(rawValue:))
186 | } else {
187 | return []
188 | }
189 | }
190 |
191 | }
192 |
193 | extension Rank: IntegerLiteralConvertible {
194 |
195 | /// Create an instance initialized to `value`.
196 | public init(integerLiteral value: Int) {
197 | guard let rank = Rank(rawValue: value) else {
198 | fatalError("Rank value not within 1 and 8, inclusive")
199 | }
200 | self = rank
201 | }
202 |
203 | }
204 |
205 | /// Returns `true` if one rank is higher than the other.
206 | public func < (lhs: Rank, rhs: Rank) -> Bool {
207 | return lhs.rawValue < rhs.rawValue
208 | }
209 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Sequence+Sage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Sequence+Sage.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #if swift(>=3)
21 |
22 | extension Sequence where Iterator.Element == Square {
23 |
24 | /// Returns moves from `square` to the squares in `self`.
25 | public func moves(from square: Square) -> [Move] {
26 | return self.map({ square >>> $0 })
27 | }
28 |
29 | /// Returns moves from the squares in `self` to `square`.
30 | public func moves(to square: Square) -> [Move] {
31 | return self.map({ $0 >>> square })
32 | }
33 |
34 | }
35 |
36 | #else
37 |
38 | extension SequenceType where Generator.Element == Square {
39 |
40 | /// Returns moves from `square` to the squares in `self`.
41 | public func moves(from square: Square) -> [Move] {
42 | return self.map({ square >>> $0 })
43 | }
44 |
45 | /// Returns moves from the squares in `self` to `square`.
46 | public func moves(to square: Square) -> [Move] {
47 | return self.map({ $0 >>> square })
48 | }
49 |
50 | }
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Square.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Square.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A pair of a chess board `File` and `Rank`.
21 | public typealias Location = (file: File, rank: Rank)
22 |
23 | /// A chess board square.
24 | ///
25 | /// A `Square` can be one of sixty-four possible values, ranging from `A1` to `H8`.
26 | public enum Square: Int, CustomStringConvertible {
27 |
28 | #if swift(>=3)
29 |
30 | /// A1 square.
31 | case a1
32 |
33 | /// B1 square.
34 | case b1
35 |
36 | /// C1 square.
37 | case c1
38 |
39 | /// D1 square.
40 | case d1
41 |
42 | /// E1 square.
43 | case e1
44 |
45 | /// F1 square.
46 | case f1
47 |
48 | /// G1 square.
49 | case g1
50 |
51 | /// H1 square.
52 | case h1
53 |
54 | /// A2 square.
55 | case a2
56 |
57 | /// B2 square.
58 | case b2
59 |
60 | /// C2 square.
61 | case c2
62 |
63 | /// D2 square.
64 | case d2
65 |
66 | /// E2 square.
67 | case e2
68 |
69 | /// F2 square.
70 | case f2
71 |
72 | /// G2 square.
73 | case g2
74 |
75 | /// H2 square.
76 | case h2
77 |
78 | /// A3 square.
79 | case a3
80 |
81 | /// B3 square.
82 | case b3
83 |
84 | /// C3 square.
85 | case c3
86 |
87 | /// D3 square.
88 | case d3
89 |
90 | /// E3 square.
91 | case e3
92 |
93 | /// F3 square.
94 | case f3
95 |
96 | /// G3 square.
97 | case g3
98 |
99 | /// H3 square.
100 | case h3
101 |
102 | /// A4 square.
103 | case a4
104 |
105 | /// B4 square.
106 | case b4
107 |
108 | /// C4 square.
109 | case c4
110 |
111 | /// D4 square.
112 | case d4
113 |
114 | /// E4 square.
115 | case e4
116 |
117 | /// F4 square.
118 | case f4
119 |
120 | /// G4 square.
121 | case g4
122 |
123 | /// H4 square.
124 | case h4
125 |
126 | /// A5 square.
127 | case a5
128 |
129 | /// B5 square.
130 | case b5
131 |
132 | /// C5 square.
133 | case c5
134 |
135 | /// D5 square.
136 | case d5
137 |
138 | /// E5 square.
139 | case e5
140 |
141 | /// F5 square.
142 | case f5
143 |
144 | /// G5 square.
145 | case g5
146 |
147 | /// H5 square.
148 | case h5
149 |
150 | /// A6 square.
151 | case a6
152 |
153 | /// B6 square.
154 | case b6
155 |
156 | /// C6 square.
157 | case c6
158 |
159 | /// D6 square.
160 | case d6
161 |
162 | /// E6 square.
163 | case e6
164 |
165 | /// F6 square.
166 | case f6
167 |
168 | /// G6 square.
169 | case g6
170 |
171 | /// H6 square.
172 | case h6
173 |
174 | /// A7 square.
175 | case a7
176 |
177 | /// B7 square.
178 | case b7
179 |
180 | /// C7 square.
181 | case c7
182 |
183 | /// D7 square.
184 | case d7
185 |
186 | /// E7 square.
187 | case e7
188 |
189 | /// F7 square.
190 | case f7
191 |
192 | /// G7 square.
193 | case g7
194 |
195 | /// H7 square.
196 | case h7
197 |
198 | /// A8 square.
199 | case a8
200 |
201 | /// B8 square.
202 | case b8
203 |
204 | /// C8 square.
205 | case c8
206 |
207 | /// D8 square.
208 | case d8
209 |
210 | /// E8 square.
211 | case e8
212 |
213 | /// F8 square.
214 | case f8
215 |
216 | /// G8 square.
217 | case g8
218 |
219 | /// H8 square.
220 | case h8
221 |
222 | #else
223 |
224 | /// A1 square.
225 | case A1
226 |
227 | /// B1 square.
228 | case B1
229 |
230 | /// C1 square.
231 | case C1
232 |
233 | /// D1 square.
234 | case D1
235 |
236 | /// E1 square.
237 | case E1
238 |
239 | /// F1 square.
240 | case F1
241 |
242 | /// G1 square.
243 | case G1
244 |
245 | /// H1 square.
246 | case H1
247 |
248 | /// A2 square.
249 | case A2
250 |
251 | /// B2 square.
252 | case B2
253 |
254 | /// C2 square.
255 | case C2
256 |
257 | /// D2 square.
258 | case D2
259 |
260 | /// E2 square.
261 | case E2
262 |
263 | /// F2 square.
264 | case F2
265 |
266 | /// G2 square.
267 | case G2
268 |
269 | /// H2 square.
270 | case H2
271 |
272 | /// A3 square.
273 | case A3
274 |
275 | /// B3 square.
276 | case B3
277 |
278 | /// C3 square.
279 | case C3
280 |
281 | /// D3 square.
282 | case D3
283 |
284 | /// E3 square.
285 | case E3
286 |
287 | /// F3 square.
288 | case F3
289 |
290 | /// G3 square.
291 | case G3
292 |
293 | /// H3 square.
294 | case H3
295 |
296 | /// A4 square.
297 | case A4
298 |
299 | /// B4 square.
300 | case B4
301 |
302 | /// C4 square.
303 | case C4
304 |
305 | /// D4 square.
306 | case D4
307 |
308 | /// E4 square.
309 | case E4
310 |
311 | /// F4 square.
312 | case F4
313 |
314 | /// G4 square.
315 | case G4
316 |
317 | /// H4 square.
318 | case H4
319 |
320 | /// A5 square.
321 | case A5
322 |
323 | /// B5 square.
324 | case B5
325 |
326 | /// C5 square.
327 | case C5
328 |
329 | /// D5 square.
330 | case D5
331 |
332 | /// E5 square.
333 | case E5
334 |
335 | /// F5 square.
336 | case F5
337 |
338 | /// G5 square.
339 | case G5
340 |
341 | /// H5 square.
342 | case H5
343 |
344 | /// A6 square.
345 | case A6
346 |
347 | /// B6 square.
348 | case B6
349 |
350 | /// C6 square.
351 | case C6
352 |
353 | /// D6 square.
354 | case D6
355 |
356 | /// E6 square.
357 | case E6
358 |
359 | /// F6 square.
360 | case F6
361 |
362 | /// G6 square.
363 | case G6
364 |
365 | /// H6 square.
366 | case H6
367 |
368 | /// A7 square.
369 | case A7
370 |
371 | /// B7 square.
372 | case B7
373 |
374 | /// C7 square.
375 | case C7
376 |
377 | /// D7 square.
378 | case D7
379 |
380 | /// E7 square.
381 | case E7
382 |
383 | /// F7 square.
384 | case F7
385 |
386 | /// G7 square.
387 | case G7
388 |
389 | /// H7 square.
390 | case H7
391 |
392 | /// A8 square.
393 | case A8
394 |
395 | /// B8 square.
396 | case B8
397 |
398 | /// C8 square.
399 | case C8
400 |
401 | /// D8 square.
402 | case D8
403 |
404 | /// E8 square.
405 | case E8
406 |
407 | /// F8 square.
408 | case F8
409 |
410 | /// G8 square.
411 | case G8
412 |
413 | /// H8 square.
414 | case H8
415 |
416 | #endif
417 |
418 | }
419 |
420 | extension Square {
421 |
422 | /// An array of all squares.
423 | public static let all: [Square] = (0 ..< 64).flatMap(Square.init(rawValue:))
424 |
425 | /// The file of `self`.
426 | public var file: File {
427 | get {
428 | return File(index: rawValue & 7)!
429 | }
430 | set(newFile) {
431 | self = Square(file: newFile, rank: rank)
432 | }
433 | }
434 |
435 | /// The rank of `self`.
436 | public var rank: Rank {
437 | get {
438 | return Rank(index: rawValue >> 3)!
439 | }
440 | set(newRank) {
441 | self = Square(file: file, rank: newRank)
442 | }
443 | }
444 |
445 | /// The location of `self`.
446 | public var location: Location {
447 | get {
448 | return (file, rank)
449 | }
450 | set(newLocation) {
451 | self = Square(location: newLocation)
452 | }
453 | }
454 |
455 | /// The square's color.
456 | public var color: Color {
457 | return (file.index & 1 != rank.index & 1) ? ._white : ._black
458 | }
459 |
460 | /// A textual representation of `self`.
461 | public var description: String {
462 | return "\(file)\(rank)"
463 | }
464 |
465 | /// Create a square from `file` and `rank`.
466 | public init(file: File, rank: Rank) {
467 | self.init(rawValue: file.index + (rank.index << 3))!
468 | }
469 |
470 | /// Create a square from `location`.
471 | public init(location: Location) {
472 | self.init(file: location.file, rank: location.rank)
473 | }
474 |
475 | /// Create a square from `file` and `rank`. Returns `nil` if either is `nil`.
476 | public init?(file: File?, rank: Rank?) {
477 | guard let file = file, rank = rank else {
478 | return nil
479 | }
480 | self.init(file: file, rank: rank)
481 | }
482 |
483 | /// Create a square from `string`.
484 | public init?(_ string: String) {
485 | let chars = string.characters
486 | guard chars.count == 2 else {
487 | return nil
488 | }
489 | guard let file = File(chars.first!) else {
490 | return nil
491 | }
492 | guard let rank = Int(String(chars.last!)).flatMap(Rank.init(_:)) else {
493 | return nil
494 | }
495 | self.init(file: file, rank: rank)
496 | }
497 |
498 | /// Returns a bitboard mask of attacks for a king at `self`.
499 | public func kingAttacks() -> Bitboard {
500 | return _kingAttackTable[rawValue]
501 | }
502 |
503 | /// Returns a bitboard mask of attacks for a knight at `self`.
504 | public func knightAttacks() -> Bitboard {
505 | return _knightAttackTable[rawValue]
506 | }
507 |
508 | /// Returns a bitboard mask of attacks for a piece at `self`.
509 | ///
510 | /// - parameter piece: The piece for the attacks.
511 | /// - parameter stoppers: The pieces stopping a sliding move. The returned bitboard includes the stopped space.
512 | ///
513 | /// - seealso: `attackMoves(for:stoppers:)`
514 | public func attacks(for piece: Piece, stoppers: Bitboard = 0) -> Bitboard {
515 | #if swift(>=3)
516 | switch piece.kind {
517 | case .king:
518 | return kingAttacks()
519 | case .knight:
520 | return knightAttacks()
521 | case .pawn:
522 | return _pawnAttackTable(for: piece.color)[rawValue]
523 | default:
524 | return Bitboard(square: self)._attacks(for: piece, stoppers: stoppers)
525 | }
526 | #else
527 | switch piece.kind {
528 | case .King:
529 | return kingAttacks()
530 | case .Knight:
531 | return knightAttacks()
532 | case .Pawn:
533 | return _pawnAttackTable(for: piece.color)[rawValue]
534 | default:
535 | return Bitboard(square: self)._attacks(for: piece, stoppers: stoppers)
536 | }
537 | #endif
538 | }
539 |
540 | /// Returns an array of attack moves for a piece at `self`.
541 | ///
542 | /// - seealso: `attacks(for:stoppers:)`
543 | public func attackMoves(for piece: Piece, stoppers: Bitboard = 0) -> [Move] {
544 | return attacks(for: piece, stoppers: stoppers).moves(from: self)
545 | }
546 |
547 | #if swift(>=3)
548 |
549 | /// Returns moves from the squares in `squares` to `self`.
550 | public func moves(from squares: S) -> [Move] {
551 | return squares.moves(to: self)
552 | }
553 |
554 | /// Returns moves from `self` to the squares in `squares`.
555 | public func moves(to squares: S) -> [Move] {
556 | return squares.moves(from: self)
557 | }
558 |
559 | #else
560 |
561 | /// Returns moves from the squares in `squares` to `self`.
562 | public func moves(from squares: S) -> [Move] {
563 | return squares.moves(to: self)
564 | }
565 |
566 | /// Returns moves from `self` to the squares in `squares`.
567 | public func moves(to squares: S) -> [Move] {
568 | return squares.moves(from: self)
569 | }
570 |
571 | #endif
572 |
573 | }
574 |
575 | extension Square: StringLiteralConvertible {
576 |
577 | /// Create an instance initialized to `value`.
578 | public init(stringLiteral value: String) {
579 | guard let square = Square(value) else {
580 | fatalError("Invalid string for square: \"\(value)\"")
581 | }
582 | self = square
583 | }
584 |
585 | /// Create an instance initialized to `value`.
586 | public init(unicodeScalarLiteral value: String) {
587 | self.init(stringLiteral: value)
588 | }
589 |
590 | /// Create an instance initialized to `value`.
591 | public init(extendedGraphemeClusterLiteral value: String) {
592 | self.init(stringLiteral: value)
593 | }
594 |
595 | }
596 |
--------------------------------------------------------------------------------
/Pods/Sage/Sources/Variant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Variant.swift
3 | // Sage
4 | //
5 | // Copyright 2016 Nikolai Vazquez
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | /// A chess variant that defines how a `Board` is populated or how a `Game` is played.
21 | public enum Variant {
22 |
23 | #if swift(>=3)
24 |
25 | /// Standard chess.
26 | case standard
27 |
28 | /// Upside down chess where the piece colors swap starting squares.
29 | case upsideDown
30 |
31 | /// Standard regardless of Swift version.
32 | internal static let _standard = Variant.standard
33 |
34 | /// UpsideDown regardless of Swift version.
35 | internal static let _upsideDown = Variant.upsideDown
36 |
37 | #else
38 |
39 | /// Standard chess.
40 | case Standard
41 |
42 | /// Upside down chess where the piece colors swap starting squares.
43 | case UpsideDown
44 |
45 | /// Standard regardless of Swift version.
46 | internal static let _standard = Variant.Standard
47 |
48 | /// UpsideDown regardless of Swift version.
49 | internal static let _upsideDown = Variant.UpsideDown
50 |
51 | #endif
52 |
53 | /// `self` is standard variant.
54 | public var isStandard: Bool {
55 | return self == ._standard
56 | }
57 |
58 | /// `self` is upside down variant.
59 | public var isUpsideDown: Bool {
60 | return self == ._upsideDown
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## Sage
5 |
6 |
7 | Apache License
8 | Version 2.0, January 2004
9 | http://www.apache.org/licenses/
10 |
11 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
12 |
13 | 1. Definitions.
14 |
15 | "License" shall mean the terms and conditions for use, reproduction,
16 | and distribution as defined by Sections 1 through 9 of this document.
17 |
18 | "Licensor" shall mean the copyright owner or entity authorized by
19 | the copyright owner that is granting the License.
20 |
21 | "Legal Entity" shall mean the union of the acting entity and all
22 | other entities that control, are controlled by, or are under common
23 | control with that entity. For the purposes of this definition,
24 | "control" means (i) the power, direct or indirect, to cause the
25 | direction or management of such entity, whether by contract or
26 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
27 | outstanding shares, or (iii) beneficial ownership of such entity.
28 |
29 | "You" (or "Your") shall mean an individual or Legal Entity
30 | exercising permissions granted by this License.
31 |
32 | "Source" form shall mean the preferred form for making modifications,
33 | including but not limited to software source code, documentation
34 | source, and configuration files.
35 |
36 | "Object" form shall mean any form resulting from mechanical
37 | transformation or translation of a Source form, including but
38 | not limited to compiled object code, generated documentation,
39 | and conversions to other media types.
40 |
41 | "Work" shall mean the work of authorship, whether in Source or
42 | Object form, made available under the License, as indicated by a
43 | copyright notice that is included in or attached to the work
44 | (an example is provided in the Appendix below).
45 |
46 | "Derivative Works" shall mean any work, whether in Source or Object
47 | form, that is based on (or derived from) the Work and for which the
48 | editorial revisions, annotations, elaborations, or other modifications
49 | represent, as a whole, an original work of authorship. For the purposes
50 | of this License, Derivative Works shall not include works that remain
51 | separable from, or merely link (or bind by name) to the interfaces of,
52 | the Work and Derivative Works thereof.
53 |
54 | "Contribution" shall mean any work of authorship, including
55 | the original version of the Work and any modifications or additions
56 | to that Work or Derivative Works thereof, that is intentionally
57 | submitted to Licensor for inclusion in the Work by the copyright owner
58 | or by an individual or Legal Entity authorized to submit on behalf of
59 | the copyright owner. For the purposes of this definition, "submitted"
60 | means any form of electronic, verbal, or written communication sent
61 | to the Licensor or its representatives, including but not limited to
62 | communication on electronic mailing lists, source code control systems,
63 | and issue tracking systems that are managed by, or on behalf of, the
64 | Licensor for the purpose of discussing and improving the Work, but
65 | excluding communication that is conspicuously marked or otherwise
66 | designated in writing by the copyright owner as "Not a Contribution."
67 |
68 | "Contributor" shall mean Licensor and any individual or Legal Entity
69 | on behalf of whom a Contribution has been received by Licensor and
70 | subsequently incorporated within the Work.
71 |
72 | 2. Grant of Copyright License. Subject to the terms and conditions of
73 | this License, each Contributor hereby grants to You a perpetual,
74 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
75 | copyright license to reproduce, prepare Derivative Works of,
76 | publicly display, publicly perform, sublicense, and distribute the
77 | Work and such Derivative Works in Source or Object form.
78 |
79 | 3. Grant of Patent License. Subject to the terms and conditions of
80 | this License, each Contributor hereby grants to You a perpetual,
81 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
82 | (except as stated in this section) patent license to make, have made,
83 | use, offer to sell, sell, import, and otherwise transfer the Work,
84 | where such license applies only to those patent claims licensable
85 | by such Contributor that are necessarily infringed by their
86 | Contribution(s) alone or by combination of their Contribution(s)
87 | with the Work to which such Contribution(s) was submitted. If You
88 | institute patent litigation against any entity (including a
89 | cross-claim or counterclaim in a lawsuit) alleging that the Work
90 | or a Contribution incorporated within the Work constitutes direct
91 | or contributory patent infringement, then any patent licenses
92 | granted to You under this License for that Work shall terminate
93 | as of the date such litigation is filed.
94 |
95 | 4. Redistribution. You may reproduce and distribute copies of the
96 | Work or Derivative Works thereof in any medium, with or without
97 | modifications, and in Source or Object form, provided that You
98 | meet the following conditions:
99 |
100 | (a) You must give any other recipients of the Work or
101 | Derivative Works a copy of this License; and
102 |
103 | (b) You must cause any modified files to carry prominent notices
104 | stating that You changed the files; and
105 |
106 | (c) You must retain, in the Source form of any Derivative Works
107 | that You distribute, all copyright, patent, trademark, and
108 | attribution notices from the Source form of the Work,
109 | excluding those notices that do not pertain to any part of
110 | the Derivative Works; and
111 |
112 | (d) If the Work includes a "NOTICE" text file as part of its
113 | distribution, then any Derivative Works that You distribute must
114 | include a readable copy of the attribution notices contained
115 | within such NOTICE file, excluding those notices that do not
116 | pertain to any part of the Derivative Works, in at least one
117 | of the following places: within a NOTICE text file distributed
118 | as part of the Derivative Works; within the Source form or
119 | documentation, if provided along with the Derivative Works; or,
120 | within a display generated by the Derivative Works, if and
121 | wherever such third-party notices normally appear. The contents
122 | of the NOTICE file are for informational purposes only and
123 | do not modify the License. You may add Your own attribution
124 | notices within Derivative Works that You distribute, alongside
125 | or as an addendum to the NOTICE text from the Work, provided
126 | that such additional attribution notices cannot be construed
127 | as modifying the License.
128 |
129 | You may add Your own copyright statement to Your modifications and
130 | may provide additional or different license terms and conditions
131 | for use, reproduction, or distribution of Your modifications, or
132 | for any such Derivative Works as a whole, provided Your use,
133 | reproduction, and distribution of the Work otherwise complies with
134 | the conditions stated in this License.
135 |
136 | 5. Submission of Contributions. Unless You explicitly state otherwise,
137 | any Contribution intentionally submitted for inclusion in the Work
138 | by You to the Licensor shall be under the terms and conditions of
139 | this License, without any additional terms or conditions.
140 | Notwithstanding the above, nothing herein shall supersede or modify
141 | the terms of any separate license agreement you may have executed
142 | with Licensor regarding such Contributions.
143 |
144 | 6. Trademarks. This License does not grant permission to use the trade
145 | names, trademarks, service marks, or product names of the Licensor,
146 | except as required for reasonable and customary use in describing the
147 | origin of the Work and reproducing the content of the NOTICE file.
148 |
149 | 7. Disclaimer of Warranty. Unless required by applicable law or
150 | agreed to in writing, Licensor provides the Work (and each
151 | Contributor provides its Contributions) on an "AS IS" BASIS,
152 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
153 | implied, including, without limitation, any warranties or conditions
154 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
155 | PARTICULAR PURPOSE. You are solely responsible for determining the
156 | appropriateness of using or redistributing the Work and assume any
157 | risks associated with Your exercise of permissions under this License.
158 |
159 | 8. Limitation of Liability. In no event and under no legal theory,
160 | whether in tort (including negligence), contract, or otherwise,
161 | unless required by applicable law (such as deliberate and grossly
162 | negligent acts) or agreed to in writing, shall any Contributor be
163 | liable to You for damages, including any direct, indirect, special,
164 | incidental, or consequential damages of any character arising as a
165 | result of this License or out of the use or inability to use the
166 | Work (including but not limited to damages for loss of goodwill,
167 | work stoppage, computer failure or malfunction, or any and all
168 | other commercial damages or losses), even if such Contributor
169 | has been advised of the possibility of such damages.
170 |
171 | 9. Accepting Warranty or Additional Liability. While redistributing
172 | the Work or Derivative Works thereof, You may choose to offer,
173 | and charge a fee for, acceptance of support, warranty, indemnity,
174 | or other liability obligations and/or rights consistent with this
175 | License. However, in accepting such obligations, You may act only
176 | on Your own behalf and on Your sole responsibility, not on behalf
177 | of any other Contributor, and only if You agree to indemnify,
178 | defend, and hold each Contributor harmless for any liability
179 | incurred by, or claims asserted against, such Contributor by reason
180 | of your accepting any such warranty or additional liability.
181 |
182 | END OF TERMS AND CONDITIONS
183 |
184 | APPENDIX: How to apply the Apache License to your work.
185 |
186 | To apply the Apache License to your work, attach the following
187 | boilerplate notice, with the fields enclosed by brackets "[]"
188 | replaced with your own identifying information. (Don't include
189 | the brackets!) The text should be enclosed in the appropriate
190 | comment syntax for the file format. We also recommend that a
191 | file or class name and description of purpose be included on the
192 | same "printed page" as the copyright notice for easier
193 | identification within third-party archives.
194 |
195 | Copyright [yyyy] [name of copyright owner]
196 |
197 | Licensed under the Apache License, Version 2.0 (the "License");
198 | you may not use this file except in compliance with the License.
199 | You may obtain a copy of the License at
200 |
201 | http://www.apache.org/licenses/LICENSE-2.0
202 |
203 | Unless required by applicable law or agreed to in writing, software
204 | distributed under the License is distributed on an "AS IS" BASIS,
205 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
206 | See the License for the specific language governing permissions and
207 | limitations under the License.
208 |
209 | Generated by CocoaPods - https://cocoapods.org
210 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 |
18 | Apache License
19 | Version 2.0, January 2004
20 | http://www.apache.org/licenses/
21 |
22 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
23 |
24 | 1. Definitions.
25 |
26 | "License" shall mean the terms and conditions for use, reproduction,
27 | and distribution as defined by Sections 1 through 9 of this document.
28 |
29 | "Licensor" shall mean the copyright owner or entity authorized by
30 | the copyright owner that is granting the License.
31 |
32 | "Legal Entity" shall mean the union of the acting entity and all
33 | other entities that control, are controlled by, or are under common
34 | control with that entity. For the purposes of this definition,
35 | "control" means (i) the power, direct or indirect, to cause the
36 | direction or management of such entity, whether by contract or
37 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
38 | outstanding shares, or (iii) beneficial ownership of such entity.
39 |
40 | "You" (or "Your") shall mean an individual or Legal Entity
41 | exercising permissions granted by this License.
42 |
43 | "Source" form shall mean the preferred form for making modifications,
44 | including but not limited to software source code, documentation
45 | source, and configuration files.
46 |
47 | "Object" form shall mean any form resulting from mechanical
48 | transformation or translation of a Source form, including but
49 | not limited to compiled object code, generated documentation,
50 | and conversions to other media types.
51 |
52 | "Work" shall mean the work of authorship, whether in Source or
53 | Object form, made available under the License, as indicated by a
54 | copyright notice that is included in or attached to the work
55 | (an example is provided in the Appendix below).
56 |
57 | "Derivative Works" shall mean any work, whether in Source or Object
58 | form, that is based on (or derived from) the Work and for which the
59 | editorial revisions, annotations, elaborations, or other modifications
60 | represent, as a whole, an original work of authorship. For the purposes
61 | of this License, Derivative Works shall not include works that remain
62 | separable from, or merely link (or bind by name) to the interfaces of,
63 | the Work and Derivative Works thereof.
64 |
65 | "Contribution" shall mean any work of authorship, including
66 | the original version of the Work and any modifications or additions
67 | to that Work or Derivative Works thereof, that is intentionally
68 | submitted to Licensor for inclusion in the Work by the copyright owner
69 | or by an individual or Legal Entity authorized to submit on behalf of
70 | the copyright owner. For the purposes of this definition, "submitted"
71 | means any form of electronic, verbal, or written communication sent
72 | to the Licensor or its representatives, including but not limited to
73 | communication on electronic mailing lists, source code control systems,
74 | and issue tracking systems that are managed by, or on behalf of, the
75 | Licensor for the purpose of discussing and improving the Work, but
76 | excluding communication that is conspicuously marked or otherwise
77 | designated in writing by the copyright owner as "Not a Contribution."
78 |
79 | "Contributor" shall mean Licensor and any individual or Legal Entity
80 | on behalf of whom a Contribution has been received by Licensor and
81 | subsequently incorporated within the Work.
82 |
83 | 2. Grant of Copyright License. Subject to the terms and conditions of
84 | this License, each Contributor hereby grants to You a perpetual,
85 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
86 | copyright license to reproduce, prepare Derivative Works of,
87 | publicly display, publicly perform, sublicense, and distribute the
88 | Work and such Derivative Works in Source or Object form.
89 |
90 | 3. Grant of Patent License. Subject to the terms and conditions of
91 | this License, each Contributor hereby grants to You a perpetual,
92 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
93 | (except as stated in this section) patent license to make, have made,
94 | use, offer to sell, sell, import, and otherwise transfer the Work,
95 | where such license applies only to those patent claims licensable
96 | by such Contributor that are necessarily infringed by their
97 | Contribution(s) alone or by combination of their Contribution(s)
98 | with the Work to which such Contribution(s) was submitted. If You
99 | institute patent litigation against any entity (including a
100 | cross-claim or counterclaim in a lawsuit) alleging that the Work
101 | or a Contribution incorporated within the Work constitutes direct
102 | or contributory patent infringement, then any patent licenses
103 | granted to You under this License for that Work shall terminate
104 | as of the date such litigation is filed.
105 |
106 | 4. Redistribution. You may reproduce and distribute copies of the
107 | Work or Derivative Works thereof in any medium, with or without
108 | modifications, and in Source or Object form, provided that You
109 | meet the following conditions:
110 |
111 | (a) You must give any other recipients of the Work or
112 | Derivative Works a copy of this License; and
113 |
114 | (b) You must cause any modified files to carry prominent notices
115 | stating that You changed the files; and
116 |
117 | (c) You must retain, in the Source form of any Derivative Works
118 | that You distribute, all copyright, patent, trademark, and
119 | attribution notices from the Source form of the Work,
120 | excluding those notices that do not pertain to any part of
121 | the Derivative Works; and
122 |
123 | (d) If the Work includes a "NOTICE" text file as part of its
124 | distribution, then any Derivative Works that You distribute must
125 | include a readable copy of the attribution notices contained
126 | within such NOTICE file, excluding those notices that do not
127 | pertain to any part of the Derivative Works, in at least one
128 | of the following places: within a NOTICE text file distributed
129 | as part of the Derivative Works; within the Source form or
130 | documentation, if provided along with the Derivative Works; or,
131 | within a display generated by the Derivative Works, if and
132 | wherever such third-party notices normally appear. The contents
133 | of the NOTICE file are for informational purposes only and
134 | do not modify the License. You may add Your own attribution
135 | notices within Derivative Works that You distribute, alongside
136 | or as an addendum to the NOTICE text from the Work, provided
137 | that such additional attribution notices cannot be construed
138 | as modifying the License.
139 |
140 | You may add Your own copyright statement to Your modifications and
141 | may provide additional or different license terms and conditions
142 | for use, reproduction, or distribution of Your modifications, or
143 | for any such Derivative Works as a whole, provided Your use,
144 | reproduction, and distribution of the Work otherwise complies with
145 | the conditions stated in this License.
146 |
147 | 5. Submission of Contributions. Unless You explicitly state otherwise,
148 | any Contribution intentionally submitted for inclusion in the Work
149 | by You to the Licensor shall be under the terms and conditions of
150 | this License, without any additional terms or conditions.
151 | Notwithstanding the above, nothing herein shall supersede or modify
152 | the terms of any separate license agreement you may have executed
153 | with Licensor regarding such Contributions.
154 |
155 | 6. Trademarks. This License does not grant permission to use the trade
156 | names, trademarks, service marks, or product names of the Licensor,
157 | except as required for reasonable and customary use in describing the
158 | origin of the Work and reproducing the content of the NOTICE file.
159 |
160 | 7. Disclaimer of Warranty. Unless required by applicable law or
161 | agreed to in writing, Licensor provides the Work (and each
162 | Contributor provides its Contributions) on an "AS IS" BASIS,
163 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
164 | implied, including, without limitation, any warranties or conditions
165 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
166 | PARTICULAR PURPOSE. You are solely responsible for determining the
167 | appropriateness of using or redistributing the Work and assume any
168 | risks associated with Your exercise of permissions under this License.
169 |
170 | 8. Limitation of Liability. In no event and under no legal theory,
171 | whether in tort (including negligence), contract, or otherwise,
172 | unless required by applicable law (such as deliberate and grossly
173 | negligent acts) or agreed to in writing, shall any Contributor be
174 | liable to You for damages, including any direct, indirect, special,
175 | incidental, or consequential damages of any character arising as a
176 | result of this License or out of the use or inability to use the
177 | Work (including but not limited to damages for loss of goodwill,
178 | work stoppage, computer failure or malfunction, or any and all
179 | other commercial damages or losses), even if such Contributor
180 | has been advised of the possibility of such damages.
181 |
182 | 9. Accepting Warranty or Additional Liability. While redistributing
183 | the Work or Derivative Works thereof, You may choose to offer,
184 | and charge a fee for, acceptance of support, warranty, indemnity,
185 | or other liability obligations and/or rights consistent with this
186 | License. However, in accepting such obligations, You may act only
187 | on Your own behalf and on Your sole responsibility, not on behalf
188 | of any other Contributor, and only if You agree to indemnify,
189 | defend, and hold each Contributor harmless for any liability
190 | incurred by, or claims asserted against, such Contributor by reason
191 | of your accepting any such warranty or additional liability.
192 |
193 | END OF TERMS AND CONDITIONS
194 |
195 | APPENDIX: How to apply the Apache License to your work.
196 |
197 | To apply the Apache License to your work, attach the following
198 | boilerplate notice, with the fields enclosed by brackets "[]"
199 | replaced with your own identifying information. (Don't include
200 | the brackets!) The text should be enclosed in the appropriate
201 | comment syntax for the file format. We also recommend that a
202 | file or class name and description of purpose be included on the
203 | same "printed page" as the copyright notice for easier
204 | identification within third-party archives.
205 |
206 | Copyright [yyyy] [name of copyright owner]
207 |
208 | Licensed under the Apache License, Version 2.0 (the "License");
209 | you may not use this file except in compliance with the License.
210 | You may obtain a copy of the License at
211 |
212 | http://www.apache.org/licenses/LICENSE-2.0
213 |
214 | Unless required by applicable law or agreed to in writing, software
215 | distributed under the License is distributed on an "AS IS" BASIS,
216 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
217 | See the License for the specific language governing permissions and
218 | limitations under the License.
219 |
220 | License
221 | Apache License, Version 2.0
222 | Title
223 | Sage
224 | Type
225 | PSGroupSpecifier
226 |
227 |
228 | FooterText
229 | Generated by CocoaPods - https://cocoapods.org
230 | Title
231 |
232 | Type
233 | PSGroupSpecifier
234 |
235 |
236 | StringsTable
237 | Acknowledgements
238 | Title
239 | Acknowledgements
240 |
241 |
242 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_SwiftChessEngine : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_SwiftChessEngine
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
6 |
7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
8 |
9 | install_framework()
10 | {
11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
12 | local source="${BUILT_PRODUCTS_DIR}/$1"
13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
15 | elif [ -r "$1" ]; then
16 | local source="$1"
17 | fi
18 |
19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
20 |
21 | if [ -L "${source}" ]; then
22 | echo "Symlinked..."
23 | source="$(readlink "${source}")"
24 | fi
25 |
26 | # use filter instead of exclude so missing patterns dont' throw errors
27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
29 |
30 | local basename
31 | basename="$(basename -s .framework "$1")"
32 | binary="${destination}/${basename}.framework/${basename}"
33 | if ! [ -r "$binary" ]; then
34 | binary="${destination}/${basename}"
35 | fi
36 |
37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
39 | strip_invalid_archs "$binary"
40 | fi
41 |
42 | # Resign the code if required by the build settings to avoid unstable apps
43 | code_sign_if_enabled "${destination}/$(basename "$1")"
44 |
45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
47 | local swift_runtime_libs
48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
49 | for lib in $swift_runtime_libs; do
50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
52 | code_sign_if_enabled "${destination}/${lib}"
53 | done
54 | fi
55 | }
56 |
57 | # Signs a framework with the provided identity
58 | code_sign_if_enabled() {
59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
60 | # Use the current code_sign_identitiy
61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\""
63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1"
64 | fi
65 | }
66 |
67 | # Strip invalid architectures
68 | strip_invalid_archs() {
69 | binary="$1"
70 | # Get architectures for current file
71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
72 | stripped=""
73 | for arch in $archs; do
74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
75 | # Strip non-valid architectures in-place
76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1
77 | stripped="$stripped $arch"
78 | fi
79 | done
80 | if [[ "$stripped" ]]; then
81 | echo "Stripped $binary of architectures:$stripped"
82 | fi
83 | }
84 |
85 |
86 | if [[ "$CONFIGURATION" == "Debug" ]]; then
87 | install_framework "$BUILT_PRODUCTS_DIR/Sage/Sage.framework"
88 | fi
89 | if [[ "$CONFIGURATION" == "Release" ]]; then
90 | install_framework "$BUILT_PRODUCTS_DIR/Sage/Sage.framework"
91 | fi
92 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-resources.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
5 |
6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
7 | > "$RESOURCES_TO_COPY"
8 |
9 | XCASSET_FILES=()
10 |
11 | case "${TARGETED_DEVICE_FAMILY}" in
12 | 1,2)
13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
14 | ;;
15 | 1)
16 | TARGET_DEVICE_ARGS="--target-device iphone"
17 | ;;
18 | 2)
19 | TARGET_DEVICE_ARGS="--target-device ipad"
20 | ;;
21 | *)
22 | TARGET_DEVICE_ARGS="--target-device mac"
23 | ;;
24 | esac
25 |
26 | realpath() {
27 | DIRECTORY="$(cd "${1%/*}" && pwd)"
28 | FILENAME="${1##*/}"
29 | echo "$DIRECTORY/$FILENAME"
30 | }
31 |
32 | install_resource()
33 | {
34 | if [[ "$1" = /* ]] ; then
35 | RESOURCE_PATH="$1"
36 | else
37 | RESOURCE_PATH="${PODS_ROOT}/$1"
38 | fi
39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then
40 | cat << EOM
41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
42 | EOM
43 | exit 1
44 | fi
45 | case $RESOURCE_PATH in
46 | *.storyboard)
47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
49 | ;;
50 | *.xib)
51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
53 | ;;
54 | *.framework)
55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
59 | ;;
60 | *.xcdatamodel)
61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
63 | ;;
64 | *.xcdatamodeld)
65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
67 | ;;
68 | *.xcmappingmodel)
69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
71 | ;;
72 | *.xcassets)
73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH")
74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
75 | ;;
76 | *)
77 | echo "$RESOURCE_PATH"
78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
79 | ;;
80 | esac
81 | }
82 |
83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
88 | fi
89 | rm -f "$RESOURCES_TO_COPY"
90 |
91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
92 | then
93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets).
94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
95 | while read line; do
96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
97 | XCASSET_FILES+=("$line")
98 | fi
99 | done <<<"$OTHER_XCASSETS"
100 |
101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
102 | fi
103 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-umbrella.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 |
4 | FOUNDATION_EXPORT double Pods_SwiftChessEngineVersionNumber;
5 | FOUNDATION_EXPORT const unsigned char Pods_SwiftChessEngineVersionString[];
6 |
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine.debug.xcconfig:
--------------------------------------------------------------------------------
1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Sage"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Sage/Sage.framework/Headers"
6 | OTHER_LDFLAGS = $(inherited) -framework "Sage"
7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
8 | PODS_BUILD_DIR = $BUILD_DIR
9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_ROOT = ${SRCROOT}/Pods
11 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_SwiftChessEngine {
2 | umbrella header "Pods-SwiftChessEngine-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine.release.xcconfig:
--------------------------------------------------------------------------------
1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Sage"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Sage/Sage.framework/Headers"
6 | OTHER_LDFLAGS = $(inherited) -framework "Sage"
7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
8 | PODS_BUILD_DIR = $BUILD_DIR
9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_ROOT = ${SRCROOT}/Pods
11 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Sage/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 2.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Sage/Sage-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Sage : NSObject
3 | @end
4 | @implementation PodsDummy_Sage
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Sage/Sage-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #endif
4 |
5 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Sage/Sage-umbrella.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 |
4 | FOUNDATION_EXPORT double SageVersionNumber;
5 | FOUNDATION_EXPORT const unsigned char SageVersionString[];
6 |
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Sage/Sage.modulemap:
--------------------------------------------------------------------------------
1 | framework module Sage {
2 | umbrella header "Sage-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Sage/Sage.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Sage
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
5 | PODS_BUILD_DIR = $BUILD_DIR
6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwiftChessEngine
2 | Prototype chess engine written in Swift with nvzqz/Sage
3 |
--------------------------------------------------------------------------------
/SwiftChessEngine.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4939D90CC0D47C7C68A5457F /* Pods_SwiftChessEngine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE93CE73D6E5713B0A9868E /* Pods_SwiftChessEngine.framework */; };
11 | BF2DD9621D29714D0028FEAF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2DD9611D29714D0028FEAF /* AppDelegate.swift */; };
12 | BF2DD9641D29714D0028FEAF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2DD9631D29714D0028FEAF /* ViewController.swift */; };
13 | BF2DD9671D29714D0028FEAF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF2DD9651D29714D0028FEAF /* Main.storyboard */; };
14 | BF2DD9691D29714D0028FEAF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF2DD9681D29714D0028FEAF /* Assets.xcassets */; };
15 | BF2DD96C1D29714D0028FEAF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF2DD96A1D29714D0028FEAF /* LaunchScreen.storyboard */; };
16 | BF40C1CA1D2971CD002BD4C3 /* ChessEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF40C1C91D2971CD002BD4C3 /* ChessEngine.swift */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | AE9930E21E305A958ED6B76E /* Pods-SwiftChessEngine.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftChessEngine.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine.debug.xcconfig"; sourceTree = ""; };
21 | BF2DD95E1D29714D0028FEAF /* SwiftChessEngine.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftChessEngine.app; sourceTree = BUILT_PRODUCTS_DIR; };
22 | BF2DD9611D29714D0028FEAF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
23 | BF2DD9631D29714D0028FEAF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
24 | BF2DD9661D29714D0028FEAF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
25 | BF2DD9681D29714D0028FEAF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
26 | BF2DD96B1D29714D0028FEAF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
27 | BF2DD96D1D29714D0028FEAF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
28 | BF40C1C91D2971CD002BD4C3 /* ChessEngine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChessEngine.swift; path = ChessEngine/ChessEngine.swift; sourceTree = ""; };
29 | E85C3F69F4B1350E3584567F /* Pods-SwiftChessEngine.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftChessEngine.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine.release.xcconfig"; sourceTree = ""; };
30 | EBE93CE73D6E5713B0A9868E /* Pods_SwiftChessEngine.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftChessEngine.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31 | /* End PBXFileReference section */
32 |
33 | /* Begin PBXFrameworksBuildPhase section */
34 | BF2DD95B1D29714D0028FEAF /* Frameworks */ = {
35 | isa = PBXFrameworksBuildPhase;
36 | buildActionMask = 2147483647;
37 | files = (
38 | 4939D90CC0D47C7C68A5457F /* Pods_SwiftChessEngine.framework in Frameworks */,
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | BF2DD9551D29714D0028FEAF = {
46 | isa = PBXGroup;
47 | children = (
48 | BF2DD9601D29714D0028FEAF /* SwiftChessEngine */,
49 | BF2DD95F1D29714D0028FEAF /* Products */,
50 | C5064F1E7977FE760E661FC6 /* Pods */,
51 | D7E4110F91DC7D3D417FECED /* Frameworks */,
52 | );
53 | sourceTree = "";
54 | };
55 | BF2DD95F1D29714D0028FEAF /* Products */ = {
56 | isa = PBXGroup;
57 | children = (
58 | BF2DD95E1D29714D0028FEAF /* SwiftChessEngine.app */,
59 | );
60 | name = Products;
61 | sourceTree = "";
62 | };
63 | BF2DD9601D29714D0028FEAF /* SwiftChessEngine */ = {
64 | isa = PBXGroup;
65 | children = (
66 | BF40C1C81D2971B8002BD4C3 /* Chess Engine */,
67 | BF2DD9611D29714D0028FEAF /* AppDelegate.swift */,
68 | BF2DD9631D29714D0028FEAF /* ViewController.swift */,
69 | BF2DD9651D29714D0028FEAF /* Main.storyboard */,
70 | BF2DD9681D29714D0028FEAF /* Assets.xcassets */,
71 | BF2DD96A1D29714D0028FEAF /* LaunchScreen.storyboard */,
72 | BF2DD96D1D29714D0028FEAF /* Info.plist */,
73 | );
74 | path = SwiftChessEngine;
75 | sourceTree = "";
76 | };
77 | BF40C1C81D2971B8002BD4C3 /* Chess Engine */ = {
78 | isa = PBXGroup;
79 | children = (
80 | BF40C1C91D2971CD002BD4C3 /* ChessEngine.swift */,
81 | );
82 | name = "Chess Engine";
83 | sourceTree = "";
84 | };
85 | C5064F1E7977FE760E661FC6 /* Pods */ = {
86 | isa = PBXGroup;
87 | children = (
88 | AE9930E21E305A958ED6B76E /* Pods-SwiftChessEngine.debug.xcconfig */,
89 | E85C3F69F4B1350E3584567F /* Pods-SwiftChessEngine.release.xcconfig */,
90 | );
91 | name = Pods;
92 | sourceTree = "";
93 | };
94 | D7E4110F91DC7D3D417FECED /* Frameworks */ = {
95 | isa = PBXGroup;
96 | children = (
97 | EBE93CE73D6E5713B0A9868E /* Pods_SwiftChessEngine.framework */,
98 | );
99 | name = Frameworks;
100 | sourceTree = "";
101 | };
102 | /* End PBXGroup section */
103 |
104 | /* Begin PBXNativeTarget section */
105 | BF2DD95D1D29714D0028FEAF /* SwiftChessEngine */ = {
106 | isa = PBXNativeTarget;
107 | buildConfigurationList = BF2DD9701D29714D0028FEAF /* Build configuration list for PBXNativeTarget "SwiftChessEngine" */;
108 | buildPhases = (
109 | 67A5302AD14E26823142450C /* [CP] Check Pods Manifest.lock */,
110 | BF2DD95A1D29714D0028FEAF /* Sources */,
111 | BF2DD95B1D29714D0028FEAF /* Frameworks */,
112 | BF2DD95C1D29714D0028FEAF /* Resources */,
113 | F804C1842389F4EFE9ECA707 /* [CP] Embed Pods Frameworks */,
114 | 74721232E3723DFCCCDE0D9D /* [CP] Copy Pods Resources */,
115 | );
116 | buildRules = (
117 | );
118 | dependencies = (
119 | );
120 | name = SwiftChessEngine;
121 | productName = SwiftChessEngine;
122 | productReference = BF2DD95E1D29714D0028FEAF /* SwiftChessEngine.app */;
123 | productType = "com.apple.product-type.application";
124 | };
125 | /* End PBXNativeTarget section */
126 |
127 | /* Begin PBXProject section */
128 | BF2DD9561D29714D0028FEAF /* Project object */ = {
129 | isa = PBXProject;
130 | attributes = {
131 | LastSwiftUpdateCheck = 0800;
132 | LastUpgradeCheck = 0800;
133 | ORGANIZATIONNAME = JaviSoto;
134 | TargetAttributes = {
135 | BF2DD95D1D29714D0028FEAF = {
136 | CreatedOnToolsVersion = 8.0;
137 | DevelopmentTeam = LQ6DVLLL6A;
138 | DevelopmentTeamName = "Javier Soto (Personal Team)";
139 | LastSwiftMigration = 0800;
140 | ProvisioningStyle = Automatic;
141 | };
142 | };
143 | };
144 | buildConfigurationList = BF2DD9591D29714D0028FEAF /* Build configuration list for PBXProject "SwiftChessEngine" */;
145 | compatibilityVersion = "Xcode 3.2";
146 | developmentRegion = English;
147 | hasScannedForEncodings = 0;
148 | knownRegions = (
149 | en,
150 | Base,
151 | );
152 | mainGroup = BF2DD9551D29714D0028FEAF;
153 | productRefGroup = BF2DD95F1D29714D0028FEAF /* Products */;
154 | projectDirPath = "";
155 | projectRoot = "";
156 | targets = (
157 | BF2DD95D1D29714D0028FEAF /* SwiftChessEngine */,
158 | );
159 | };
160 | /* End PBXProject section */
161 |
162 | /* Begin PBXResourcesBuildPhase section */
163 | BF2DD95C1D29714D0028FEAF /* Resources */ = {
164 | isa = PBXResourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | BF2DD96C1D29714D0028FEAF /* LaunchScreen.storyboard in Resources */,
168 | BF2DD9691D29714D0028FEAF /* Assets.xcassets in Resources */,
169 | BF2DD9671D29714D0028FEAF /* Main.storyboard in Resources */,
170 | );
171 | runOnlyForDeploymentPostprocessing = 0;
172 | };
173 | /* End PBXResourcesBuildPhase section */
174 |
175 | /* Begin PBXShellScriptBuildPhase section */
176 | 67A5302AD14E26823142450C /* [CP] Check Pods Manifest.lock */ = {
177 | isa = PBXShellScriptBuildPhase;
178 | buildActionMask = 2147483647;
179 | files = (
180 | );
181 | inputPaths = (
182 | );
183 | name = "[CP] Check Pods Manifest.lock";
184 | outputPaths = (
185 | );
186 | runOnlyForDeploymentPostprocessing = 0;
187 | shellPath = /bin/sh;
188 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
189 | showEnvVarsInLog = 0;
190 | };
191 | 74721232E3723DFCCCDE0D9D /* [CP] Copy Pods Resources */ = {
192 | isa = PBXShellScriptBuildPhase;
193 | buildActionMask = 2147483647;
194 | files = (
195 | );
196 | inputPaths = (
197 | );
198 | name = "[CP] Copy Pods Resources";
199 | outputPaths = (
200 | );
201 | runOnlyForDeploymentPostprocessing = 0;
202 | shellPath = /bin/sh;
203 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-resources.sh\"\n";
204 | showEnvVarsInLog = 0;
205 | };
206 | F804C1842389F4EFE9ECA707 /* [CP] Embed Pods Frameworks */ = {
207 | isa = PBXShellScriptBuildPhase;
208 | buildActionMask = 2147483647;
209 | files = (
210 | );
211 | inputPaths = (
212 | );
213 | name = "[CP] Embed Pods Frameworks";
214 | outputPaths = (
215 | );
216 | runOnlyForDeploymentPostprocessing = 0;
217 | shellPath = /bin/sh;
218 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftChessEngine/Pods-SwiftChessEngine-frameworks.sh\"\n";
219 | showEnvVarsInLog = 0;
220 | };
221 | /* End PBXShellScriptBuildPhase section */
222 |
223 | /* Begin PBXSourcesBuildPhase section */
224 | BF2DD95A1D29714D0028FEAF /* Sources */ = {
225 | isa = PBXSourcesBuildPhase;
226 | buildActionMask = 2147483647;
227 | files = (
228 | BF40C1CA1D2971CD002BD4C3 /* ChessEngine.swift in Sources */,
229 | BF2DD9641D29714D0028FEAF /* ViewController.swift in Sources */,
230 | BF2DD9621D29714D0028FEAF /* AppDelegate.swift in Sources */,
231 | );
232 | runOnlyForDeploymentPostprocessing = 0;
233 | };
234 | /* End PBXSourcesBuildPhase section */
235 |
236 | /* Begin PBXVariantGroup section */
237 | BF2DD9651D29714D0028FEAF /* Main.storyboard */ = {
238 | isa = PBXVariantGroup;
239 | children = (
240 | BF2DD9661D29714D0028FEAF /* Base */,
241 | );
242 | name = Main.storyboard;
243 | sourceTree = "";
244 | };
245 | BF2DD96A1D29714D0028FEAF /* LaunchScreen.storyboard */ = {
246 | isa = PBXVariantGroup;
247 | children = (
248 | BF2DD96B1D29714D0028FEAF /* Base */,
249 | );
250 | name = LaunchScreen.storyboard;
251 | sourceTree = "";
252 | };
253 | /* End PBXVariantGroup section */
254 |
255 | /* Begin XCBuildConfiguration section */
256 | BF2DD96E1D29714D0028FEAF /* Debug */ = {
257 | isa = XCBuildConfiguration;
258 | buildSettings = {
259 | ALWAYS_SEARCH_USER_PATHS = NO;
260 | CLANG_ANALYZER_NONNULL = YES;
261 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
262 | CLANG_CXX_LIBRARY = "libc++";
263 | CLANG_ENABLE_MODULES = YES;
264 | CLANG_ENABLE_OBJC_ARC = YES;
265 | CLANG_WARN_BOOL_CONVERSION = YES;
266 | CLANG_WARN_CONSTANT_CONVERSION = YES;
267 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
268 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
269 | CLANG_WARN_EMPTY_BODY = YES;
270 | CLANG_WARN_ENUM_CONVERSION = YES;
271 | CLANG_WARN_INT_CONVERSION = YES;
272 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
273 | CLANG_WARN_UNREACHABLE_CODE = YES;
274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
275 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
276 | COPY_PHASE_STRIP = NO;
277 | DEBUG_INFORMATION_FORMAT = dwarf;
278 | ENABLE_STRICT_OBJC_MSGSEND = YES;
279 | ENABLE_TESTABILITY = YES;
280 | GCC_C_LANGUAGE_STANDARD = gnu99;
281 | GCC_DYNAMIC_NO_PIC = NO;
282 | GCC_NO_COMMON_BLOCKS = YES;
283 | GCC_OPTIMIZATION_LEVEL = 0;
284 | GCC_PREPROCESSOR_DEFINITIONS = (
285 | "DEBUG=1",
286 | "$(inherited)",
287 | );
288 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
289 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
290 | GCC_WARN_UNDECLARED_SELECTOR = YES;
291 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
292 | GCC_WARN_UNUSED_FUNCTION = YES;
293 | GCC_WARN_UNUSED_VARIABLE = YES;
294 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
295 | MTL_ENABLE_DEBUG_INFO = YES;
296 | ONLY_ACTIVE_ARCH = YES;
297 | SDKROOT = iphoneos;
298 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
299 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
300 | TARGETED_DEVICE_FAMILY = "1,2";
301 | };
302 | name = Debug;
303 | };
304 | BF2DD96F1D29714D0028FEAF /* Release */ = {
305 | isa = XCBuildConfiguration;
306 | buildSettings = {
307 | ALWAYS_SEARCH_USER_PATHS = NO;
308 | CLANG_ANALYZER_NONNULL = YES;
309 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
310 | CLANG_CXX_LIBRARY = "libc++";
311 | CLANG_ENABLE_MODULES = YES;
312 | CLANG_ENABLE_OBJC_ARC = YES;
313 | CLANG_WARN_BOOL_CONVERSION = YES;
314 | CLANG_WARN_CONSTANT_CONVERSION = YES;
315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
316 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
317 | CLANG_WARN_EMPTY_BODY = YES;
318 | CLANG_WARN_ENUM_CONVERSION = YES;
319 | CLANG_WARN_INT_CONVERSION = YES;
320 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
321 | CLANG_WARN_UNREACHABLE_CODE = YES;
322 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
323 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
324 | COPY_PHASE_STRIP = NO;
325 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
326 | ENABLE_NS_ASSERTIONS = NO;
327 | ENABLE_STRICT_OBJC_MSGSEND = YES;
328 | GCC_C_LANGUAGE_STANDARD = gnu99;
329 | GCC_NO_COMMON_BLOCKS = YES;
330 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
331 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
332 | GCC_WARN_UNDECLARED_SELECTOR = YES;
333 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
334 | GCC_WARN_UNUSED_FUNCTION = YES;
335 | GCC_WARN_UNUSED_VARIABLE = YES;
336 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
337 | MTL_ENABLE_DEBUG_INFO = NO;
338 | SDKROOT = iphoneos;
339 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
340 | TARGETED_DEVICE_FAMILY = "1,2";
341 | VALIDATE_PRODUCT = YES;
342 | };
343 | name = Release;
344 | };
345 | BF2DD9711D29714D0028FEAF /* Debug */ = {
346 | isa = XCBuildConfiguration;
347 | baseConfigurationReference = AE9930E21E305A958ED6B76E /* Pods-SwiftChessEngine.debug.xcconfig */;
348 | buildSettings = {
349 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
350 | INFOPLIST_FILE = SwiftChessEngine/Info.plist;
351 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
352 | PRODUCT_BUNDLE_IDENTIFIER = es.javisoto.SwiftChessEngine;
353 | PRODUCT_NAME = "$(TARGET_NAME)";
354 | SWIFT_VERSION = 3.0;
355 | };
356 | name = Debug;
357 | };
358 | BF2DD9721D29714D0028FEAF /* Release */ = {
359 | isa = XCBuildConfiguration;
360 | baseConfigurationReference = E85C3F69F4B1350E3584567F /* Pods-SwiftChessEngine.release.xcconfig */;
361 | buildSettings = {
362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
363 | INFOPLIST_FILE = SwiftChessEngine/Info.plist;
364 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
365 | PRODUCT_BUNDLE_IDENTIFIER = es.javisoto.SwiftChessEngine;
366 | PRODUCT_NAME = "$(TARGET_NAME)";
367 | SWIFT_VERSION = 3.0;
368 | };
369 | name = Release;
370 | };
371 | /* End XCBuildConfiguration section */
372 |
373 | /* Begin XCConfigurationList section */
374 | BF2DD9591D29714D0028FEAF /* Build configuration list for PBXProject "SwiftChessEngine" */ = {
375 | isa = XCConfigurationList;
376 | buildConfigurations = (
377 | BF2DD96E1D29714D0028FEAF /* Debug */,
378 | BF2DD96F1D29714D0028FEAF /* Release */,
379 | );
380 | defaultConfigurationIsVisible = 0;
381 | defaultConfigurationName = Release;
382 | };
383 | BF2DD9701D29714D0028FEAF /* Build configuration list for PBXNativeTarget "SwiftChessEngine" */ = {
384 | isa = XCConfigurationList;
385 | buildConfigurations = (
386 | BF2DD9711D29714D0028FEAF /* Debug */,
387 | BF2DD9721D29714D0028FEAF /* Release */,
388 | );
389 | defaultConfigurationIsVisible = 0;
390 | defaultConfigurationName = Release;
391 | };
392 | /* End XCConfigurationList section */
393 | };
394 | rootObject = BF2DD9561D29714D0028FEAF /* Project object */;
395 | }
396 |
--------------------------------------------------------------------------------
/SwiftChessEngine.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftChessEngine.xcodeproj/project.xcworkspace/xcuserdata/javiers.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaviSoto/SwiftChessEngine/91af170925a6af85522f89db3fabaf3da77cd0eb/SwiftChessEngine.xcodeproj/project.xcworkspace/xcuserdata/javiers.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SwiftChessEngine.xcodeproj/xcuserdata/javiers.xcuserdatad/xcschemes/SwiftChessEngine.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/SwiftChessEngine.xcodeproj/xcuserdata/javiers.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftChessEngine.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | BF2DD95D1D29714D0028FEAF
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwiftChessEngine.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SwiftChessEngine.xcworkspace/xcuserdata/javiers.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaviSoto/SwiftChessEngine/91af170925a6af85522f89db3fabaf3da77cd0eb/SwiftChessEngine.xcworkspace/xcuserdata/javiers.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SwiftChessEngine.xcworkspace/xcuserdata/javiers.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/SwiftChessEngine/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SwiftChessEngine
4 | //
5 | // Created by Javier Soto on 7/3/16.
6 | // Copyright © 2016 JaviSoto. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | return true
19 | }
20 |
21 | func applicationWillResignActive(_ application: UIApplication) {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
24 | }
25 |
26 | func applicationDidEnterBackground(_ application: UIApplication) {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | func applicationWillEnterForeground(_ application: UIApplication) {
32 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
33 | }
34 |
35 | func applicationDidBecomeActive(_ application: UIApplication) {
36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
37 | }
38 |
39 | func applicationWillTerminate(_ application: UIApplication) {
40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
41 | }
42 |
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/SwiftChessEngine/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/SwiftChessEngine/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SwiftChessEngine/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/SwiftChessEngine/ChessEngine/ChessEngine.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ChessEngine.swift
3 | // SwiftChessEngine
4 | //
5 | // Created by Javier Soto on 7/3/16.
6 | // Copyright © 2016 JaviSoto. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Sage
11 |
12 | extension Collection where Iterator.Element == Piece {
13 | var valuation: ChessEngine.Valuation {
14 | return self.lazy.filter { !$0.kind.isKing }.map { $0.kind.relativeValue }.reduce(0, combine: +)
15 | }
16 | }
17 |
18 | private extension Board {
19 | private static let initialBoard = Board()
20 |
21 | func pieces(for color: Color) -> [Piece] {
22 | return color.isWhite ? self.whitePieces : self.blackPieces
23 | }
24 |
25 | func allAttackers(attackingColor: Color) -> Int {
26 | let oppositePiecesSquares = self.squares(for: attackingColor.inverse())
27 |
28 | var total = 0
29 |
30 | for oppositePieceSquare in oppositePiecesSquares {
31 | total += self.attackers(to: oppositePieceSquare, color: attackingColor).count
32 | }
33 |
34 | return total
35 | }
36 |
37 | private func piecesOutsideOriginalPosition(for color: Color) -> Int {
38 | let pieces = self.pieces(for: color)
39 |
40 | var count = 0
41 |
42 | for piece in pieces {
43 | if self.bitboard(for: piece) != Board.initialBoard.bitboard(for: piece) {
44 | count += 1
45 | }
46 | }
47 |
48 | return count
49 | }
50 |
51 | func doubledPawns(for color: Color) -> Int {
52 | let pawnFiles = self.pieces(for: color)
53 | .filter { $0.kind.isPawn }
54 | .flatMap { self.locations(for: $0).map { $0.file.rawValue } }
55 |
56 | let uniqueFiles = Set(pawnFiles)
57 |
58 | return pawnFiles.count - uniqueFiles.count
59 | }
60 | }
61 |
62 | private extension CastlingRights {
63 | private static let whiteCastlingRights: CastlingRights = [.whiteQueenside, .whiteKingside]
64 | private static let blackCastlingRights: CastlingRights = [.blackQueenside, .blackKingside]
65 |
66 | static func rightsFor(color: Color) -> CastlingRights {
67 | return color.isWhite ? self.whiteCastlingRights : self.blackCastlingRights
68 | }
69 |
70 | func canCastle(side: Color) -> Bool {
71 | return !self.intersection(CastlingRights.rightsFor(color: side)).isEmpty
72 | }
73 | }
74 |
75 | extension Game {
76 | func currentPositionValuation() -> ChessEngine.Valuation {
77 | let movingSide = self.position.playerTurn
78 | let oppositeSide = movingSide.inverse()
79 | let board = self.position.board
80 |
81 | var extras: ChessEngine.Valuation = 0
82 |
83 | if board.kingIsChecked(for: oppositeSide) {
84 | extras += 1
85 | }
86 | else if board.kingIsChecked(for: movingSide) {
87 | extras -= 0.3
88 | }
89 |
90 | let myPieces = board.pieceCount(for: movingSide)
91 | let theirPieces = board.pieceCount(for: oppositeSide)
92 |
93 | extras += Double(myPieces - theirPieces) * 0.1
94 |
95 | extras += 0.001 * Double(board.allAttackers(attackingColor: movingSide))
96 | extras -= 0.0005 * Double(board.allAttackers(attackingColor: oppositeSide))
97 | extras += 0.01 * Double(board.piecesOutsideOriginalPosition(for: movingSide))
98 | extras -= 0.01 * Double(board.piecesOutsideOriginalPosition(for: oppositeSide))
99 |
100 | extras -= 0.01 * Double(board.doubledPawns(for: movingSide))
101 | extras += 0.01 * Double(board.doubledPawns(for: oppositeSide))
102 |
103 | let weHaveCastled = self.playedMoves(bySide: movingSide).contains { $0.isCastle() }
104 | let theyHaveCastled = self.playedMoves(bySide: oppositeSide).contains { $0.isCastle() }
105 |
106 | let pointsForCastling: ChessEngine.Valuation = 2
107 | let cantCastlePenalty: ChessEngine.Valuation = -pointsForCastling
108 |
109 | if weHaveCastled {
110 | extras += pointsForCastling
111 | }
112 |
113 | if theyHaveCastled {
114 | extras -= pointsForCastling
115 | }
116 |
117 | let weCanCastle = self.castlingRights.canCastle(side: movingSide)
118 | let theyCanCastle = self.castlingRights.canCastle(side: movingSide.inverse())
119 |
120 | if !weCanCastle {
121 | extras += cantCastlePenalty
122 | }
123 |
124 | if !theyCanCastle {
125 | extras -= cantCastlePenalty
126 | }
127 |
128 | return (board.whitePieces.valuation - board.blackPieces.valuation) + (extras * (movingSide.isWhite ? 1 : -1))
129 | }
130 | }
131 |
132 | private extension Int {
133 | var isEven: Bool {
134 | return self % 2 == 0
135 | }
136 |
137 | var isOdd: Bool {
138 | return !self.isEven
139 | }
140 | }
141 |
142 | private extension Game {
143 | func playedMoves(bySide side: Color) -> [Move] {
144 | return self.playedMoves.enumerated()
145 | .filter { (side.isWhite && $0.offset.isEven) || (side.isBlack && !$0.offset.isEven) }
146 | .map { $0.element }
147 | }
148 | }
149 |
150 | private extension Game {
151 | func deepEvaluation(depth: Int) throws -> ChessEngine.PositionAnalysis {
152 | return try self.deepEvaluation(depth: depth, alpha: ChessEngine.Valuation.infinity.negated(), beta: ChessEngine.Valuation.infinity)
153 | }
154 |
155 | private func deepEvaluation(depth: Int, alpha: ChessEngine.Valuation, beta: ChessEngine.Valuation) throws -> ChessEngine.PositionAnalysis {
156 | let movingSide = self.position.playerTurn
157 |
158 | guard depth > 0 else {
159 | return ChessEngine.PositionAnalysis(move: nil, valuation: self.currentPositionValuation(), movesAnalized: 1)
160 | }
161 |
162 | let availableMoves = self.availableMoves()
163 |
164 | guard availableMoves.count > 1 else {
165 | let valuation: ChessEngine.Valuation
166 |
167 | switch self.outcome {
168 | case .some(.win(let color)):
169 | valuation = color.isWhite ? ChessEngine.Valuation.infinity : ChessEngine.Valuation.infinity.negated()
170 |
171 | default:
172 | valuation = self.currentPositionValuation()
173 | }
174 |
175 | return ChessEngine.PositionAnalysis(move: availableMoves.first, valuation: valuation, movesAnalized: 1)
176 | }
177 |
178 | var bestMove: Move?
179 | var bestValuation: ChessEngine.Valuation = movingSide.isWhite ? Double.infinity.negated() : Double.infinity
180 | var movesAnalized = 0
181 |
182 | var alpha = alpha
183 | var beta = beta
184 |
185 | for move in availableMoves {
186 | try self.execute(move: move)
187 |
188 | let analysis = try self.deepEvaluation(depth: depth - 1, alpha: alpha, beta: beta)
189 | self.undoMove()
190 |
191 | movesAnalized += analysis.movesAnalized
192 |
193 | if movingSide.isWhite {
194 | if analysis.valuation > alpha {
195 | alpha = analysis.valuation
196 | bestValuation = analysis.valuation
197 | bestMove = move
198 | }
199 | if alpha >= beta {
200 | break
201 | }
202 | }
203 | else {
204 | if analysis.valuation < beta {
205 | beta = analysis.valuation
206 | bestValuation = analysis.valuation
207 | bestMove = move
208 | }
209 |
210 | if beta <= alpha {
211 | break
212 | }
213 | }
214 | }
215 |
216 | return ChessEngine.PositionAnalysis(move: bestMove, valuation: bestValuation, movesAnalized: movesAnalized)
217 | }
218 | }
219 |
220 | final class ChessEngine {
221 | typealias Valuation = Double
222 |
223 | struct PositionAnalysis {
224 | let move: Move?
225 | let valuation: Valuation
226 | let movesAnalized: Int
227 | }
228 |
229 | let game = Game(whitePlayer: Player(kind: .computer), blackPlayer: Player(kind: .computer), variant: Variant.standard)
230 |
231 | init() {
232 |
233 | }
234 |
235 | func bestMove(maxDepth: Int) throws -> PositionAnalysis {
236 | return try self.game.deepEvaluation(depth: maxDepth)
237 | }
238 |
239 | func benchmark() -> (Int, TimeInterval) {
240 | var iterations = 0
241 |
242 | let start = Date()
243 | while iterations < 10000 {
244 | iterations += 1
245 |
246 | guard let move = game.availableMoves().random else { break }
247 | try! game.execute(move: move)
248 | }
249 |
250 | let end = Date()
251 |
252 | let interval = end.timeIntervalSince(start)
253 |
254 | return (iterations, interval)
255 | }
256 | }
257 |
258 | extension Array {
259 | var random: Element? {
260 | guard !self.isEmpty else { return nil }
261 |
262 | let randomIndex = Int(arc4random_uniform(UInt32(self.count)))
263 |
264 | return self[randomIndex]
265 | }
266 | }
267 |
--------------------------------------------------------------------------------
/SwiftChessEngine/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/SwiftChessEngine/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SwiftChessEngine
4 | //
5 | // Created by Javier Soto on 7/3/16.
6 | // Copyright © 2016 JaviSoto. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Sage
11 |
12 | extension PlaygroundQuickLook {
13 | var view: UIView? {
14 | switch self {
15 | case .view(let view): return view as? UIView
16 | default: return nil
17 | }
18 | }
19 | }
20 |
21 | extension UIView {
22 | var image: UIImage {
23 | let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
24 |
25 | return renderer.image() { context in
26 | self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
27 | }
28 | }
29 | }
30 |
31 | final class EngineViewController: UIViewController {
32 | @IBOutlet private var boardViewContainer: UIView!
33 | @IBOutlet private var boardImageView: UIImageView!
34 | @IBOutlet private var evaluationLabel: UILabel!
35 | @IBOutlet private var toggleCalculationButton: UIButton!
36 |
37 | private var currentBoard: Board! {
38 | didSet {
39 | let view = currentBoard.customPlaygroundQuickLook.view!
40 | let image = view.image
41 |
42 | self.boardImageView.image = image
43 | }
44 | }
45 |
46 | private let engine = ChessEngine()
47 |
48 | private let engineQueue = DispatchQueue(label: "engine")
49 | private static let maxDepth = 3
50 |
51 | override func viewDidLoad() {
52 | super.viewDidLoad()
53 |
54 | self.evaluationLabel.text = nil
55 | self.currentBoard = self.engine.game.position.board
56 | }
57 |
58 | private func presentAlertWithGamePGN() {
59 | let alert = UIAlertController(title: "Moves", message: "\(self.engine.game.playedMoves)", preferredStyle: .alert)
60 | let dismissAction = UIAlertAction(title: "OK", style: .`default`) { _ in
61 | alert.dismiss(animated: true)
62 | }
63 | alert.addAction(dismissAction)
64 |
65 | self.present(alert, animated: true)
66 | }
67 |
68 | var calculating: Bool = false {
69 | didSet {
70 | self.toggleCalculationButton.setTitle(calculating ? "Stop calculating" : "Start calculating", for: [])
71 |
72 | if calculating != oldValue {
73 | if calculating {
74 | self.tick()
75 | }
76 | else {
77 | self.presentAlertWithGamePGN()
78 | }
79 | }
80 | }
81 | }
82 |
83 | var totalMovesAnalized = 0
84 |
85 | private func tick() {
86 | guard self.calculating else { return }
87 |
88 | self.engineQueue.async {
89 | do {
90 | let analysis = try self.engine.bestMove(maxDepth: EngineViewController.maxDepth)
91 |
92 | DispatchQueue.main.async {
93 | if let move = analysis.move {
94 | try! self.engine.game.execute(move: move)
95 | self.currentBoard = self.engine.game.position.board
96 | }
97 |
98 | self.totalMovesAnalized += analysis.movesAnalized
99 | self.evaluationLabel.text = "Move \(self.engine.game.fullmoves). Valuation: \(analysis.valuation) (after \(self.totalMovesAnalized) moves analized)"
100 | self.tick()
101 | }
102 | }
103 | catch {
104 | DispatchQueue.main.async {
105 | self.evaluationLabel.text = "Error: \(error)"
106 | }
107 | }
108 | }
109 | }
110 |
111 | @IBAction func calculateButtonTapped() {
112 | self.calculating = !self.calculating
113 | }
114 | }
115 |
116 |
117 |
--------------------------------------------------------------------------------