bool GameUtil::SequenceFromPosition(const Game& game, const StoneBoard& pos, 
                                    MoveSequence& seq)
{
    if (game.Board().Const() != pos.Const())
        return false;
    StoneBoard cur(pos);
    cur.StartNewGame();
    if (cur == pos)
    {
        seq = game.History();
        return true;
    }
    const MoveSequence& history = game.History();
    for (MoveSequence::const_iterator it = history.begin(); 
         it != history.end(); ++it)
    {    
        const Move& move = *it;
        cur.PlayMove(move.Color(), move.Point());
        if (cur == pos)
        {
            LogInfo() << "Position matched!\n";
            seq.assign(++it, history.end());
            return true;
        }
    }
    return false;
}
void DfpnSolver::PropagateBackwards(const Game& game, DfpnStates& pos)
{
    HexState state(game.Board(), BLACK);
    MoveSequence history(game.History());
    if (history.empty())
        return;
    do
    {
        HexPoint cell = history.back().point();
        state.UndoMove(cell);
        state.SetToPlay(history.back().color());
        history.pop_back();
        DfpnData data;
        if (!pos.Get(state, data))
            break;
        if (data.m_bounds.IsSolved())
            break;
        std::vector<DfpnData> childrenData(data.m_children.Size());
        for (size_t i = 0; i < data.m_children.Size(); ++i)
            LookupData(childrenData[i], data.m_children, i, state);
        size_t maxChildIndex = ComputeMaxChildIndex(childrenData);
        UpdateBounds(data.m_bounds, childrenData, maxChildIndex);
        pos.Put(state, data);
    } while(!history.empty());
}
bool GameUtil::IsGameOver(const Game& game)
{
    Groups groups;
    GroupBuilder::Build(game.Board(), groups);
    return groups.IsGameOver();
}