#include #include #include "global.hpp" Game::Game(int _N, int _M) : N(_N), M(_M) { possible = vector>(N, vector(M, 1)); empty_colors = vector(M, 0); final = vector(N, -1); unsigned int seed = std::chrono::system_clock::now().time_since_epoch().count(); random_engine = std::default_random_engine(seed); } // Getting known information bool Game::can(int n, int col) { return possible[n][col]; } vector> Game::get_positions_of_colors(vector guess) { auto positions_of_colors = vector>(M, vector(0)); for(int n = 0; n < N; n++) if(guess[n] > -1) positions_of_colors[guess[n]].push_back(n); return positions_of_colors; } int Game::final_color(int n) { if(final[n] > -1) return final[n]; int final_col, count = 0; for(int col = 0; col < M; col++) if(possible[n][col]) { final_col = col; count++; } if(count == 1) { final[n] = final_col; return final_col; } return -1; } bool Game::is_empty(int col) { if(empty_colors[col]) return true; for(int n = 0; n < N; n++) if(possible[n][col]) return false; empty_colors[col] = true; return true; } vector> Game::list_all_possibilities() { auto r = vector>(N, vector(0)); for(int col = 0; col < M; col++) for(int n = 0; n < N; n++) if(possible[n][col]) r[n].push_back(col); for(int n = 0; n < N; n++) std::shuffle(r[n].begin(), r[n].end(), random_engine); return r; } void Game::print() { cout << " "; for(int col = 0; col < M; col++) cout << col; cout << std::endl; for(int i = 0; i < N; i++) { cout << i; for(auto col : possible[i]) cout << col; cout << std::endl;; } cout << std::endl; } // Learning functions void Game::cannot_be(int n, int col) { possible[n][col] = false; } void Game::must_be(int n, int must_col) { for(int col = 0; col < M; col++) if(col != must_col) possible[n][col] = 0; } void Game::empty_color(int col) { for(int n = 0; n < N; n++) possible[n][col] = 0; } // Specific reactions bool Game::if_not_here_then_nowhere(vector guess) { auto positions_of_colors = get_positions_of_colors(guess); bool learned_something = false; // If color isn't here, it can't be in the sequence for(int col = 0; col < M; col++) { int possible_count = 0; for(int n : positions_of_colors[col]) if(possible[n][col]) possible_count++; if(possible_count == 0 && positions_of_colors[col].size() > 0 && !is_empty(col)) { empty_color(col); learned_something = true; } } return learned_something; } void Game::here(vector guess) { for(int n = 0; n < N; n++) if(guess[n] > -1 && possible[n][guess[n]]) must_be(n, guess[n]); } void Game::not_here(vector guess) { for(int n = 0; n < N; n++) if(guess[n] > -1) cannot_be(n, guess[n]); } void Game::empty(vector guess) { for(int col : guess) if(col > -1) empty_color(col); } void Game::all_are_here(vector guess) { auto positions_of_colors = get_positions_of_colors(guess); for(int col = 0; col < M; col++) { if(positions_of_colors[col].size() == 0) empty_color(col); } } // For remembering guesses with their responses Historic_guess::Historic_guess(vector _guess, Response _response) { guess = _guess; response = _response; }