const Stonepair Gamefield::NextStones() { sf::Sprite sprite(myResourcemanager->Get<sf::Texture>(mySettings.GetSettings("Resource", "Bubbles"))); sprite.setScale(mySettings.GetScaleFactor()); return Stonepair(Stone(sf::Vector2i(2, -1), myOrigin, GetRandomColor(), sprite), Stone(sf::Vector2i(2, -2), myOrigin, GetRandomColor(), sprite)); }
Stone AI::calc(int depth) { int score; int max_y=-1,max_x=-1; //int max = -AI_INFINITY; int alpha = -AI_INFINITY; int beta = AI_INFINITY; //On parcourt les cases du Goban TILE_IT_T it = _openTiles.begin(); while (it != _openTiles.end()) { checkTime(); int y = it->first;//le temps de faire marcher les iterateurs int x = it->second; Map map_tmp = _map;// Copy de la map et des nombres de pierres capturées char fake = 0;// On crée la pierre et on joue le coup Referee::E_STATE ret = _referee.check(Stone(y,x, _color), map_tmp, fake); // _closeTiles.push_back(*it); // it = _openTiles.erase(it); // Si le coup est valide on évalue (Pas de double trois) if (ret != Referee::INVALID) { //score = calcMin(map_tmp, depth - 1, ret, alpha, beta); score = -calcMinMax(map_tmp, depth - 1, ret, Referee::OP_COLOR[_color], -beta, -alpha); // Si ce score est plus grand //if (score > max)/*Moins optimise mais aleatoire: if (score > max || (score == max && rand()%2))*/ if (score > alpha) { std::cout << "depth:"<<depth<<"[" << alpha << "("<<max_y<<";"<<max_x<<")->" << score << "("<<y<<";"<<x<< ")]" << std::endl; //On le choisit //max = score; alpha = score; // On sauvegarde les coordonnées du coup optimum max_y = y; max_x = x; } } // On annule le coup (Ici rien pour l'instant car copie de la Map et des éléments) // TILE_VALUE_T tmp_tile = _closeTiles.back(); // _closeTiles.pop_back(); // it = _openTiles.insert(it, tmp_tile); ++it; } // On retourne la pierre optimale return Stone(max_y, max_x, _color); }
int AI::getEvalForFirstMovePossible(Map& map, int depth, Stone::E_COLOR color, int alpha, int beta, int &y, int &x) { // On parcours le Goban a la recherche du premier coup possible for (; y < Map::_MAPSIZE_Y; ++y) { for (; x < Map::_MAPSIZE_X; ++x) { checkTime(); if (map[y][x].isEmpty()) { // Copy de la map et des nombres de pierres capturées Map map_tmp = map; // On crée la pierre et on joue le coup char fake = 0; Referee::E_STATE ret = _referee.check(Stone(y, x, color), map_tmp, fake); // Si le coup est valide on évalue (Pas de double trois) if (ret != Referee::INVALID) return -calcMinMax(map_tmp, depth-1, ret, Referee::OP_COLOR[color], -beta, -alpha); } } } return 0; }
Stone SgfTree::move() { Point p = attrValue("B").toPoint(); if ( ! p.isNull()) { return Stone(cBlack, p); } else { p = attrValue("W").toPoint(); if ( ! p.isNull() ) { return Stone(cWhite, p); } else { return Stone::null(); } } }
int AI::calcMinMax(Map& map, int depth, Referee::E_STATE ret, Stone::E_COLOR color, int alpha, int beta) { if (depth == 0 || Referee::gameHasEnded(ret)) return eval(map, ret, color); // int y_first = 0; // int x_first = 0; // On récupère l'évaluation du premier coup possible // int current = getEvalForFirstMovePossible(map, depth, color, alpha, beta, y_first, x_first); // if (current >= alpha) // alpha = current; // if (current < beta) // { TILE_IT_T it = _openTiles.begin(); // On parcours les autres cases du Goban while (it != _openTiles.end()) { checkTime(); int y = it->first;//le temps de faire marcher les iterateurs int x = it->second; // Copy de la map et des nombres de pierres capturées Map map_tmp = map; // On crée la pierre et on joue le coup char fake = 0; Referee::E_STATE ret = _referee.check(Stone(y, x, color), map_tmp, fake); // Si le coup est valide on évalue (Pas de double trois) if (ret != Referee::INVALID) { // int score = 1; int score = -calcMinMax(map_tmp, depth-1, ret, Referee::OP_COLOR[color], -(alpha+1), -alpha); if (score > alpha && score < beta) score = -calcMinMax(map_tmp, depth-1, ret, Referee::OP_COLOR[color], -beta, -alpha); // if (score >= current) // { // current = score; if (score >= alpha) { alpha = score; if (/*alpha*/score >= beta) return score; // return current; } // } } ++it; } // } return alpha; // return /*alpha*/current; }
void MazeBoard::initialize(int _board_size) { board_size = _board_size; // adding board_size to class variable /* initialize random seed: */ srand(time(NULL)); std::vector<int> ratio (3, 0); // ratio between counts of Stone types board.resize(board_size * board_size); // adding corners to the board (4x L) board[INDEX(1, 1 )] = Stone(L, 1); board[INDEX(1, board_size)] = Stone(L, 2); board[INDEX(board_size, 1 )] = Stone(L, 0); board[INDEX(board_size, board_size)] = Stone(L, 3); ratio[L] += 4; // adding T stones (odd x and odd y coordinates - but not corners) // count is ((N/2+1)*(N/2+1)-4) for (int x = 1; x <= board_size; x+=2) { for (int y = 1; y <= board_size; y+=2) { if (is_corner(x, y, board_size)) continue; board[INDEX(x,y)] = Stone(T, rand()%4); if (x == 1) (board[INDEX(x,y)]).rotation = 0; // first row else if (x == board_size) (board[INDEX(x,y)]).rotation = 2; // last row else if (y == 1) (board[INDEX(x,y)]).rotation = 3; // first column else if (y == board_size) (board[INDEX(x,y)]).rotation = 1; // last column (ratio[T])++; //std::cout << "ratio.. I: " << ratio[I] << " L: " << ratio[L] << " T: " << ratio[T] << std::endl; } } // placing remaining stones (with random shape and rotation) // it is trying to keep ratio 1:1:1 int remaining_stones_cnt = (board_size/2)*board_size + (board_size/2+1)*(board_size/2); std::vector<Stone> temp_board (remaining_stones_cnt); StoneType min_ratio; // stone type with the smallest count of stones for (int x = 0; x < remaining_stones_cnt; x++) { min_ratio = minimum(ratio); temp_board[x].type = min_ratio; temp_board[x].rotation = rand() % 4; (ratio[min_ratio])++; //std::cout << "ratio.. I: " << ratio[I] << " L: " << ratio[L] << " T: " << ratio[T] << std::endl; } // shuffle remaining stones unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); auto engine = std::default_random_engine{seed}; std::shuffle(std::begin(temp_board), std::end(temp_board), engine); // adding remaining stones to the even rows (N/2)*N for (int x = 2; x <= board_size; x+=2) { for (int y = 1; y <= board_size; y++) { board[INDEX(x,y)] = temp_board.back(); temp_board.pop_back(); } } // adding remaining stones to the odd rows, where column is even ((N/2+1)*(N/2)) for (int x = 1; x <= board_size; x+=2) { for (int y = 2; y <= board_size; y+=2) { board[INDEX(x,y)] = temp_board.back(); temp_board.pop_back(); } } free_stone.type = minimum(ratio); }