package com.nullprogram.chess.ai;

import java.util.Random;

import com.nullprogram.chess.Game;
import com.nullprogram.chess.Board;
import com.nullprogram.chess.Player;

import com.nullprogram.chess.boards.StandardBoard;

/**
 * Alternate main class for optimizing AI parameters via genetic algorithm.
 */
public class OptimizeGA {

    /** Random number generator.  */
    private static Random rng;

    /** Maximum range for piece values. */
    static final double PIECE_RANGE = 10.0;

    /** Locked-in dpeth: we don't change this in the population. */
    static final int DEPTH = 4;

    /**
     * Hidden constructor.
     */
    protected OptimizeGA() {
    }

    /**
     * Rather than start the GUI, run undisplayed games.
     *
     * @param args input arguments
     */
    public static void main(final String[] args) {
        rng = new Random();

        Config whiteConf = create();
        Config blackConf = create();
        Player white = new Minimax(null, whiteConf.getProperties());
        Player black = new Minimax(null, whiteConf.getProperties());
        Board board = new StandardBoard();
        Game game = new Game(null, board, white, black);
        game.begin();
    }

    /**
     * Randomly create a new configuration.
     *
     * @return a randomly generated config
     */
    private static Config create() {
        Config conf = new Config();
        conf.put("depth", (double) DEPTH);
        String[] pieces = {"Pawn", "Knight", "Bishop", "Rook", "Queen",
                           "King", "Chancellor", "Archbishop"};
        for (String piece : pieces) {
            Double v = rng.nextDouble() * PIECE_RANGE;
            if ("King".equals(piece)) {
                /* The king has a much larger value range. */
                v *= PIECE_RANGE * PIECE_RANGE;
            }
            conf.put(piece, v);
        }
        conf.put("material", rng.nextDouble());
        conf.put("safety", rng.nextDouble());
        conf.put("mobility", rng.nextDouble());
        return conf;
    }
}

@@ -83,20 +83,99 @@
 m.chess.
-Game
+Piece;%0Aimport com.nullprogram.chess.Game;%0Aimport com.nullprogram.chess.GameListener
 ;%0Aimport
@@ -402,16 +402,40 @@
 imizeGA 
+implements GameListener 
 %7B%0A%0A    /
@@ -687,16 +687,90 @@
 H = 4;%0A%0A
+    /** Maximum number of moves. */%0A    static final int MAX_MOVES = 75;%0A%0A
     /**%0A
@@ -829,24 +829,60 @@
 imizeGA() %7B%0A
+        launch(create(), create());%0A
     %7D%0A%0A    /
@@ -1074,342 +1074,1213 @@
 ();%0A
+        new OptimizeGA();
 %0A    
+%7D%0A%0A
     
-Config whiteConf = create();%0A        Config blackConf = create();%0A        Player white = new Minimax(null, whiteConf.getProperties());%0A        Player black = new Minimax(null, whiteConf.getProperties());%0A        Board board = new StandardBoard();%0A        Game game = new Game(null, board, white, black);%0A        game.begin();
+/**%0A     * Launch a game with players using the given configurations.%0A     *%0A     * @param whiteConf config for the white player%0A     * @param blackConf config for the black player%0A     */%0A    private void launch(final Config whiteConf, final Config blackConf) %7B%0A        Player white = new Minimax(null, whiteConf.getProperties());%0A        Player black = new Minimax(null, whiteConf.getProperties());%0A        Board board = new StandardBoard();%0A        Game game = new Game(null, board, white, black);%0A        game.addListener(this);%0A        game.begin();%0A    %7D%0A%0A    /** %7B@inheritDoc%7D */%0A    public final void gameEvent(final Game game) %7B%0A        if (game.isDone()) %7B%0A            System.out.println(%22Game complete: %22);%0A            if (game.getWinner() == Piece.Side.WHITE) %7B%0A                System.out.println(%22White wins.%22);%0A            %7D else if (game.getWinner() == Piece.Side.BLACK) %7B%0A                System.out.println(%22White wins.%22);%0A            %7D else %7B%0A                System.out.println(%22Stalemate.%22);%0A            %7D%0A        %7D else if (game.getBoard().moveCount() %3E MAX_MOVES) %7B%0A            System.out.println(%22Game timeout!%22);%0A            game.end();%0A        %7D
 %0A   

Set up OptimizeGA for running games.