BitBully 0.0.39
Loading...
Searching...
No Matches
generator.cpp
1#include "Position.hpp"
2#include "OpeningBook.hpp"
3
4#include <iostream>
5#include <sstream>
6#include <string>
7#include <unordered_set>
8
9using namespace GameSolver::Connect4;
10
11std::unordered_set<uint64_t> visited;
12
17void explore(const Position &P, char* pos_str, const int depth) {
18 uint64_t key = P.key3();
19 if(!visited.insert(key).second)
20 return; // already explored position
21
22 int nb_moves = P.nbMoves();
23 if(nb_moves <= depth)
24 std::cout << pos_str << std::endl;
25 if(nb_moves >= depth) return; // do not explore at further depth
26
27 for(int i = 0; i < Position::WIDTH; i++) // explore all possible moves
28 if(P.canPlay(i) && !P.isWinningMove(i)) {
29 Position P2(P);
30 P2.playCol(i);
31 pos_str[nb_moves] = '1' + i;
32 explore(P2, pos_str, depth);
33 pos_str[nb_moves] = 0;
34 }
35}
36
43void generate_opening_book() {
44 static constexpr int BOOK_SIZE = 23; // store 2^BOOK_SIZE positions in the book
45 static constexpr int DEPTH = 14; // max depth of every position to be stored
46 static constexpr double LOG_3 = 1.58496250072; // log2(3)
47 TranspositionTable<uint_t<int((DEPTH + Position::WIDTH -1) * LOG_3) + 1 - BOOK_SIZE>, Position::position_t, uint8_t, BOOK_SIZE> *table =
48 new TranspositionTable<uint_t<int((DEPTH + Position::WIDTH -1) * LOG_3) + 1 - BOOK_SIZE>, Position::position_t, uint8_t, BOOK_SIZE>();
49
50 long long count = 1;
51 for(std::string line; getline(std::cin, line); count++) {
52 if(line.length() == 0) break; // empty line = end of input
53 std::istringstream iss(line);
54 std::string pos;
55 getline(iss, pos, ' '); // read position before first space character
56 int score;
57 iss >> score;
58
59 Position P;
60 if(iss.fail() || !iss.eof()
61 || P.play(pos) != pos.length()
62 || score < Position::MIN_SCORE || score > Position::MAX_SCORE) { // a valid line is a position a space and a valid score
63 std::cerr << "Invalid line (line ignored): " << line << std::endl;
64 continue;
65 }
66 table->put(P.key3(), score - Position::MIN_SCORE + 1);
67 if(count % 1000000 == 0) std::cerr << count << std::endl;
68 }
69
70 OpeningBook book{Position::WIDTH, Position::HEIGHT, DEPTH, table};
71
72 std::ostringstream book_file;
73 book_file << Position::WIDTH << "x" << Position::HEIGHT << ".book";
74 book.save(book_file.str());
75}
76
81int main(int argc, char** argv) {
82 if(argc > 1) {
83 int depth = atoi(argv[1]);
84 char pos_str[depth + 1] = {0};
85 explore(Position(), pos_str, depth);
86 } else generate_opening_book();
87}
bool canPlay(int col) const
Definition Position.hpp:239
bool isWinningMove(int col) const
Definition Position.hpp:259
void play(position_t move)
Definition Position.hpp:113