예제 #1
0
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());
}
예제 #3
0
/** 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;
}