Dar
const int GW = 10;
const int GL = 10;
const int GENES = 16;
const int GENELEN=5;
const int GN = 0;
const int GB = 9;
const int GDC = 5;
const int GWA = 1;
const int VC[4]={GN,GB,GWA,GDC};
const int NVC=4;
const int UP=1;
const int LEFT=2;
const int RIGHT=3;
const int DOWN=4;
const int RANDDIR=5;
const int NDC =5;
const int MOVECODES[5]={UP,LEFT,RIGHT,DOWN,RANDDIR};
const int NR=200;
const double PERCBAT = 0.4;
const int GENERATIONS = 6000;
const double MUTRATE=0.05;
const int INITEN=5;
#include <iostream>
class Grid {
int g[GW][GL];
void randbat(int k){
int x,y;
if (k==0) return;
do {
x=rand()%GW;
y=rand()%GL;
} while(g[x][y] != GN);
g[x][y]=GB;
randbat(k-1);
}
public:
Grid(double perc) {
for (int y=0; y<GL; y++)
for (int x=0; x<GW;x++)
g[x][y]=0;
int k=(GW*GL)*perc;
randbat(k);
}
int getcode(int x, int y) {
if ((x>=GW)||(x<0)||(y>=GL)||(y<0)) return GWA;
else return g[x][y];
}
void getnwes(int x, int y, int* into) {
into[0]=getcode(x,y-1);
into[1]=getcode(x-1,y);
into[2]=getcode(x+1,y);
into[3]=getcode(x,y+1);
}
void print() {
for (int y=0;y<GL;y++) {
for (int x=0;x<GW;x++) {
std::cout<<g[x][y];
}
std::cout<<std::endl;
}
}
int munch(int x, int y) {
if (g[x][y]==GB) {g[x][y]=GN; return 1;}
else return 0;
}
int cango(int x, int y) {
return (getcode(x,y)!=GWA);
}
void printcodes(int x, int y) {
int a[4];
getnwes(x,y,a);
for(int i=0;i<4;i++)
std::cout<<a[i];
}
};
class Rb {
int genes[GENES][GENELEN];
int energy;
int x,y;
int movesmade;
void randplace() {
x=rand()%GW;
y=rand()%GL;
}
void randgene(int* g) {
for (int i=0;i<4;i++) {
g[i]=VC[rand()%NVC];
}
g[4]=MOVECODES[rand()%NDC];
}
public:
Rb() {
for (int g=0;g<GENES;g++) {
randgene(genes[g]);
}
randplace();
movesmade=0;
energy=INITEN;
}
int activategene(int*view,int*gene){
for (int i=0;i<4;i++) {
if (view[i]!=gene[i]&&gene[i]!=GDC) return 0;
}
return gene[GENELEN-1];
}
int lookup(int* view) {
int move;
for (int i=0;i<GENELEN;i++) {
move=activategene(view, genes[i]);
if (move!=0) return move;
}
return genes[GENES-1][GENELEN-1];
}
void reset() {
randplace();
movesmade=0;
energy=INITEN;
}
void go(Grid*gr) {
for(;;) {
if (energy<0) return;
int view[4];
int move;
int x2, y2;
gr->getnwes(x,y,view);
move=lookup(view);
if (move==RANDDIR) {
int ds[4]={UP,LEFT,RIGHT,DOWN};
move=ds[rand()%4];
}
y2=y;x2=x;
switch(move) {
case(UP): y2--;break;
case(LEFT): x2--; break;
case(RIGHT): x2++; break;
case(DOWN): y2++; break;
}
if (gr->cango(x2,y2)) {x=x2;y=y2;}
movesmade++;
energy+=gr->munch(x,y);
energy--;
}
}
void mutate(int z) {
int code=rand()%GENELEN;
const int* source=VC;
int l=NVC;
if (code==GENELEN-1) {
source=MOVECODES;
l=NDC;
}
genes[z][code]=source[rand()%l];
}
void printgenes() {
for (int g=0; g<GENES;g++) {
for (int i=0; i<GENELEN; i++) {
std::cout<<genes[g][i]<<" ";
}
std::cout<<std::endl;
}
}
int harvest() {
return movesmade-INITEN;
}
Rb mate(Rb pa) {
Rb baby;
int i=0;
Rb *source=this;
for (i=0;i<GENES;i++) {
if(i>=GENES/2) source=&pa;
for(int i2=0;i2<GENELEN;i2++) {
baby.genes[i][i2]=source->genes[i][i2];
}
}
return baby;
}
};
class Breeder {
Rb rs[NR];
double avg[GENERATIONS];
Grid newgrid() {
Grid g(PERCBAT);
return g;
}
void runrs() {
for (int gennum=0; gennum<GENERATIONS; gennum++) {
double tot=0.0;
for (int i=0; i<NR; i++) {
Grid g=newgrid();
rs[i].reset();
rs[i].go(&g);
tot+=rs[i].harvest();
}
avg[gennum]=tot/(double)NR;
sort();
breed();
}
}
void sort() {
Rb temp;
for (int i=0;i<NR-1;i++) {
for (int i2=i+1;i2<NR;i2++) {
if (rs[i].harvest()<rs[i2].harvest()) {
temp=rs[i];
rs[i]=rs[i2];
rs[i2]=temp;
}
}
}
}
void breed() {
for(int i=0;i<NR/2;i=i+2) {
rs[i+NR/2]=rs[i].mate(rs[i+1]);
rs[i+NR/2+1]=rs[i+1].mate(rs[i]);
}
int m[(int)(NR*MUTRATE*GENES)];
for (int i=0; i<NR*MUTRATE*GENES;i++) {
int in;
do {
in=0;
m[i]=rand()%(NR*GENES);
for(int i2=0;i2<i;i2++) if (m[i2]==m[i]) in=1;
} while (in);
rs[i/GENES].mutate(i%GENES);
}
}
public:
Breeder() {
runrs();
sort();
}
void print() {
for (int i=0;i<GENERATIONS;i++) {
std::cout<<"Generation "<<1+i<<" average "<<avg[i]<<std::endl;
}
}
void printwinner() {
rs[0].printgenes();
std::cout<<rs[0].harvest()<<std::endl;
}
};
int main()
{
srand(time(NULL));
Breeder b;
b.print();
std::cout<<"Bonus feature - genes followed by harvest of top robot in the final generation"<<std::endl;
b.printwinner();
}
|
run
| edit
| history
| help
|
0
|
|
|