The Board Model¶
The foundational value types. All are Sendable and presentation-free:
colors, glyphs, and asset names are not part of the model and are left to the
consuming UI.
PieceColor¶
| Member | Meaning |
|---|---|
opposite |
the other side |
persistenceKey |
stable "white" / "black" storage key |
shortKey |
compact "w" / "b" |
init?(persistenceKey:) |
parse from the stable key |
static ofUser(white:black:username:) |
which side a username played (case-insensitive), or nil |
PieceType¶
public enum PieceType: Equatable, Hashable, Codable, Sendable {
case king, queen, rook, bishop, knight, pawn
}
Piece¶
public struct Piece: Equatable, Hashable, Codable, Sendable {
public let type: PieceType
public let color: PieceColor
public init(type: PieceType, color: PieceColor)
public var fenChar: String // uppercase for white, e.g. "N" / "n"
}
Square¶
A board coordinate, file/rank 0...7.
public struct Square: Hashable, Equatable, Codable, Sendable {
public let file: Int
public let rank: Int
public init(file: Int, rank: Int)
public init?(algebraic: String) // "e4"
public var isValid: Bool // both in 0..<8
public var fileChar: Character // 'a'...'h'
public var algebraic: String // "e4"
public var index: Int // rank * 8 + file (0...63)
public static func fromIndex(_ index: Int) -> Square
}
CastlingRights¶
public struct CastlingRights: Equatable, Hashable, Codable, Sendable {
public var whiteKingside = true
public var whiteQueenside = true
public var blackKingside = true
public var blackQueenside = true
public static let none: CastlingRights // all false
}
Move¶
A single move with full disambiguation metadata.
public struct Move: Equatable, Hashable, Sendable {
public let from: Square
public let to: Square
public let piece: PieceType
public let capturedPiece: PieceType?
public let promotion: PieceType?
public let isEnPassant: Bool
public let isCastling: Bool
public init(from: Square, to: Square, piece: PieceType,
capturedPiece: PieceType? = nil, promotion: PieceType? = nil,
isEnPassant: Bool = false, isCastling: Bool = false)
public var uci: String // "e2e4", "e7e8q"
}
MoveRecord¶
A move paired with its SAN and the position it was played from:
public struct MoveRecord: Sendable {
public let move: Move
public let notation: String
public let positionBefore: Position
}
Piece names¶
displayName is the English noun the algebraic-notation letter abbreviates, so
it is a property of the notation rather than of a user interface. It is not
localized: a program presenting piece names in another language should map from
the PieceType case rather than from this string. Composing a phrase from it
("White knight", a screen-reader sentence) is the caller's.
MoveAnnotation¶
The PGN/NAG glyphs. The model covers chess logic only; display name, symbol, and tint are left to the UI:
public enum MoveAnnotation: String, Equatable, Hashable, Sendable, CaseIterable {
case brilliant = "!!", great, best, excellent
case good = "!", interesting = "!?", dubious = "?!"
case miss, mistake = "?", blunder = "??"
}
let (cleaned, annotation) = MoveAnnotation.extract(from: "Nf3!?") // ("Nf3", .interesting)
let fromNag = MoveAnnotation.from(nag: 1) // .good
let suffix = MoveAnnotation.brilliant.pgnSuffix // the PGN suffix
MoveQuality¶
Engine move-quality classification (display is left to the UI):
public enum MoveQuality: String, CaseIterable, Sendable {
case best, excellent, good, inaccuracy, mistake, blunder
}
GameState¶
public enum GameState: Equatable, Sendable {
case playing, check, checkmate, stalemate
case draw, insufficientMaterial, repetition
public var isGameOver: Bool
}
Position¶
The complete board state, plus FEN parse/serialize and material/EP analysis.
public struct Position: Equatable, Sendable {
public var board: [Piece?] // 64 entries
public var activeColor: PieceColor
public var castlingRights: CastlingRights
public var enPassantTarget: Square?
public var halfmoveClock: Int
public var fullmoveNumber: Int
public var whiteKingSquare: Square
public var blackKingSquare: Square
public init() // empty board, White to move
public init?(fen: String) // standard FEN (failable)
public subscript(square: Square) -> Piece? { get set } // bounds-safe
public static func initial() -> Position // standard start
public var fen: String // full FEN incl. counters
public var positionKey: String // FEN without counters (the legality/transposition key)
public var consistentFEN: String // metadata reconciled with the placement
public var capturableEnPassantTarget: Square? // EP only when a capture exists
public var hasInsufficientMaterial: Bool
}
See FEN for the three FEN-shaped accessors and when to use each.