BitBully 0.0.74
Loading...
Searching...
No Matches
main.cpp
1#include <chrono>
2#include <fstream>
3#include <iomanip> // For setting precision
4#include <iostream>
5#include <numeric>
6#include <sstream>
7#include <string>
8#include <thirdParty/connect4/Solver.hpp>
9#include <tuple>
10#include <unordered_map>
11#include <vector>
12
13#include "BitBully.h"
14#include "Board.h"
15
16#ifdef _WIN32 // Check if we're on a Windows platform
17using Clock = std::chrono::steady_clock; // Use steady_clock on Windows
18#else
19using Clock = std::chrono::high_resolution_clock; // Use high_resolution_clock
20 // on other platforms
21#endif
22
23void writeToCSV(const std::vector<std::tuple<float, float>>& data,
24 const std::string& filename) {
25 std::ofstream file(filename); // Open file for writing
26 if (!file.is_open()) {
27 std::cerr << "Error: Unable to open file " << filename << std::endl;
28 return;
29 }
30
31 // Write header
32 file << "Bitbully,Pons-C4\n";
33
34 // Write data
35 for (const auto& [val1, val2] : data) {
36 file << std::fixed << std::setprecision(5) // Control float precision
37 << val1 << "," << val2 << "\n";
38 }
39
40 file.close();
41 std::cout << "Data successfully written to " << filename << std::endl;
42}
43
44std::unordered_map<std::string, std::string> parseArgs(
45 const int argc, const char* const argv[]) {
46 std::unordered_map<std::string, std::string> args;
47
48 for (int i = 1; i < argc; i += 2) {
49 if (i + 1 < argc) {
50 args[argv[i]] = argv[i + 1];
51 } else {
52 std::cerr << "Error: Missing value for argument " << argv[i] << std::endl;
53 exit(EXIT_FAILURE);
54 }
55 }
56
57 return args;
58}
59
60int main(const int argc, const char* const argv[]) {
61 // Default values
62 int nPly = 8;
63 int nRepeats = 1000;
64 std::string filename;
65 int reset_tt = 0;
66
67 // Parse command-line arguments
68 auto args = parseArgs(argc, argv);
69 if (args.find("--nply") != args.end()) nPly = std::stoi(args["--nply"]);
70 if (args.find("--nrepeats") != args.end())
71 nRepeats = std::stoi(args["--nrepeats"]);
72 if (args.find("--filename") != args.end())
73 filename = args["--filename"];
74 else
75 filename = "../times_" + std::to_string(nPly) + "_ply_" +
76 std::to_string(nRepeats) + "_pos.csv";
77 if (args.find("--reset_tt") !=
78 args.end()) // reset transposition table every N moves
79 reset_tt = std::stoi(args["--reset_tt"]);
80
81 std::vector<std::tuple<float, float>> times = {};
82
83 using duration = std::chrono::duration<float>;
84
87
88 for (auto i = 0; i < nRepeats; i++) {
89 auto [b, mvSequence] = BitBully::Board::randomBoard(nPly, true);
90
91 if (reset_tt > 0 && i % reset_tt == 0) {
92 solverPonsC4.reset();
93 bb.resetTranspositionTable();
94 }
95
96 // Bitbully:
97 auto tStart = Clock::now();
98 const int scoreBitbully = bb.mtdf(b, 0);
99 auto tEnd = Clock::now();
100 auto timeBitbully = static_cast<float>(duration(tEnd - tStart).count());
101
102 // Pons-C4:
104 // Convert move sequence into a string representation:
105 auto mvSequenceStr =
106 std::accumulate(mvSequence.begin(), mvSequence.end(), std::string(""),
107 [](const std::string& a, const int mv) {
108 return a + std::to_string(mv + 1);
109 });
110 if (P.play(mvSequenceStr) != b.countTokens()) {
111 std::cerr << "Error: (P.play(mvSequenceStr) != b.countTokens())";
112 exit(EXIT_FAILURE);
113 }
114 tStart = Clock::now();
115 const int scorePonsC4 = solverPonsC4.solve(P, false);
116 tEnd = Clock::now();
117 auto timePonsC4 = static_cast<float>(duration(tEnd - tStart).count());
118 times.emplace_back(timeBitbully, timePonsC4);
119
120 if (scorePonsC4 != scoreBitbully) {
121 std::cerr << "Error: " << b.toString() << "Pons-C4: " << scorePonsC4
122 << " BitBully: " << scoreBitbully << std::endl;
123 exit(EXIT_FAILURE);
124 }
125
126 if (i % (std::max(nRepeats, 100) / 100) == 0) {
127 std::cout << "Done with " << i << " iterations" << std::endl;
128 }
129 }
130 writeToCSV(times, filename);
131
132 std::cout << "Node Count Pons-C4: " << solverPonsC4.getNodeCount() << ", "
133 << "BitBully: " << bb.getNodeCounter() << " Percent: "
134 << static_cast<double>(bb.getNodeCounter() -
135 solverPonsC4.getNodeCount()) /
136 bb.getNodeCounter() * 100.0
137 << " %" << std::endl;
138 return 0;
139}
void play(position_t move)
Definition Position.hpp:113