void GoBook::Add(const GoBoard& bd, SgPoint move)
{
    if (move != SG_PASS && bd.Occupied(move))
        throw SgException("point is not empty");
    if (! bd.IsLegal(move))
        throw SgException("move is not legal");
    const GoBook::MapEntry* mapEntry = LookupEntry(bd);
    if (mapEntry == 0)
    {
        vector<SgPoint> moves;
        moves.push_back(move);
        GoBoard tempBoard;
        InsertEntry(GetSequence(bd), moves, bd.Size(), tempBoard, 0);
    }
    else
    {
        size_t id = mapEntry->m_id;
        SG_ASSERT(id < m_entries.size());
        Entry& entry = m_entries[id];
        int invRotation = SgPointUtil::InvRotation(mapEntry->m_rotation);
        SgPoint rotMove = SgPointUtil::Rotate(invRotation, move, bd.Size());
        if (! Contains(entry.m_moves, rotMove))
            entry.m_moves.push_back(rotMove);
    }
}
Beispiel #2
0
GoSetup GoSetupUtil::CurrentPosSetup(const GoBoard& bd)
{
    GoSetup setup;
    setup.m_player = bd.ToPlay();
    for (GoBoard::Iterator it2(bd); it2; ++it2)
    {
        SgPoint p = *it2;
        if (bd.Occupied(p))
            setup.m_stones[bd.GetColor(p)].Include(p);
    }
    return setup;
}
Beispiel #3
0
int GoEyeUtil::CountSinglePointEyes2(const GoBoard& board, SgPoint p)
{
    if (! board.Occupied(p))
        return 0;

    SgBlackWhite color = board.GetColor(p);
    int numeyes = 0;

    for (GoBoard::LibertyIterator lib(board, p); lib; ++lib)
    {
        if (IsSinglePointEye2(board, *lib, color))
            numeyes++;
    }
    
    return numeyes;
}
Beispiel #4
0
GoLadderStatus GoLadderUtil::LadderStatus(const GoBoard& bd, SgPoint prey,
                                          bool twoLibIsEscape,
                                          SgPoint* toCapture,
                                          SgPoint* toEscape)
{
    SG_ASSERT(bd.IsValidPoint(prey));
    SG_ASSERT(bd.Occupied(prey));
#ifndef NDEBUG
    SgHashCode oldHash = bd.GetHashCode();
#endif
    // Unsettled only if can capture when hunter plays first, and can escape
    // if prey plays first.
    GoLadder ladder;
    SgBlackWhite preyColor = bd.GetStone(prey);
    SgVector<SgPoint> captureSequence;
    GoLadderStatus status = GO_LADDER_ESCAPED;
    if (ladder.Ladder(bd, prey, SgOppBW(preyColor), &captureSequence,
                      twoLibIsEscape) < 0)
    {
        SgVector<SgPoint> escapeSequence;
        if (ladder.Ladder(bd, prey, preyColor, &escapeSequence,
                          twoLibIsEscape) < 0)
            status = GO_LADDER_CAPTURED;
        else
        {
            status = GO_LADDER_UNSETTLED;
            // Unsettled = ladder depends on who plays first, so there must
            // be a move that can be played.
            SG_ASSERT(captureSequence.NonEmpty());
            // escapeSequence can be empty in 2 libs, prey to play case
            SG_ASSERT(twoLibIsEscape || escapeSequence.NonEmpty());
            if (toCapture)
                *toCapture = captureSequence.Front();
            if (toEscape)
                *toEscape = escapeSequence.IsEmpty() ? SG_PASS :
                                                       escapeSequence.Front();
        }
    }
#ifndef NDEBUG
    // Make sure Ladder didn't change the board position.
    SG_ASSERT(oldHash == bd.GetHashCode());
#endif
    return status;
}
Beispiel #5
0
bool GoLadderUtil::Ladder(const GoBoard& bd, SgPoint prey,
                          SgBlackWhite toPlay, bool twoLibIsEscape,
                          SgVector<SgPoint>* sequence)
{
    SG_ASSERT(bd.IsValidPoint(prey));
    SG_ASSERT(bd.Occupied(prey));
    // @todo for an unsettled block with 2 liberties, it
    // immediately says it can escape, but does not return a move.
    // Sequence is empty.  Have to special case this and look for
    // moves that escape from ladder myself.
#ifndef NDEBUG
    SgHashCode oldHash = bd.GetHashCode();
#endif
    GoLadder ladder;
    int result = ladder.Ladder(bd, prey, toPlay, sequence, twoLibIsEscape);
#ifndef NDEBUG
    // Make sure Ladder didn't change the board position.
    SG_ASSERT(oldHash == bd.GetHashCode());
#endif
    SG_ASSERT(result != 0);
    return (result < 0);
}
Beispiel #6
0
void GoBoardUpdater::Update(const SgNode* node, GoBoard& bd)
{
    ////SG_ASSERT(node != 0);
    m_nodes.clear();
    while (node != 0)
    {
        m_nodes.push_back(node);
        node = node->Father();
    }
    const SgNode* root = m_nodes[m_nodes.size() - 1];
    int size = GO_DEFAULT_SIZE;
    SgPropInt* boardSize = static_cast<SgPropInt*>(root->Get(SG_PROP_SIZE));
    if (boardSize)
    {
        size = boardSize->Value();
        ////SG_ASSERT(SgUtil::InRange(size, SG_MIN_SIZE, SG_MAX_SIZE));
    }
    bd.Init(size);
    for (vector<const SgNode*>::reverse_iterator it = m_nodes.rbegin();
         it != m_nodes.rend(); ++it)
    {
        const SgNode* node = *it;
        SgEmptyBlackWhite player = GetPlayer(node);
        if (node->HasProp(SG_PROP_ADD_EMPTY)
            || node->HasProp(SG_PROP_ADD_BLACK)
            || node->HasProp(SG_PROP_ADD_WHITE))
        {
            // Compute the new initial setup position to re-initialize the
            // board with
            GoSetup setup = GoSetupUtil::CurrentPosSetup(bd);
            if (player != SG_EMPTY)
                setup.m_player = player;
            if (node->HasProp(SG_PROP_ADD_BLACK))
            {
                SgPropAddStone* prop =
                  dynamic_cast<SgPropAddStone*>(node->Get(SG_PROP_ADD_BLACK));
                const SgVector<SgPoint>& addBlack = prop->Value();
                for (SgVectorIterator<SgPoint> it2(addBlack); it2; ++it2)
                {
                    SgPoint p = *it2;
                    setup.m_stones[SG_WHITE].Exclude(p);
                    if (! setup.m_stones[SG_BLACK].Contains(p))
                        setup.AddBlack(p);
                }
            }
            if (node->HasProp(SG_PROP_ADD_WHITE))
            {
                SgPropAddStone* prop =
                  dynamic_cast<SgPropAddStone*>(node->Get(SG_PROP_ADD_WHITE));
                const SgVector<SgPoint>& addWhite = prop->Value();
                for (SgVectorIterator<SgPoint> it2(addWhite); it2; ++it2)
                {
                    SgPoint p = *it2;
                    setup.m_stones[SG_BLACK].Exclude(p);
                    if (! setup.m_stones[SG_WHITE].Contains(p))
                        setup.AddWhite(p);
                }
            }
            if (node->HasProp(SG_PROP_ADD_EMPTY))
            {
                SgPropAddStone* prop =
                  dynamic_cast<SgPropAddStone*>(node->Get(SG_PROP_ADD_EMPTY));
                const SgVector<SgPoint>& addEmpty = prop->Value();
                for (SgVectorIterator<SgPoint> it2(addEmpty); it2; ++it2)
                {
                    SgPoint p = *it2;
                    setup.m_stones[SG_BLACK].Exclude(p);
                    setup.m_stones[SG_WHITE].Exclude(p);
                }
            }
            bd.Init(bd.Size(), setup);
        }
        else if (player != SG_EMPTY)
            bd.SetToPlay(player);
        if (node->HasProp(SG_PROP_MOVE))
        {
            SgPropMove* prop =
                dynamic_cast<SgPropMove*>(node->Get(SG_PROP_MOVE));
            SgPoint p = prop->Value();
            if (p == SG_PASS || ! bd.Occupied(p))
                bd.Play(p, prop->Player());
        }
    }
}