diff --git a/Sources/Engine/Board.swift b/Sources/Engine/Board.swift index 5b3264b..57a99aa 100644 --- a/Sources/Engine/Board.swift +++ b/Sources/Engine/Board.swift @@ -33,7 +33,7 @@ public class Board: CustomStringConvertible, EventDelegate { } private var squares = [Square]() - private var board: Grid { + internal var board: Grid { var board = Grid() var rank = -1 for i in 0...63 { @@ -46,7 +46,7 @@ public class Board: CustomStringConvertible, EventDelegate { return board } - public private(set) var fen: Fen + public internal(set) var fen: Fen public func setBoard() throws { var file: Int8 = 1 diff --git a/Sources/Engine/FEN.swift b/Sources/Engine/FEN.swift index 62419ec..c7cc30c 100644 --- a/Sources/Engine/FEN.swift +++ b/Sources/Engine/FEN.swift @@ -14,7 +14,7 @@ public struct Fen: CustomStringConvertible { case All = "KQkq" } private var _fen: String = "" - private var value: String { + public private(set) var value: String { get { return _fen } @@ -63,14 +63,49 @@ public struct Fen: CustomStringConvertible { self.value = value } + internal mutating func set( + from board: Board.Grid, castiling ca: CastlingAvailibility, + enPassant: String + ) { + #warning( + "Determine active color, halfMoveClock, fullMoveClock based on history SAN later passed in arguments" + ) + var placement = "" + var rankNr = 0 + for rank in board { + var count = 0 + for i in 0.. 0 { + placement += String(count) + count = 0 + } + placement += piece.kind.fenRepresentation(with: piece.color) + } else { + count += 1 + } + } + if count > 0 { + placement += String(count) + } + if rankNr != rank.count - 1 { + placement += "/" + } + rankNr += 1 + } + + value = placement + " w " + ca.rawValue + " " + enPassant + " 0 " + "1" + } + public enum FenError: Error { case InvalidCharacter(c: String, column: Int8) case NumberTooBig(n: Int8, column: Int8) case NumberTooSmall(n: Int8, column: Int8) - case NotAppropriateLength(n: Int8, column: Int8) + case NotAppropriateLength(n: Int8, column: Int8) } public var description: String { return value } -} \ No newline at end of file +} diff --git a/Sources/Engine/Pieces/Piece.swift b/Sources/Engine/Pieces/Piece.swift index e1c0117..6a37740 100644 --- a/Sources/Engine/Pieces/Piece.swift +++ b/Sources/Engine/Pieces/Piece.swift @@ -12,6 +12,20 @@ public enum Kind: String, CaseIterable { } } + 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() diff --git a/Tests/EngineTests/EngineTests.swift b/Tests/EngineTests/EngineTests.swift index 912e460..a8e1b71 100644 --- a/Tests/EngineTests/EngineTests.swift +++ b/Tests/EngineTests/EngineTests.swift @@ -105,6 +105,16 @@ final class EngineTests: XCTestCase { XCTAssertEqual(result, pb.pseudoLegalPositions) } + func testSetFenFromBoard() throws { + let board: Board = .init() + let fen = board.fen.value + board.fen.set( + from: board.board, castiling: board.fen.castlingAvailibility, + enPassant: board.fen.enPassant) + XCTAssertEqual( + fen, board.fen.value, "Expected \(fen) got \(board.fen.value)") + } + // func testBoard() throws { // let board = Board() // }