void GoGame::PlaceHandicap(const SgVector<SgPoint>& stones) { SG_ASSERT(GoBoardUtil::IsBoardEmpty(m_board)); SgNode* node = m_current; if (node->HasSon()) node = node->NewRightMostSon(); SgPropAddStone* addBlack = new SgPropAddStone(SG_PROP_ADD_BLACK); for (SgVectorIterator<SgPoint> it(stones); it; ++it) addBlack->PushBack(*it); node->Add(addBlack); SgPropInt* handicap = new SgPropInt(SG_PROP_HANDICAP, stones.Length()); node->Add(handicap); node->Add(new SgPropPlayer(SG_PROP_PLAYER, SG_WHITE)); m_board.Rules().SetHandicap(stones.Length()); GoToNode(node); }
/** Generates a move using WolveSearch. */ HexPoint WolvePlayer::Search(const HexState& state, const Game& game, HexBoard& brd, const bitset_t& consider, double maxTime, double& outScore) { UNUSED(game); m_search.SetRootMovesToConsider(consider); m_search.SetWorkBoard(&brd); m_search.SetHashTable(m_hashTable.get()); m_search.SetToPlay(HexSgUtil::HexColorToSgColor(state.ToPlay())); SgVector<SgMove> PV; WolveSearchControl timeControl(maxTime, m_useEarlyAbort, PV); m_search.SetSearchControl(&timeControl); std::size_t minDepth = MinDepth(); std::size_t maxDepth = MaxDepth(); if (!m_search.SpecificPlyWidths().empty()) { LogInfo() << "Using specific plywidths!!\n"; if (maxDepth > m_search.SpecificPlyWidths().size()) { maxDepth = m_search.SpecificPlyWidths().size(); LogWarning() << "Max depth exceeds depth specified in ply_width!\n" << "Capping maxDepth to be safe.\n"; } } LogInfo() << "minDepth=" << minDepth << ' ' << "maxDepth=" << maxDepth << '\n'; int score = m_search.IteratedSearch(int(minDepth), int(maxDepth), -SgSearchValue::MIN_PROVEN_VALUE, +SgSearchValue::MIN_PROVEN_VALUE, &PV, false); if (m_search.GuiFx()) WolveSearchUtil::DumpGuiFx(state, *m_hashTable); LogInfo() << PrintStatistics(score, PV); outScore = score; if (PV.Length() > 0) return static_cast<HexPoint>(PV[0]); LogWarning() << "**** WolveSearch returned empty sequence!\n" << "**** Returning random move!\n"; return BoardUtil::RandomEmptyCell(state.Position()); }
/** Play prey move and update all the relevant information. Extend the prey by playing at its only liberty, or capture a block adjacent to the prey. */ int GoLadder::PlayPreyMove(int depth, SgPoint move, SgPoint lib1, const GoPointList& adjBlk, SgVector<SgPoint>* sequence) { int result = 0; GoPointList newAdj(adjBlk); SgVector<SgPoint> newLib; SgVector<SgPoint> newStones; SgVector<SgPoint> neighbors; if (move == lib1) { NeighborsOfColor(*m_bd, move, m_preyColor, &neighbors); for (SgVectorIterator<SgPoint> iter(neighbors); iter; ++iter) { SgPoint block = *iter; if (! m_partOfPrey[block]) { MarkStonesAsPrey(block, &newStones); GoPointList temp = GoBoardUtil::AdjacentStones(*m_bd, block); newAdj.PushBackList(temp); for (GoBoard::LibertyIterator it(*m_bd, block); it; ++it) newLib.Include(*it); } } m_partOfPrey.Include(move); } if (PlayIfLegal(*m_bd, move, m_preyColor)) { if (move == lib1) { NeighborsOfColor(*m_bd, move, SG_EMPTY, &neighbors); for (SgVectorIterator<SgPoint> iter(newLib); iter; ++iter) { SgPoint point = *iter; // Test for Empty is necessary because newLib will include // the move just played. if (m_bd->IsEmpty(point)) neighbors.Include(point); } } else { neighbors.PushBack(lib1); } if (m_bd->CapturingMove()) { // Add the points at the captured stones that are adjacent to the // prey to the liberties, at least if exactly one stone captured. for (GoPointList::Iterator it(m_bd->CapturedStones()); it; ++it) { SgPoint stone = *it; if (PointIsAdjToPrey(stone)) neighbors.Include(stone); } } SG_ASSERT(! neighbors.IsEmpty()); lib1 = neighbors[0]; SG_ASSERT(m_bd->IsEmpty(lib1)); SgArrayList<SgPoint,4> temp = NeighborsOfColor(*m_bd, move, m_hunterColor); newAdj.PushBackList(temp); FilterAdjacent(newAdj); if (neighbors.Length() == 1) result = HunterLadder(depth + 1, lib1, newAdj, sequence); else if (neighbors.Length() == 2) { SgPoint lib2 = neighbors[1]; SG_ASSERT(m_bd->IsEmpty(lib2)); result = HunterLadder(depth + 1, lib1, lib2, newAdj, sequence); } else // 3 <= numLib { if (sequence) sequence->Clear(); result = GOOD_FOR_PREY - (depth + 1); } if (sequence) sequence->PushBack(move); m_bd->Undo(); } else { if (sequence) sequence->Clear(); result = GOOD_FOR_HUNTER + depth; } m_partOfPrey.Exclude(move); m_partOfPrey.Exclude(newStones); return result; }