int Game::minMove(int depth, int alpha, int beta) { std::vector<int> allMoves = getAvailableMoves(); int winner = checkWinner(); if ((allMoves.size() <= 0 || winner > 0) || depth <= 0) { return evaluateState(2, winner); } int* bestMove = NULL; int bestScore = INT_MAX; for (std::vector<int>::const_iterator it = allMoves.begin(); it != allMoves.end(); it++) { setCell(*it, 1); int score = maxMove(depth - 1, alpha, beta); undoMove(*it); if (score < bestScore) { bestScore = score; beta = score; } if (beta < alpha) { return bestScore; } } return bestScore; }
void SA<FunctionType, CoolingScheduleType>::MoveControl(const size_t nMoves, arma::mat& accept) { arma::mat target; target.copy_size(accept); target.fill(0.44); moveSize = arma::log(moveSize); moveSize += gain * (accept / (double) nMoves - target); moveSize = arma::exp(moveSize); // To avoid the use of element-wise arma::min(), which is only available in // Armadillo after v3.930, we use a for loop here instead. for (size_t i = 0; i < accept.n_elem; ++i) moveSize(i) = (moveSize(i) > maxMove(i)) ? maxMove(i) : moveSize(i); accept.zeros(); }
int Game::minMax() { std::vector<int> allMoves = getAvailableMoves(); int bestMove = NULL; int bestScore = INT_MIN; for (std::vector<int>::const_iterator it = allMoves.begin(); it != allMoves.end(); it++) { setCell(*it, 1); int val = maxMove(100, INT_MIN + 1, INT_MAX); undoMove(*it); if (val > bestScore) { bestScore = val; bestMove = *it; } } return bestMove; }
int AI::minValue(vector<vector<int>> tempBoard, vector<Piece> teamCopy, vector<Piece> enemyTeamCopy, int depth, Directions direction){ bool killMove = false; if(!checkNode(tempBoard, teamCopy, enemyTeamCopy, direction, true)){ return OUT_OF_BOUND; } int x = enemyTeamCopy[enemyCurrentIndex].x; int y = enemyTeamCopy[enemyCurrentIndex].y; changeWithDirection(x, y, direction, true); if(sameTeam(tempBoard[x][y],TEAM_NUMBER)){ if(!killCheckArea(tempBoard, x, y, direction, true)){ return OUT_OF_BOUND; } else{ changeWithDirection(x, y, direction, true); killMove = true; } } //This should move on the tempBoard movePiece(tempBoard, enemyTeamCopy, enemyCurrentIndex, x, y); updateKings(tempBoard, enemyTeamCopy, true); if (killMove) { updateTeam(tempBoard, teamCopy, false); if (teamCopy.size()<=0) { //smallest number return -1 * WIN_VALUE; } } if (depth <= 0) { return valueCalculator(teamCopy, enemyTeamCopy); } else{ return maxMove(tempBoard, teamCopy, enemyTeamCopy, depth-1); } }
void OmokAI::normalSearch() { Position w = _game->getPreviousWhite(); auto iter = _root->children.find(w); if (iter == _root->children.cend()) { _root->state->set(Piece::createWhite(w)); _root->children.clear(); } else { _root = iter->second; } double alpha = -std::numeric_limits<double>::infinity(); double beta = std::numeric_limits<double>::infinity(); std::shared_ptr<OmokNode> maxOmokNode; Position maxMove(-1, -1); if (!_root->state->isWin()) { if (_root->children.size() == 0) { buildChildren(_root, 0); } for (auto &node : _root->children) { double a = alphabeta(node.second, alpha, beta, 1); if (a > alpha) { alpha = a; maxOmokNode = node.second; maxMove = node.first; } if (beta <= alpha) { // beta cut-off break; } } assert(_game->isBlackTurn()); _game->put(maxMove); assert(maxOmokNode); _root = maxOmokNode; } }