Print

Print


Hi all,
I'm playing around with using ECJ to evolve game-playing agents. In
the particular, at the moment, I'm prototyping my ideas by evolving
Tic-Tac-Toe players. I want fitness to be evaluated by each program
playing 5 matches with randomly selected opponents. Their fitness will
be a sum of the number of wins they wind up with, plus half a point
for each draw. Each match consists of playing the same engine twice,
once with X and once with O. I'm not sure if I'm implementing this
correctly or not, so I thought I'd see what you all think.

Here are my evaluation settings:
eval = ec.coevolve.CompetitiveEvaluator
eval.style = rand-2-ways
eval.group-size = 5

Here is the evaluate function:

    public void evaluate(EvolutionState state, Individual[] ind,
boolean[] updateFitness, boolean countVictoriesOnly, int [] someInts,
int threadnum)
    {
        float [] fitnesses = new float [] {0,0}; // resulting
fitnesses of the individuals

    	reset(); // set up a new game
        int index = 0; // index of individual whose turn it is
        //state.output.message("Game 1:");
        while (moves.size() > 0){ // i.e., while legal moves exist
        	// calling eval on an individual causes it to choose a move
        	((GPIndividual)ind[index]).trees[0].child.eval(state,
threadnum, (GPData)input, stack, (GPIndividual)ind[0], this);
            makemove(); // make the chosen move, calculate next set of
legal moves
            index = (index + 1) % 2; // next player's turn
        }
        if (game_over()){ // bad name, but this checks to see whether
there are 3 marks in a row
        	// someone won
        	int winner = (index + 1) % 2;
        	fitnesses[winner] += 1; // 1 point for a win
        } else {
            fitnesses[0] += 0.5; // half point for a tie
            fitnesses[1] += 0.5;
        }

        // set up a second game
        reset();
        index = 1; // the other individual goes first this time
        //state.output.message("Game 2:");
        while (moves.size() > 0){
        	((GPIndividual)ind[index]).trees[0].child.eval(state,
threadnum, (GPData)input, stack, (GPIndividual)ind[0], this);
            makemove();
            index = (index + 1) % 2;
        }
        if (game_over()){
        	// someone won
        	int winner = (index + 1) % 2;
        	fitnesses[winner] += 1;
        } else {
            fitnesses[0] += 0.5;
            fitnesses[1] += 0.5;
        }

        // games are over: time to actually update the fitnesses
        for (int i = 0; i < 2; i++)
        	if (updateFitness[i]){
        		KozaFitness fitness = ((KozaFitness)ind[0].fitness);
        		fitness.setStandardizedFitness(state,
fitness.standardizedFitness() + fitnesses[i]);
        	}
        }