public struct Square: Equatable { public struct Position: Equatable, Hashable { public let rank: Int8 public let file: Int8 public var index: Int? { guard (rank > 0 && rank < 9) && (file > 0 && file < 9) else { return nil } return Int(8 * (8 - rank) + file - 1) } public init(rank r: Int8, file f: Int8) { rank = r file = f } public enum File: String, CustomStringConvertible { case a, b, c, d, e, f, g, h public static subscript(_ f: Int8) -> Self? { return switch f { case 1: Self.a case 2: Self.b case 3: Self.c case 4: Self.d case 5: Self.e case 6: Self.f case 7: Self.g case 8: Self.h default: nil } } public var value: Int8 { return switch self { case .a: 1 case .b: 2 case .c: 3 case .d: 4 case .e: 5 case .f: 6 case .g: 7 case .h: 8 } } public var description: String { self.rawValue.uppercased() } } public static func == (lhs: Position, rhs: Position) -> Bool { return lhs.index == rhs.index } public static func + (lhs: Position, rhs: Position) -> Position { .init(rank: lhs.rank + rhs.rank, file: lhs.file + rhs.file) } public static func + (lhs: Position, rhs: (Int8, Int8)) -> Position { .init(rank: lhs.rank + rhs.0, file: lhs.file + rhs.1) } public static func += (lhs: inout Position, rhs: Position) { lhs = lhs + rhs } public static func += (lhs: inout Position, rhs: (Int8, Int8)) { lhs = lhs + rhs } } public let position: Position public internal(set) var piece: Piece? = nil public let color: Color public typealias Targets = [Piece] public internal(set) var targetted: Targets = [] public static func == (lhs: Square, rhs: Square) -> Bool { return lhs.position == rhs.position } }