Your idea with the operators is very good. Please post your program
when you are finished!

I used a very simple approach: each individual consists of a sequential
number of rules, which are looked through one after another, and the
first rule that fires is executed. Each rule consists of 9 fields that
are used as a match-template for the world. For example a template
looks like this:

[[EMPTY, DONT_CARE, DONT_CARE, DONT_CARE, X, X, O, X, O], 3]

That means that the template matches if the first field of the world is
empty, field 2, 3, 4 are irrelevent, field 4 has to be an X, and so on.
If the template matches the world, the rule triggeres and the player
tries to put its sign to field 3.

I have implemented the standard operators mutation, crossover, roulette
wheel selection, and co-evolution, but over time the population always
gets stuck in a local maximum very early, the solutions are barely able
to play two moves.

martinus