132 lines
3.2 KiB
Swift
132 lines
3.2 KiB
Swift
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: Hashable {
|
|
#warning("TODO: To be removed, handle everything through the delegate")
|
|
public internal(set) var color: Color
|
|
public internal(set) var halfMoveCount: UInt8 = 0
|
|
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]()
|
|
internal func getLegalPosition() {
|
|
legalPositions = pseudoLegalPositions.filter { isLegal(on: $0) }
|
|
}
|
|
internal var delegate: EventDelegate?
|
|
|
|
internal func move(to dst: Square.Position) throws {
|
|
guard (legalPositions.contains { $0 == dst }) else {
|
|
throw Board.MoveFailure.destinationIsIllegal(pos: dst)
|
|
}
|
|
|
|
try delegate?.movePiece(self, to: dst)
|
|
halfMoveCount += 1
|
|
}
|
|
|
|
#warning("This method should be better thought out.")
|
|
internal func isLegal(on pos: Square.Position) -> Bool {
|
|
if let s = delegate?.getSquareInfo(on: pos) {
|
|
if let p = s.piece {
|
|
if p.color == color { return false }
|
|
if let king = p as? King {
|
|
#warning("It could be in check or behind another piece.")
|
|
delegate?.notify(.kingInCheck(self, on: king))
|
|
return false
|
|
}
|
|
}
|
|
|
|
}
|
|
delegate?.addPieceToTarget(self, target: pos)
|
|
return true
|
|
}
|
|
|
|
internal init(kind: Kind, on pos: Square.Position, with col: Color) {
|
|
self.kind = kind
|
|
self.position = pos
|
|
self.color = col
|
|
}
|
|
|
|
/// Two pieces are equal when they share the same kind, color and position
|
|
public static func == (lhs: Piece, rhs: Piece) -> Bool {
|
|
return lhs.kind == rhs.kind && lhs.color == rhs.color
|
|
&& lhs.position == rhs.position
|
|
}
|
|
|
|
/// Two pieces are not equal when they either do not share the same kind,
|
|
/// color or position
|
|
public static func != (lhs: Piece, rhs: Piece) -> Bool {
|
|
return !(lhs == rhs)
|
|
}
|
|
|
|
/// Checks if tho pieces are similar yet not equal.
|
|
/// They are considered simmilar if they share the same color and the same kind,
|
|
/// but differ in position.
|
|
public static func ~= (lhs: Piece, rhs: Piece) -> Bool {
|
|
return lhs.kind == rhs.kind && lhs.color == rhs.color
|
|
&& lhs.position != rhs.position
|
|
}
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
hasher.combine(kind)
|
|
hasher.combine(color)
|
|
hasher.combine(position)
|
|
}
|
|
}
|