SgHashCode SequenceHash::Hash(const PointSequence& seq) { BenzeneAssert(seq.size() < (std::size_t)BITSETSIZE); const HashData& data = GetHashData(); SgHashCode ret; for (std::size_t i = 0; i < seq.size(); ++i) ret.Xor(data.m_hashes[i][seq[i]]); return ret; }
void GameUtil::HistoryToSequence(const MoveSequence& history, PointSequence& sequence) { sequence.clear(); for (MoveSequence::const_iterator it = history.begin(); it != history.end(); ++it) { const Move& move = *it; sequence.push_back(move.Point()); } }
void DfpnSolver::GetPVFromHash(PointSequence& pv) { // to do: SgAssertRestore r(state of search in subclass); int nuMoves = 0; for (;; ++nuMoves) { DfpnData data; if ( ! TTRead(data) || data.m_bestMove == SG_NULLMOVE ) break; pv.push_back(data.m_bestMove); PlayMove(data.m_bestMove); } while (--nuMoves >= 0) UndoMove(); }
// **************************************************************************** // Method: PointSequenceList::GetNextSequence // // Purpose: // Extract another sequence from the connectivity array and return it // as a PointSequence. Skip repeated adjacent points. // // Returns: true if we found another sequence; false otherwise // // Programmer: Jeremy Meredith // Creation: November 1, 2002 // // Modifications: // Rich Cook and Hank Childs, Thu Oct 2 16:32:55 PDT 2008 // Added support for loops. // // Eric Brugger, Tue Dec 29 16:35:34 PST 2009 // I modified the logic that looks for loops to only consider points // that have 2 neighbors. Previously it would have considered points // with no neighbors, which caused it to reference uninitialized memory. // // Jean Favre, Tue May 7 16:38:37 CEST 2013 // I modified the calls to GetPoint() to use the other variant of the call // with two arguments. The previous version would never succeed in the test // to remove sequential identical points. // Used vtkIdType where needed // **************************************************************************** bool vtkConnectedTubeFilter::PointSequenceList::GetNextSequence(PointSequence &seq) { // index is already set by InitTraversal and previous calls to this fn for (; index < len; index++) { // if numneighbors is 1, then this is a start point if (((lookforloops && numneighbors[index] == 2) || numneighbors[index] == 1) && !visited[index]) { vtkIdType current = index; vtkIdType previous = -1; seq.Init(len); seq.Add(current, cellindex[current]); visited[current] = true; while (true) { vtkIdType n1 = connectivity[0][current]; vtkIdType n2 = connectivity[1][current]; vtkIdType next = (n1 == previous) ? n2 : n1; previous = current; current = next; // we must skip any sequential identical points: // 1) they are useless, and 2) they mess up calculations double prePt[3]; double curPt[3]; pts->GetPoint(previous, prePt); pts->GetPoint(current, curPt); if (prePt[0] != curPt[0] || prePt[1] != curPt[1] || prePt[2] != curPt[2]) { seq.Add(current, cellindex[current]); } // check for a loop (AFTER adding the node again...) if (lookforloops && visited[current]) { break; } visited[current] = true; bool endpoint = (numneighbors[current] == 1); if (endpoint) break; } // We may have one duplicated cell index due to the way the // connectivity was built -- shift them all down by one from // the right spot, so the only duplicated one is the last one. for (int i=1; i<seq.length-1; i++) { if (seq.cellindex[i-1] == seq.cellindex[i]) seq.cellindex[i] = seq.cellindex[i+1]; } // true ==> success; got another sequence return true; } } if (index == len && !lookforloops) { lookforloops = true; index=0; return GetNextSequence(seq); } // false ==> failed; no more sequences return false; }
inline void DfsSolutionSet::SetPV(HexPoint cell, const PointSequence& old) { pv.clear(); pv.push_back(cell); pv.insert(pv.end(), old.begin(), old.end()); }
inline void DfsSolutionSet::SetPV(HexPoint cell) { pv.clear(); pv.push_back(cell); }
/** Does a 1-ply search. For each move in the consider set, if the move is a win, returns true and the move. If the move is a loss, prune it out of the consider set if there are non-losing moves in the consider set. If all moves are losing, perform no pruning, search will resist. Returns true if there is a win, false otherwise. @todo Is it true that MoHex will resist in the strongest way possible? */ bool MoHexPlayer::PerformPreSearch(HexBoard& brd, HexColor color, bitset_t& consider, double maxTime, PointSequence& winningSequence) { bitset_t losing; HexColor other = !color; PointSequence seq; bool foundWin = false; SgTimer elapsed; Resistance resist; resist.Evaluate(brd); std::vector<HexPoint> moves; SortConsiderSet(consider, resist, moves); for (std::size_t i = 0; i < moves.size() && !foundWin; ++i) { if (elapsed.GetTime() > maxTime) { LogInfo() << "PreSearch: max time reached " << '(' << i << '/' << moves.size() << ").\n"; break; } brd.PlayMove(color, moves[i]); seq.push_back(moves[i]); if (EndgameUtil::IsLostGame(brd, other)) // Check for winning move { winningSequence = seq; foundWin = true; } else if (EndgameUtil::IsWonGame(brd, other)) losing.set(moves[i]); seq.pop_back(); brd.UndoMove(); } // Abort if we found a one-move win if (foundWin) return true; // Backing up cannot cause this to happen, right? BenzeneAssert(!EndgameUtil::IsDeterminedState(brd, color)); // Use the backed-up ice info to shrink the moves to consider if (m_backup_ice_info) { bitset_t new_consider = EndgameUtil::MovesToConsider(brd, color) & consider; if (new_consider.count() < consider.count()) { consider = new_consider; LogFine() << "$$$$$$ new moves to consider $$$$$$" << brd.Write(consider) << '\n'; } } // Subtract any losing moves from the set we consider, unless all of them // are losing (in which case UCT search will find which one resists the // loss well). if (losing.any()) { if (BitsetUtil::IsSubsetOf(consider, losing)) LogInfo() << "************************************\n" << " All UCT root children are losing!!\n" << "************************************\n"; else { LogFine() << "Removed losing moves: " << brd.Write(losing) << '\n'; consider = consider - losing; } } BenzeneAssert(consider.any()); LogInfo() << "Moves to consider:\n" << brd.Write(consider) << '\n'; return false; }