stellar

UCI Chess engine written in C++20
git clone git://git.dimitrijedobrota.com/stellar.git
Log | Files | Refs | README | LICENSE

arena.cpp (3068B)


0 #include <format>
1 #include <functional>
2 #include <iostream>
3 #include <mutex>
4 #include <thread>
6 #include <bits/getopt_core.h>
7 #include <stdexcept>
9 #include "attack.hpp"
10 #include "logger.hpp"
11 #include "match.hpp"
13 class Arena {
14 public:
15 Arena(const Arena &) = delete;
16 Arena &operator==(const Arena &) = delete;
17 Arena(const char *name1, const char *name2) : engine1(new Engine(name1)), engine2(new Engine(name2)) {
18 logger::log(std::format("Arena {}: created", id), logger::Debug);
19 }
21 ~Arena() {
22 delete (engine1), delete (engine2);
23 logger::log(std::format("Arena {}: destroyed", id), logger::Debug);
24 }
26 void operator()(const std::vector<std::string> &positions, Match::Settings swhite,
27 Match::Settings sblack) {
28 Match match(*engine1, *engine2);
29 for (const std::string &fen : positions) {
30 logger::log(
31 std::format("Arena {}: match from {}", id, fen == Game::startPosition ? "startpos" : fen),
32 logger::Debug);
33 Arena::print(match.play(swhite, sblack, fen));
34 }
35 }
37 private:
38 static void print(const Game &game) {
39 mutex.lock();
40 std::cout << game << std::endl;
41 mutex.unlock();
42 }
44 static uint16_t id_t;
45 uint16_t id = id_t++;
47 Engine *engine1;
48 Engine *engine2;
50 static std::mutex mutex;
51 };
53 uint16_t Arena::id_t = 0;
55 std::mutex Arena::mutex;
56 void usage(const char *program) {
57 std::cerr << program << ": ";
58 std::cerr << "[-f fen]";
59 std::cerr << "\n[-G wmovestogo -g bmovestogo]";
60 std::cerr << "\n[-D wdepth -d bdepth]";
61 std::cerr << "\n[-T wtime -t btime]";
62 std::cerr << "\n[-I winc -i binc]";
63 std::cerr << "\n-E engine1 -e engine2";
64 std::cerr << "\n[- startpos] ... fen ...";
65 }
67 int main(int argc, char *argv[]) {
68 char *engine1 = nullptr, *engine2 = nullptr;
69 Match::Settings settings1, settings2;
71 char c = 0;
72 while ((c = getopt(argc, argv, "hE:e:D:d:T:t:I:i:G:g:N:")) != -1) {
73 switch (c) {
74 case 'E': engine1 = optarg; break;
75 case 'e': engine2 = optarg; break;
76 case 'D': settings1.depth = atoi(optarg); break;
77 case 'd': settings2.depth = atoi(optarg); break;
78 case 'T': settings1.time = atoll(optarg); break;
79 case 't': settings2.time = atoll(optarg); break;
80 case 'I': settings1.inc = atoll(optarg); break;
81 case 'i': settings2.inc = atoll(optarg); break;
82 case 'G': settings1.togo = atoi(optarg); break;
83 case 'g': settings2.togo = atoi(optarg); break;
84 case 'h': usage(argv[0]); return 1;
85 default: usage(argv[0]), abort();
86 }
87 }
89 if (!engine1 || !engine2) {
90 usage(argv[0]);
91 abort();
92 }
94 std::vector<std::string> positions;
95 for (int i = optind; i < argc; i++)
96 positions.emplace_back(!strcmp(argv[i], "-") ? start_position : argv[i]);
98 attack::init();
99 zobrist::init();
100 Arena arena(engine1, engine2);
101 arena(positions, settings1, settings2);
103 return 0;