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