void SpLadderMoveGenerator::GenerateMoves(SgEvaluatedMoves& eval,
                                          SgBlackWhite toPlay)
{
    GoModBoard modBoard(m_board);
    GoBoard& bd = modBoard.Board();
    // Don't permit player to kill its own groups.
    GoRestoreToPlay restoreToPlay(bd);
    bd.SetToPlay(toPlay);
    GoRestoreSuicide restoreSuicide(bd, false);
    for (SgBlackWhite color = SG_BLACK; color <= SG_WHITE; ++color)
    {
        for (SgConnCompIterator it(bd.All(color), bd.Size());
             it; ++it)
        {
            SgPointSet block(*it);
            SgPoint p = block.PointOf(), toCapture, toEscape; 
            GoLadderStatus st = LadderStatus(bd, p, false, &toCapture,
                                             &toEscape);
            if (st == GO_LADDER_UNSETTLED)
            {
                SgPoint move =
                    color == bd.ToPlay() ? toEscape : toCapture;
                int size = 1000 * block.Size();
                eval.AddMove(move, size);
                if ((color == bd.ToPlay()) && (move == SG_PASS))
                {
                    // try liberties
                    for (GoBoard::LibertyIterator it(bd, p); it; ++it)
                    {
                        SgPoint lib = *it;
                        GoMoveExecutor m(bd, lib, color);
                        if (m.IsLegal() && bd.Occupied(p))
                        {
                            SgPoint toCapture2, toEscape2; 
                            GoLadderStatus st2 =
                                LadderStatus(bd, p, false, &toCapture2,
                                             &toEscape2);
                            if (st2 == GO_LADDER_ESCAPED)
                                eval.AddMove(lib, size);
                        }
                    }
                }
            }
        }
    }
}
void SpDumbTacticalMoveGenerator::GenerateDefendMoves(SgEvaluatedMoves& eval)
{
    const int stoneweight = 1000;
    // Do any of own blocks have just one liberty?
    for (GoBlockIterator anchorit(m_board); anchorit; ++anchorit)
    {
        // Ignore opponent blocks
        if (m_board.IsColor(*anchorit, m_board.Opponent()))
            continue;

        // Try to save blocks in atari
        if (! m_board.InAtari(*anchorit))
            continue;
        
        // Don't waste saving blocks that will be laddered to death anyway
        if (m_useLadders)
        {
            GoLadderStatus status = LadderStatus(m_board, *anchorit, false);
            if (status == GO_LADDER_CAPTURED)
                continue;
        }
        
        int score = stoneweight * m_board.NumStones(*anchorit);

        // Generate liberty
        eval.AddMove(m_board.TheLiberty(*anchorit), score);
        
        // Generate any captures that will save the group
        for (GoAdjBlockIterator<GoBoard> adjbit(m_board, *anchorit, 1);
             adjbit; ++adjbit)
        {
            int bonus = stoneweight * m_board.NumStones(*adjbit);
            if (m_board.InAtari(*adjbit)) 
            // should always be true but just in case
            {
                eval.AddMove(m_board.TheLiberty(*adjbit), score + bonus);
            }
        }
    }
}
    void HyperNEATMoveGenerator::GenerateMoves(
        SgEvaluatedMoves& eval,
        SgBlackWhite toPlay
        )
    {
        GoRestoreToPlay restoreToPlay(m_board);
        m_board.SetToPlay(toPlay);
        // Don't permit player to kill its own groups.
        GoRestoreSuicide restoreSuicide(m_board, false);

        //Passing is an option
        eval.AddMove(SG_PASS,0);

        experiment->generateMoves(eval);

        // Otherwise make a random legal move that doesn't fill own eye
        // This will be done automatically by the simple player if no moves
        // have been generated.
        //TODO: SINCE WE ADD PASS MOVE, THIS SHOULD NEVER HAPPEN
    }
    void GoExperiment::generateMoves(SgEvaluatedMoves& eval)
    {
        if(goBoardSize != self->Board().Size())
        {
            cout << "DIFFERENT SIZE BOARD IS NOT SUPPORTED YET!\n";
            throw CREATE_LOCATEDEXCEPTION_INFO("DIFFERENT SIZE BOARD IS NOT SUPPORTED YET!");
        }

        //First, have HyperNEAT generate a move
		substrates[0].getNetwork()->reinitialize();
        for(int r=0;r<goBoardSize;r++)
        {
            for(int c=0;c<goBoardSize;c++)
            {
                SgBoardColor boardColor = self->Board().GetColor(SgPointUtil::Pt(c+1,r+1));
#if USE_SINGLE_LAYER_FOR_PIECES
                if(boardColor==SG_BLACK)
                {
                    substrates[0].setValue( Node(r,c,0) , 1 );
                }
                else if(boardColor==SG_WHITE)
                {
                    substrates[0].setValue( Node(r,c,0) , -1 );
                }
                else //c==SG_EMPTY
                {
                    substrates[0].setValue( Node(r,c,0) , 0 );
                }
#else
                if(boardColor==SG_BLACK)
                {
                    substrates[0].setValue( Node(r,c,0) , 1 );
                }
                else
                {
                    substrates[0].setValue( Node(r,c,0) , -1 );
                }

                if(boardColor==SG_WHITE)
                {
                    substrates[0].setValue( Node(r,c,1) , 1 );
                }
                else
                {
                    substrates[0].setValue( Node(r,c,1) , -1 );
                }
#endif
            }
        }
        substrates[0].getNetwork()->dummyActivation();
        substrates[0].getNetwork()->update();

        //Get a sorted list of moves to make
        moves.clear();
        for(int r=0;r<goBoardSize;r++)
        {
            for(int c=0;c<goBoardSize;c++)
            {
                SgPoint p = SgPointUtil::Pt(c+1,r+1);
                if(
                    self->Board().IsLegal(p)
                    )
                {
                    int index = substrates[0].getLayerIndex("Output");
                    float moveMotivation = substrates[0].getValue(Node(r,c,index));

                    if(moveMotivation>0)
                    {
                        moves.push_back(MoveRating(moveMotivation,p));
                    }
                }
            }
        }
        sort(moves.begin(),moves.end());

        int curSize = eval.moveListSize();
        for(int a=int(moves.size())-1;a>=0;a--)
        {
            //Since the values are floats, don't bother with them and just add the best move
            eval.AddMove(moves[a].move,1000);
            if(curSize != eval.moveListSize())
            {
                //Move was accepted, we are done
                break;
            }
        }
    }
void SpDumbTacticalMoveGenerator::GenerateAttackMoves(SgEvaluatedMoves& eval)
{
    const int capturestoneweight = 100;
    const int firstlibweight = 100;
    const int secondlibweight = 20;
    const int stoneweight = 1;

    // Do Benson life test
    SgBWSet safepoints;
    GoModBoard modBoard(m_board);
    GoBoard& bd = modBoard.Board();
    GoBensonSolver benson(bd);
    benson.FindSafePoints(&safepoints);
    
    // Find opponent blocks without two eyes (using Benson algorithm)
    for (GoBlockIterator anchorit(bd); anchorit; ++anchorit)
    {
        // Ignore own blocks
        if (bd.IsColor(*anchorit, bd.ToPlay()))
            continue;
        
        // Ignore opponent blocks that are unconditionally alive
        if (safepoints[bd.Opponent()].Contains(*anchorit))
            continue;

        // Generate all ladder captures
        if (m_useLadders)
        {
            SgPoint tocapture, toescape;
            GoLadderStatus status = LadderStatus(bd, *anchorit, false,
                                                 &tocapture, &toescape);
            if (status == GO_LADDER_CAPTURED)
            {
                int score = bd.NumStones(*anchorit) * capturestoneweight;
                eval.AddMove(tocapture, score);
            }
        }
            
        // Score according to:
        // 1. -First liberties
        // 2. +Second liberties
        // 3. +Size of group
        // [4]. Own liberties?
        int firstlibs = bd.NumLiberties(*anchorit);
        int size = bd.NumStones(*anchorit);
        for (GoBoard::LibertyIterator libit(bd, *anchorit); libit;
             ++libit)
        {
            int secondlibs = 0;
            for (SgNb4Iterator nbit(*libit); nbit; ++nbit)
            {
                if (bd.IsValidPoint(*nbit) && bd.IsEmpty(*nbit))
                {
                    secondlibs++;
                }
            }
            int score   = size * stoneweight
                        + secondlibs * secondlibweight
                        - firstlibs * firstlibweight;
            eval.AddMove(*libit, score);
        }
    }
}