public enum Kind: String, CaseIterable { case Pawn, Knight, Bishop, Rook, Queen, King var value: Int8 { switch self { case .Pawn: 1 case .Bishop: 3 case .Knight: 3 case .Rook: 5 case .Queen: 9 case .King: -1 } } func fenRepresentation(with color: Color) -> String { let str = switch self { case .Pawn: "P" case .Bishop: "B" case .Knight: "N" case .Rook: "R" case .Queen: "Q" case .King: "K" } return color == .White ? str : str.lowercased() } static subscript(_ c: Character) -> (Self, Color)? { let v = c.uppercased() guard v == "N" || (Self.allCases.contains { String($0.rawValue.first!) == v }) else { return nil } let kind: Self = switch v { case "P": .Pawn case "N": .Knight case "B": .Bishop case "R": .Rook case "Q": .Queen case "K": .King default: .Pawn } let color: Color = c.isUppercase ? .White : .Black return (kind, color) } } public class Piece { #warning("TODO: TO be removed, handle everything through the delegate") internal weak var board: Board? public internal(set) var color: Color public var unicodeRepresentation: String { return "" } public internal(set) var kind: Kind public internal(set) var position: Square.Position internal var pseudoLegalPositions: [Square.Position] { return [] } internal var legalPositions: [Square.Position] { return [] } internal var delegate: EventDelegate? internal func move(to dst: Square.Position) throws { if !(legalPositions.contains { $0 == dst }) { throw Board.MoveFailure.destinationIsIllegal(pos: dst) } try delegate?.movePiece(self, to: dst) } internal func isLegal(on pos: Square.Position) -> Bool { if let board = board, let s = board[pos] { if let p = s.piece { if p.color == color { return false } if p.kind == .King { // TODO: Notify board of check delegate?.notify(.kingInCheck(self)) return false } } } return true } internal init(kind: Kind, on pos: Square.Position, with col: Color) { self.kind = kind self.position = pos self.color = col } }