Files
swift-chess/Sources/Engine/Pieces/Piece.swift
2024-07-01 17:18:10 +02:00

130 lines
3.1 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 {
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 []
}
package internal(set) 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 {
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)
}
}