bool doSwap() const { // Get parent dir auto dir = archive_->dir(path_); if (dir) return dir->swapEntries(index1_, index2_); return false; }
static void shuffleVector(std::vector<T> &v, unsigned int start, unsigned int end) { for (unsigned int i = start + 1; i < end; i++) { unsigned int range = i - start; unsigned int j = ((unsigned int) (start + (range * ((double)rand()/RAND_MAX)))) % range; swapEntries(v, i, j); } }
// ----------------------------------------------------------------------------- // Swaps [entry1] and [entry2]. // Returns false if either entry is invalid or if both entries are not in the // same directory, true otherwise // ----------------------------------------------------------------------------- bool Archive::swapEntries(ArchiveEntry* entry1, ArchiveEntry* entry2) { // Abort if read only if (read_only_) return false; // Check both entries if (!checkEntry(entry1) || !checkEntry(entry2)) return false; // Check neither entry is locked if (entry1->isLocked() || entry2->isLocked()) return false; // Get their directory auto dir = entry1->parentDir(); // Error if no dir if (!dir) return false; // Check they are both in the same directory if (entry2->parentDir() != dir) { Log::error("Can't swap two entries in different directories"); return false; } // Get entry indices int i1 = dir->entryIndex(entry1); int i2 = dir->entryIndex(entry2); // Check indices if (i1 < 0 || i2 < 0) return false; // Create undo step if (UndoRedo::currentlyRecording()) UndoRedo::currentManager()->recordUndoStep(std::make_unique<EntrySwapUS>(dir, i1, i2)); // Swap entries dir->swapEntries(i1, i2); // Announce the swap announce("entries_swapped"); // Set modified setModified(true); // Return success return true; }
void HexMC1Player::Move(HexBoard &board, HexColor turn, unsigned int &row, unsigned int &col) { clock_t tStart = clock(); const unsigned int nTrials = 1000; // keep track of best play and best score int bestScore = -1; unsigned int bestPlay; // obtain the currently open cells HexCellSet hcs; board.GetCells(hcs, HEXBLANK); unsigned int nCells = hcs.size(); // shuffle cells to examine them in random order shuffleVector(hcs, 0, nCells); // precompute the order of moves during simulation HexColor turns[2]; turns[0] = turn; turns[1] = ((turn == HEXBLUE) ? HEXRED : HEXBLUE); // now evaluate each cell in turn for (unsigned int iCell = 0; iCell < nCells; iCell++) { // make a working copy of the cell set HexCellSet hcsCopy(hcs); // store away the current cell by swapping with last cell swapEntries(hcsCopy, iCell, nCells - 1); // run MC simulation int nWins = 0; for (unsigned int iTrial = 0; iTrial < nTrials; iTrial++) { // shuffle the first n-1 entries (keeping the current cell safely at the end) // to randomize the order in which cells are played in simulation shuffleVector(hcsCopy, 0, nCells-1); // make a copy of the board to run simulated game HexBoard boardCopy(board); // alternate turns until board is full (until no more cells to play) for (unsigned int iTurn = 0; iTurn < nCells; iTurn++) { // for the first move, play the cell currently under evaluation, // which is stored at the end of the vector. // for subsequent moves, play each cell in succession, starting from 0th cell unsigned int thisMove = ((iTurn == 0) ? (nCells - 1) : (iTurn - 1)); HexColor thisColor = turns[iTurn % 2]; boardCopy.SetColor(hcsCopy[thisMove].row, hcsCopy[thisMove].col, thisColor); } // find out who won this simulated game HexColor winner = boardCopy.Winner(); // if we won, update stats if (winner == turn) { nWins++; } } if (nWins > bestScore) { bestScore = nWins; bestPlay = iCell; if (nWins == nTrials) { // if this cell won all its trials, then play it break; } } } // return the best play we found clock_t tEnd = clock(); clock_t tElapsed = (tEnd - tStart) / CLOCKS_PER_SEC; std::cout << "Time elapsed: " << tElapsed << "(secs) \n"; row = hcs[bestPlay].row; col = hcs[bestPlay].col; }