diff --git a/.gitmodules b/.gitmodules
index 333a85e..47e98be 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "Sources/ChessKitEngineCore/Engines/lc0"]
path = Sources/ChessKitEngineCore/Engines/lc0
url = https://github.com/chesskit-app/lc0.git
+[submodule "Sources/ChessKitEngineCore/Engines/arasan-chess"]
+ path = Sources/ChessKitEngineCore/Engines/arasan-chess
+ url = git@github.com:ameter/arasan-chess.git
diff --git a/Package.swift b/Package.swift
index a6aadf2..6b8ff67 100644
--- a/Package.swift
+++ b/Package.swift
@@ -21,7 +21,8 @@ let package = Package(
dependencies: ["ChessKitEngineCore"],
resources: [
.copy("Resources/192x15_network"),
- .copy("Resources/nn-1337b1adec5b.nnue")
+ .copy("Resources/nn-1337b1adec5b.nnue"),
+ .copy("Resources/book.bin")
]
),
.target(
@@ -31,7 +32,17 @@ let package = Package(
.headerSearchPath("Engines/lc0/src"),
.headerSearchPath("Engines/lc0/subprojects/eigen-3.4.0"),
.define("NNUE_EMBEDDING_OFF"),
- .define("NO_PEXT")
+ .define("NO_PEXT"),
+ // Arasan
+ .headerSearchPath("Engines/arasan-chess/src"),
+ .headerSearchPath("Engines/arasan-chess/src/nnue"),
+ .define("ARASAN_VERSION=v24.0.0"),
+ .define("_64BIT"),
+ .define("USE_INTRINSICS"),
+ .define("USE_ASM"),
+ .define("SYZYGY_TBS"),
+ .define("SMP"),
+ .define("SMP_STATS"),
],
linkerSettings: [
.linkedLibrary("z")
@@ -48,6 +59,18 @@ let package = Package(
// MARK: - ChessKitEngineCore excludes
package.targets.first { $0.name == "ChessKitEngineCore" }?.exclude = [
+ // Arasan
+ "Engines/arasan-chess/src/arasanx.cpp",
+ "Engines/arasan-chess/src/unit.cpp",
+ "Engines/arasan-chess/src/tuner.cpp",
+ "Engines/arasan-chess/src/tune.cpp",
+ "Engines/arasan-chess/src/topo.cpp",
+ "Engines/arasan-chess/src/bitbase.cpp",
+ "Engines/arasan-chess/src/util",
+ "Engines/arasan-chess/src/nnue/test",
+ "Engines/arasan-chess/src/syzygy/src/apps",
+ "Engines/arasan-chess/src/syzygy/src/tbchess.c",
+ "Engines/arasan-chess/src/nnueintf.cpp",
// lc0
"Engines/lc0/build",
"Engines/lc0/cross-files",
diff --git a/README.md b/README.md
index 68a0183..3f08705 100644
--- a/README.md
+++ b/README.md
@@ -102,6 +102,7 @@ The following engines are currently supported:
| :---: | --- | :---: | :---: | :---: |
|
| [Stockfish](https://stockfishchess.org) | [15.1](https://github.com/official-stockfish/Stockfish/tree/sf_15.1) | [GPL v3](https://github.com/official-stockfish/Stockfish/blob/sf_15.1/Copying.txt) | [🔗](https://github.com/official-stockfish/Stockfish/tree/sf_15.1#the-uci-protocol-and-available-options)
|
| [lc0](https://lczero.org) | [0.29](https://github.com/LeelaChessZero/lc0/tree/v0.29.0) | [GPL v3](https://github.com/LeelaChessZero/lc0/blob/v0.29.0/COPYING) | [🔗](https://github.com/LeelaChessZero/lc0/wiki/Lc0-options)
+|
| [Arasan](https://www.arasanchess.org) | [24.0.0](https://github.com/jdart1/arasan-chess/tree/v24.0.0) | [MIT License](https://github.com/jdart1/arasan-chess/blob/v24.0.0/LICENSE) | [🔗](https://github.com/jdart1/arasan-chess/tree/v24.0.0#uci-options)
## Author
diff --git a/Sources/ChessKitEngine/EngineType.swift b/Sources/ChessKitEngine/EngineType.swift
index 73b2767..7016f2a 100644
--- a/Sources/ChessKitEngine/EngineType.swift
+++ b/Sources/ChessKitEngine/EngineType.swift
@@ -10,12 +10,14 @@ public enum EngineType: Int {
case stockfish
case lc0
+ case arasan
/// Internal mapping from Swift to Obj-C type.
var objc: EngineType_objc {
switch self {
case .stockfish: return .stockfish
case .lc0: return .lc0
+ case .arasan: return .arasan
}
}
@@ -24,6 +26,7 @@ public enum EngineType: Int {
switch self {
case .stockfish: return "Stockfish"
case .lc0: return "LeelaChessZero (Lc0)"
+ case .arasan: return "Arasan"
}
}
@@ -32,6 +35,7 @@ public enum EngineType: Int {
switch self {
case .stockfish: return "15.1"
case .lc0: return "0.29"
+ case .arasan: return "24.0.0"
}
}
@@ -59,6 +63,15 @@ public enum EngineType: Int {
weights != nil ?
.setoption(id: "WeightsFile", value: weights!) : nil
].compactMap { $0 }
+ case .arasan:
+ let openingBook = Bundle.module.url(forResource: "book", withExtension: "bin")?
+ .absoluteString
+ .replacingOccurrences(of: "file://", with: "")
+
+ return [
+ openingBook != nil ?
+ .setoption(id: "BookPath", value: openingBook!) : nil
+ ].compactMap { $0 }
}
}
diff --git a/Sources/ChessKitEngine/Resources/book.bin b/Sources/ChessKitEngine/Resources/book.bin
new file mode 100644
index 0000000..f4955e4
Binary files /dev/null and b/Sources/ChessKitEngine/Resources/book.bin differ
diff --git a/Sources/ChessKitEngineCore/EngineMessenger/EngineMessenger.mm b/Sources/ChessKitEngineCore/EngineMessenger/EngineMessenger.mm
index 906de71..fae0a8f 100644
--- a/Sources/ChessKitEngineCore/EngineMessenger/EngineMessenger.mm
+++ b/Sources/ChessKitEngineCore/EngineMessenger/EngineMessenger.mm
@@ -28,6 +28,9 @@ - (id)initWithEngineType: (EngineType_objc) type {
case EngineTypeLc0:
_engine = new Lc0Engine();
break;
+ case EngineTypeArasan:
+ _engine = new ArasanEngine();
+ break;
}
_engine->initialize();
diff --git a/Sources/ChessKitEngineCore/Engines/AvailableEngines.h b/Sources/ChessKitEngineCore/Engines/AvailableEngines.h
index 07bd7b8..a47f5dd 100644
--- a/Sources/ChessKitEngineCore/Engines/AvailableEngines.h
+++ b/Sources/ChessKitEngineCore/Engines/AvailableEngines.h
@@ -8,5 +8,6 @@
#import "../Engines/Extensions/stockfish+engine.h"
#import "../Engines/Extensions/lc0+engine.h"
+#import "../Engines/Extensions/arasan+engine.h"
#endif /* AvailableEngines_h */
diff --git a/Sources/ChessKitEngineCore/Engines/EngineType_objc.h b/Sources/ChessKitEngineCore/Engines/EngineType_objc.h
index e63b42e..290f41e 100644
--- a/Sources/ChessKitEngineCore/Engines/EngineType_objc.h
+++ b/Sources/ChessKitEngineCore/Engines/EngineType_objc.h
@@ -8,7 +8,8 @@
typedef NS_ENUM(NSInteger, EngineType_objc) {
EngineTypeStockfish,
- EngineTypeLc0
+ EngineTypeLc0,
+ EngineTypeArasan
};
#endif /* EngineType_objc_h */
diff --git a/Sources/ChessKitEngineCore/Engines/Extensions/arasan+engine.cpp b/Sources/ChessKitEngineCore/Engines/Extensions/arasan+engine.cpp
new file mode 100644
index 0000000..c6182cd
--- /dev/null
+++ b/Sources/ChessKitEngineCore/Engines/Extensions/arasan+engine.cpp
@@ -0,0 +1,73 @@
+//
+// arasan+engine.cpp
+//
+// Created by Chris Ameter on 10/10/23.
+//
+
+#import "arasan+engine.h"
+
+#include "../arasan-chess/src/types.h"
+#include "../arasan-chess/src/globals.h"
+#include "../arasan-chess/src/options.h"
+#include "../arasan-chess/src/protocol.h"
+
+#include
+#include
+
+Protocol *protocol;
+Board board;
+
+void ArasanEngine::initialize() {
+ signal(SIGINT,SIG_IGN);
+
+ // Show a message on the console
+ std::cout << "Arasan " Arasan_Version << ' ' << Arasan_Copyright << std::endl;
+ // Must use unbuffered console
+ setbuf(stdin,NULL);
+ setbuf(stdout, NULL);
+ std::cout.rdbuf()->pubsetbuf(NULL, 0);
+ std::cin.rdbuf()->pubsetbuf(NULL, 0);
+
+ Bitboard::init();
+ Board::init();
+ globals::initOptions();
+ Attacks::init();
+ Scoring::init();
+ Search::init();
+ if (!globals::initGlobals(true)) {
+ globals::cleanupGlobals();
+ exit(-1);
+ }
+
+ struct rlimit rl;
+ const rlim_t STACK_MAX = static_cast(globals::LINUX_STACK_SIZE);
+ auto result = getrlimit(RLIMIT_STACK, &rl);
+ if (result == 0)
+ {
+ if (rl.rlim_cur < STACK_MAX)
+ {
+ rl.rlim_cur = STACK_MAX;
+ result = setrlimit(RLIMIT_STACK, &rl);
+ if (result)
+ {
+ std::cerr << "failed to increase stack size" << std::endl;
+ exit(-1);
+ }
+ }
+ }
+
+ bool ics = true, trace = false, cpusSet = false, memorySet = false;
+
+ protocol = new Protocol(board, trace, ics, cpusSet, memorySet);
+ // Begins protocol (UCI) run loop, listening on standard input
+ // protocol->poll(globals::polling_terminated);
+}
+
+void ArasanEngine::deinitialize() {
+ globals::cleanupGlobals();
+ delete protocol;
+}
+
+void ArasanEngine::send_command(const std::string &cmd) {
+ protocol->do_command(cmd, board);
+}
diff --git a/Sources/ChessKitEngineCore/Engines/Extensions/arasan+engine.h b/Sources/ChessKitEngineCore/Engines/Extensions/arasan+engine.h
new file mode 100644
index 0000000..c12cfbd
--- /dev/null
+++ b/Sources/ChessKitEngineCore/Engines/Extensions/arasan+engine.h
@@ -0,0 +1,21 @@
+//
+// arasan+engine.h
+//
+// Created by Chris Ameter on 10/10/23.
+//
+
+#ifndef arasan_engine_h
+#define arasan_engine_h
+
+#import "engine.h"
+#import
+
+/// Arasan implementation of `Engine`.
+class ArasanEngine: public Engine {
+public:
+ void initialize();
+ void deinitialize();
+ void send_command(const std::string &cmd);
+};
+
+#endif /* arasan_engine_h */
diff --git a/Sources/ChessKitEngineCore/Engines/arasan-chess b/Sources/ChessKitEngineCore/Engines/arasan-chess
new file mode 160000
index 0000000..c4786a9
--- /dev/null
+++ b/Sources/ChessKitEngineCore/Engines/arasan-chess
@@ -0,0 +1 @@
+Subproject commit c4786a9e109215759132d94ae39feab0a632fa83
diff --git a/Tests/ChessKitEngineTests/EngineTests/ArasanTests.swift b/Tests/ChessKitEngineTests/EngineTests/ArasanTests.swift
new file mode 100644
index 0000000..4e9d3d6
--- /dev/null
+++ b/Tests/ChessKitEngineTests/EngineTests/ArasanTests.swift
@@ -0,0 +1,17 @@
+//
+// ArasanTests.swift
+//
+// Created by Chris Ameter on 10/20/23.
+//
+
+import XCTest
+@testable import ChessKitEngine
+
+final class ArasanTests: BaseEngineTests {
+
+ override func setUp() {
+ engineType = .arasan
+ super.setUp()
+ }
+
+}