UCTNode* getNewChild(UCTNode* node, std::default_random_engine& engine) { node->mutex.lock(); if (node->possibleChildren.empty() && node->child == nullptr) { auto state = node->getState(); auto legalMoves = state->getPossibleMoves(); for (unsigned short i = 0; i < legalMoves.size(); ++i) { node->possibleChildren.push_back((unsigned short)(legalMoves[i]->row*BOARD_SIZE + legalMoves[i]->column)); } } if (node->possibleChildren.size() == 0) { node->mutex.unlock(); return nullptr; } std::uniform_int_distribution<> dist(0, (int)node->possibleChildren.size()-1); unsigned int choice = dist(engine); auto chosenChildIndex = node->possibleChildren[choice]; node->possibleChildren[choice] = node->possibleChildren.back(); node->possibleChildren.pop_back(); node->mutex.unlock(); if (chosenChildIndex == BOARD_SIZE*BOARD_SIZE + BOARD_SIZE) return new UCTNode(BOARD_SIZE, BOARD_SIZE, node); else return new UCTNode((unsigned char)(chosenChildIndex/BOARD_SIZE), (unsigned char)(chosenChildIndex%BOARD_SIZE), node); }
Move getBestMove(board Game, Piece piece, Point point) { Move possibleMoves[26]; int possibleMovesNumber = getPossibleMoves(Game, piece, possibleMoves, point); Move result = NULL; int bestValue = -INFINITY; for (int i = 0; i < possibleMovesNumber; i++) { doMove(Game, possibleMoves[i]); int moveValue = evaluatePosition(Game, aiPlayerNumber, possibleMoves[i]); if (moveValue > bestValue) { result = possibleMoves[i]; bestValue = moveValue; } undoMove(Game, possibleMoves[i]); } for (int i=0; i<possibleMovesNumber; i++) { if (result != possibleMoves[i]) { cleanMoveData(possibleMoves[i]); } } return result; }
std::vector<Position> Table::getPiecesWhichCanBeMoved(const Array &array, PieceColor pieceColor) const { std::vector<std::pair<int,Position>> pieces; int maxMoves = 0; for(int i = 0; i < array.size(); ++i) { for(int z = 0; z < array.size(); ++z) { if(array.get(i,z) && array.get(i,z)->color() == pieceColor) { auto possibleMoves = getPossibleMoves(array, Position(i,z)); if(!possibleMoves.empty()) { auto numberOfCapturedPieces = possibleMoves.at(0).numberOfCapturedPieces(); maxMoves = maxMoves < numberOfCapturedPieces? numberOfCapturedPieces: maxMoves; pieces.push_back(std::make_pair(numberOfCapturedPieces, Position(i,z))); } } } } auto withMaxSizeIt = std::partition(pieces.begin(), pieces.end(), [&maxMoves](const std::pair<int, Position>& pos) { return pos.first == maxMoves; }); std::vector<Position> piecesPositions; std::transform(pieces.begin(), withMaxSizeIt, std::back_inserter(piecesPositions), [](const std::pair<int, Position>& pos) { return pos.second; }); return piecesPositions; }
std::vector<PieceMove> Table::getAllPossibleMoves(const Array& array, PieceColor pieceColor) const { std::vector<std::pair<int,PieceMove>> moves; int maxMoves = 0; for(int i = 0; i < array.size(); ++i) { for(int z = 0; z < array.size(); ++z) { if(array.get(i,z) && array.get(i,z)->color() == pieceColor) { auto possibleMoves = getPossibleMoves(array, Position(i,z)); for(const auto& move: possibleMoves) { auto numberOfCapturedPieces = move.numberOfCapturedPieces(); maxMoves = maxMoves < numberOfCapturedPieces? numberOfCapturedPieces: maxMoves; moves.push_back(std::make_pair(numberOfCapturedPieces, move)); } } } } auto withMaxSizeIt = std::partition(moves.begin(), moves.end(), [&maxMoves](const std::pair<int, PieceMove>& pos) { return pos.first == maxMoves; }); std::vector<PieceMove> possibleMoves; std::transform(moves.begin(), withMaxSizeIt, std::back_inserter(possibleMoves), [](const std::pair<int, PieceMove>& pos) { return pos.second; }); return possibleMoves; }
bool Piece::isValidPossibleMove(int _row,int _col){ list<square> moves; getPossibleMoves(moves); if(type == W_QUEEN || type==B_QUEEN){ //std::cout << "Determining Queen moves" << std::endl; } return isMove(moves,_row,_col); }
bool Board::isMoveAllowed(const playerId player, const Move& move) const { std::list<Move>* pm = &getPossibleMoves(player); std::list<Move>::const_iterator it; for (it = pm->begin(); it != pm->end(); ++it) { if (*it == move) { return true; } } return false; }
bool Board::isValidMove(Point move, std::list<unsigned long int> *previousHashes) { if (move == *pass) return true; if (move.row < 0 || move.row >= BOARD_SIZE) return false; if (move.column < 0 || move.column >= BOARD_SIZE) return false; auto legalMoves = getPossibleMoves(); if (previousHashes != nullptr) eliminatePositionalSuperKo(legalMoves, previousHashes); for (unsigned short i = 0; i < legalMoves.size(); ++i) if (move == *legalMoves[i]) return true; return false; }
void MoveEngine::diceroll(const int& newplayer,const int& face1,const int& face2,const int& face3,const int& face4,bool computer) { checkstate(); player=newplayer; otherplayer=(player==1) ? 2 : 1; dice[0]=face1; dice[1]=face2; dice[2]=face3; dice[3]=face4; marker_current=-1; if(getPossibleMoves()==0) { emit nomove(); return; // player will be changed } if(!computer) return; //human intervention required QTimer::singleShot(2000,this,SLOT(automove())); }
void Rook::getMoves(list<square>& moves){ getPossibleMoves(moves); removeCheck(moves); }
bool Board::canMove(const playerId player) const { return ! getPossibleMoves(player).empty(); }
std::vector<UCBrow> UpperConfidence::generateUCBTable(int color, GoGame* game) { LOG_DEBUG<<"Generating UCB table"<<std::endl; time_t timer; time(&timer); std::vector<UCBrow> ucbtable; LOG_VERBOSE<<"Began UCB"<<std::endl; workingBoard = new GoBoard(game->Board->Size()); workingBoard->resetAndReplayMoves(game->Board); this->color = color; LOG_VERBOSE<<"SD: "<<color<<std::endl; this->game = game; LOG_VERBOSE<<"SD: "<<game<<std::endl; LOG_VERBOSE << "Generating UCB move for "<<color<<std::endl; //Generate possible moves moves = preselRandMoves; if(moves.size() == 0) moves = getPossibleMoves(color, game); float expected[moves.size()]; int numPlayed[moves.size()]; int totalNumPlayed = 0; int initialPlayNum = 1; LOG_VERBOSE << "Play all 1 time"; //Play all moves "once" for(size_t j = 0; j<moves.size(); ++j) { numPlayed[j] = 0; expected[j] = 0; for(int i = 0; i<initialPlayNum; ++i) { float result = simulateMove(moves[j]); if(result > 0) result = 1; else result = 0; float oldWins = expected[j] * numPlayed[j]; ++numPlayed[j]; ++totalNumPlayed; expected[j] = ((float)(result+oldWins)/(float)numPlayed[j]); } } float maximisedVal = 0.0; int nextToPlay = 0; int numSim = numSimulations; while(totalNumPlayed<numSim && playUntilStopped) { //Maximise for all following plays for(size_t i = 0; i<moves.size(); ++i) { float ucbVal = expected[i] + sqrt( expRatio * log(totalNumPlayed) / numPlayed[i]); // LOG_VERBOSE <<i<< " " <<expected[i]<< " "<< sqrt( expRatio * log(totalNumPlayed) / numPlayed[i]) << std::endl; if(ucbVal > maximisedVal) { maximisedVal = ucbVal; nextToPlay = i; } } // LOG_VERBOSE <<nextToPlay<< " " <<expected[nextToPlay]<< " "<< sqrt( expRatio * log(totalNumPlayed) / numPlayed[nextToPlay]) << std::endl; //Play best move and update expected return float result = simulateMove(moves[nextToPlay]); if(result > 0) result = 1; else result = 0; ++numPlayed[nextToPlay]; ++totalNumPlayed; if(playUntilStopped) ++numSim; if(totalNumPlayed%1000==0) std::cerr<<"Simulated "<<totalNumPlayed<<" games"<<std::endl; float oldWins = expected[nextToPlay] * (numPlayed[nextToPlay]-1); expected[nextToPlay] = ((float)(result+oldWins)/(float)numPlayed[nextToPlay]); maximisedVal = 0; nextToPlay = 0; } for(size_t i = 0; i<moves.size(); ++i) { UCBrow u; u.pos = moves[i]; u.expected = expected[i]; u.timesPlayed = numPlayed[i]; ucbtable.push_back(u); } time_t now; time(&now); int perf = (float)totalNumPlayed/difftime(now,timer); std::cerr<<"child; " <<perf<<" sims per sec"<<std::endl; LOG_VERBOSE<<"Completed UCB table"<<std::endl; return ucbtable; }