The following source code is a countdown numbers game solver for PocketC:
Note: Daniel Silverstone ported it to "normal" C - here.
//countdown_game
//(c) T.Frogley
#include "sort.i"
#define NUMBERS 6
#define OPSIZE 3
#define ISIZE 18
#define WORST 65535
#define PLUS 0
#define MINUS 1
#define TIMES 2
#define DIVIDE 3
#define DISCARD 4
#define OPCOUNT 5
int source[NUMBERS];
int target;
int abs(int a)
{ if (a<0) return -a;
else return a;}
int Execute(
pointer instructions,
int draw, int bail
)
{
int scratch[NUMBERS];
int size,ip,i;
int a,b,best;
for (ip=0;ip<NUMBERS;ip++)
scratch[ip]=source[ip];
ip = 0;
size = NUMBERS;
best = WORST;
while(size>1){
a=scratch[instructions[ip+1]];
scratch[instructions[ip+1]]=
scratch[--size];
b=scratch[instructions[ip+2]];
scratch[instructions[ip+2]]=
scratch[--size];
i=instructions[ip];
if (i==PLUS){
if (draw) puts(a+"+"+b);
a=a+b;
}
else if (i==MINUS){
if (draw) puts(a+"-"+b);
a=a-b;
}
else if (i==TIMES){
if (draw) puts(a+"*"+b);
a=a*b;
}
else if (i==DIVIDE){
if (draw) puts(a+"/"+b);
if (b==0) return WORST;
if (((a/b)*b)!=a) return WORST;
a=a/b;
}
else if (i==DISCARD){
if (draw) puts("discard "+b+"\n");
}
if (draw)
if (i!=DISCARD)
puts("="+a+"\n");
scratch[size++]=a;
a=abs(a-target);
if (a==bail) return bail;
if (a<best) best=a;
ip=ip+3;
}
return best;
}
Randomize(pointer p)
{
int i,ip;
ip=0;
for (i=0;i<NUMBERS;){
p[ip++]=random(OPCOUNT);
p[ip++]=random(NUMBERS-i++);
p[ip++]= random(NUMBERS-i);
}
}
RandomSearch()
{
int instrucs[ISIZE];
int b,r;
b=WORST;
do{
Randomize(instrucs);
r=Execute(instrucs,0,0);
if (r<b){
clear();
b=r;
Execute(instrucs,1,b);
}
}while(b);
}
CrossMutate(
pointer a,
pointer b,
pointer c
)
{
int i,ip;
pointer r;
ip=0;
for (i=0;i<NUMBERS;i++){
if (random(2)) r=a;
else r=b;
if (random(50))
c[ip]=r[ip];
else
c[ip]=random(OPCOUNT);
ip++;
if (random(50) &&
r[ip]<NUMBERS-(i+1)){
c[ip]=r[ip+1];
ip++;
c[ip]=r[ip-1];
ip++;
}else{
if (random(50))
c[ip]=r[ip];
else
c[ip]=random(NUMBERS-i);
ip++;
if (random(50))
c[ip]=r[ip];
else
c[ip]=random(NUMBERS-(i+1));
ip++;
}
}
}
#define PSIZE 40
int score[PSIZE];
int derefcomp(pointer a, pointer b)
{
return score[*a]-score[*b];
}
GASearch()
{
pointer instructions[PSIZE];
int index[PSIZE];
int r,g,i,gen;
//randomize population
puts("Initialising...");
for(g=0;g<PSIZE;g++){
instructions[g]=malloc(ISIZE);
Randomize(instructions[g]);
index[g] = g;
}
gen = 0;
do{
//test population
puts("Testing...");
for(g=0;g<PSIZE;g++){
score[g]=
Execute(instructions[g],0,0);
if (score[g]==0) break;
}
//sort results, best first
if (g==PSIZE){
puts("Sorting...");
sort(index,PSIZE,1,derefcomp);
}
else index[0]=g;
clear();
puts("in generation "
+(gen++)+":\n");
Execute(
instructions[index[0]],
1, score[index[0]]
);
if (score[index[0]]==0) break;
//cross & mutate population
puts("Breeding...");
for(g=0;g<PSIZE/2;g++){
if (score[index[g]]==WORST)
Randomize(
instructions[index[g]]
);
CrossMutate(
instructions[index[g]],
instructions[index[random(g)]],
instructions[index[PSIZE/2+g]]
);
}
}while(1);
for(g=0;g<PSIZE;g++)
free(instructions[g]);
}
main()
{
int i;
for (i=0;i<NUMBERS;i++){
source[i]=gets(i);
}
target=gets("target");
GASearch();
}