📄 gene.cpp
字号:
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<math.h>
#include<time.h>
#include<string.h>
#include "paint.h"
#define TL1 20
#define TL2 5
#define NEWFOODS 3
#define MUTATION 0.05
#define G_LENGTH 32
#define MAX_POP 100
#define MAX_FOOD 100
#define MAX_WX 60
#define MAX_WY 32
#define SX1 330
#define SY1 40
#define GX 360
#define GY 257
#define GXR 250
#define GYR 100
#define GSTEP 2
#define R_LIFE 0.05
#define R_FOOD 0.02
#define SL_MIN 10
unsigned char gene[MAX_POP][G_LENGTH];
unsigned char iflg[MAX_POP];
unsigned char fflg[MAX_FOOD];
unsigned char world[MAX_WX][MAX_WY];
unsigned char life1[5][5]={{0,0,1,0,0},{0,1,0,1,0},{1,0,0,0,1},{0,1,0,1,0},{0,0,1,0,0}};
unsigned char life2[5][5]={{1,1,1,1,1},{1,0,0,0,1},{1,0,0,0,1},{1,0,0,0,1},{1,1,1,1,1}};
unsigned char food1[5][5]={{0,0,0,1,0},{0,0,1,1,0},{0,1,0,1,0},{0,0,1,1,0},{0,0,0,1,0}};
unsigned char food2[5][5]={{0,0,0,1,0},{0,0,1,1,0},{0,1,1,1,0},{0,0,1,1,0},{0,0,0,1,0}};
int pop_size;
int iatr[MAX_POP][4];
int food_size;
int fatr[MAX_FOOD][4];
int wx,wy;
void uni_crossover(unsigned char *gene,int g1,int g2,int g3,double ratio1,int g_length)
{
unsigned char *gene1;
unsigned char *gene2;
unsigned char *gene3;
double rnd,r1;
int i;
gene1=gene+g_length*g1;
gene2=gene+g_length*g2;
gene3=gene+g_length*g3;
r1=(int)(10000.0*ratio1);
for(i=0;i<g_length;i++)
{
rnd=random(10000);
if(rnd<=r1)
*(gene3+i)=*(gene1+i);
else
*(gene3+i)=*(gene2+i);
}
}
void g_disp_unit(int x,int y,int n)
{
int gx,gy,i,j;
unsigned char col;
gx=SX1+5*x;gy=SY1+5*y;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
switch(n)
{
case 0: col=0; break;
case 1: col=life1[j][i]*2; break;
case 2: col=life2[j][i]*4; break;
case 3: col=food1[j][i]*6; break;
case 4: col=7; break;
case 5: col=food2[j][i]*11;
}
g_pset(gx+j,gy+i,col);
}
}
void g_draw_world()
{
int i,j;
for(i=0;i<wy;i++)
for(j=0;j<wx;j++)
g_disp_unit(j,i,world[j][i]);
}
void g_draw_frame(int x1,int y1,int x2,int y2,int c1,int c2,int c3,int c4,char *text)
{
int n,x3;
g_rectangle(x1,y1,x2,y2,c1,1);
g_rectangle(x1,y1,x2,y2,c2,0);
g_rectangle(x1,y1,x2,y1+16,c3,1);
g_rectangle(x1,y1,x2,y1+16,c2,0);
n=strlen(text);
x3=x1+((x2-x1-n*8)/2);
disp_hz16(text,x3,y1,c4);
}
void g_init_frames()
{
int i,j,cx,cy,x,y;
char text[17];
g_draw_frame(0,0,639,399,15,0,4,15,
"基于遗传算法的人工生命模拟");
g_draw_frame(0,16,320,170,7,0,8,15,"设定参数");
y=48;
setcolor(9);
disp_hz16("植物食物限制时间",16,y,15);
sprintf(text,"%d",TL1);
g_text(200,y+8,4,text);
y=y+24;
setcolor(9);
disp_hz16("动物食物限制时间",16,y,15);
sprintf(text,"%d",TL2);
g_text(200,y+8,4,text);
y=y+24;
setcolor(9);
disp_hz16("植物食物每代生成个数",16,y,15);
sprintf(text,"%d",NEWFOODS);
g_text(200,y+8,4,text);
y=y+24;
setcolor(9);
disp_hz16("变异概率",16,y,15);
i=(int)(MUTATION*100.0);
sprintf(text,"%d",i);
g_text(152,y+8,4,text);
g_draw_frame(0,170,320,399,7,0,8,15,"最佳基因型");
x=16;y=194;
setcolor(6);
disp_hz16("SP:物种号........",x,y,15);y=y+16;
disp_hz16("SL:寿命..........",x,y,15);y=y+16;
disp_hz16("VF:视野..........",x,y,15);y=y+16;
disp_hz16("TM:基本移动模式..",x,y,15);y=y+16;
disp_hz16("CM:移动特点......",x,y,15);y=y+16;
disp_hz16("LM:移动能耗......",x,y,15);y=y+16;
disp_hz16("CA:行动特点......",x,y,15);y=y+16;
disp_hz16("CR:善变性........",x,y,15);y=y+16;
disp_hz16("SA:攻击速度......",x,y,15);y=y+16;
disp_hz16("DA:防御能力......",x,y,15);y=y+16;
disp_hz16("LA:攻击能耗......",x,y,15);y=y+16;
disp_hz16("EF:食物吸取效率..",x,y,15);y=y+16;
g_draw_frame(320,16,639,207,7,0,8,15,"虚拟世界");
g_draw_frame(320,207,639,399,7,0,8,15,"世代个体数目变化");
}
void g_init_graph()
{
g_rectangle(GX,GY,GX+GXR,GY+GYR,0,1);
g_rectangle(GX,GY,GX+GXR,GY+GYR,6,0);
setcolor(1);
disp_hz16( "生物 1",GX+5,GY-18,15);
g_line(GX+90,GY-10,GX+110,GY-10,1);
setcolor(4);
disp_hz16( "生物 2",GX+120,GY-18,15);
g_line(GX+205,GY-10,GX+225,GY-10,4);
setcolor(0);
disp_hz16("世代数",GX+168,GY+GYR+10,15);
g_text(GX-25,GY,0,"100");
g_text(GX-14,GY+GYR,0,"0");
}
void g_plot_population(int gen_num,int n1,int n2,int n1old,int n2old)
{
int x,y,gx,gy,x_old,y_old;
char text[8];
if(gen_num%10==0)
{
x=GX+(gen_num-1)*GSTEP;
g_line(x,GY+1,x,GY+GYR-1,1);
sprintf(text,"%d",gen_num);
if(gen_num<100||gen_num%20==0)
g_text(x-8,GY+GYR+5,15,text);
}
x_old=GX+(gen_num-1)*GSTEP;
x=x_old+GSTEP;
y_old=GY+GYR-n1old;
y=GY+GYR-n1;
g_line(x_old,y_old,x,y,1);
y_old=GY+GYR-n2old;
y=GY+GYR-n2;
g_line(x_old,y_old,x,y,4);
}
void g_disp_genotype()
{
int i,j,n0,n1,x,y;
unsigned char g[G_LENGTH];
unsigned char bits[12][2]=
{{0,0},{1,4},{5,6},{7,8},{9,11},{12,12},{13,15},
{16,18},{19,21},{22,24},{25,27},{28,31}};
g_rectangle(200,187,319,398,7,1);
if(pop_size!=0)
{
for(i=0;i<G_LENGTH;i++)
{
n0=0;
n1=0;
for(j=0;j<pop_size;j++)
if(gene[j][i]==0)
n0++;
else
n1++;
if(n0>=n1)
g[i]=0;
else
g[i]=1;
}
x=220;
for(i=0;i<12;i++)
{
y=202+i*16;
for(j=bits [ i][0];j<=bits [ i][1];j++)
if(g[j]==0)
g_text(x+(j-bits[i][0])*16,y,4,"0");
else
g_text(x+(j-bits[i][0])*16,y,4,"1");
}
}
}
void g_disp_char(int x,int y,int x1,int y1,int x2,int y2,unsigned char v)
{
char c[10];
if(x>=x1&& x<=x2-8 && y>=y1 && y<=y2-10)
{
switch(v)
{
case 0: strcpy(c,"0\0");break;
case 1: strcpy(c,"+\0");break;
case 2: strcpy(c,"-\0");break;
case 3: strcpy(c,"x\0");
}
g_text(x,y,15,c);
}
}
void remove_life(int n)
{
iflg[n]=0;
world[iatr[n][0]][iatr[n][1]]=0;
g_disp_unit(iatr[n][0],iatr[n][1],0);
if(food_size+1<=MAX_FOOD)
{
food_size++;
fatr[food_size-1][0]=iatr[n][0];
fatr[food_size-1][1]=iatr[n][1];
fatr[food_size-1][2]=1;
fatr[food_size-1][3]=0;
fflg[food_size-1]=1;
world[iatr[n][0]][iatr[n][1]]=5;
g_disp_unit(iatr[n][0],iatr[n][1],5);
}
}
int get_world(int,int);
void remove_food(int n)
{
fflg[n]=0;
world[fatr[n][0]][fatr[n][1]]=0;
g_disp_unit(fatr[n][0],fatr[n][1],0);
}
void make_lives_and_foods()
{
int x,y,i,j;
pop_size=0;
food_size=0;
for(y=0;y<wy;y++)
for(x=0;x<wx;x++)
{
if(world[x][y]==1||world[x][y]==2)
{
if(pop_size+1<=MAX_POP)
{
pop_size++;
gene[pop_size-1][0]=world[x][y]-1;
for(i=1;i<G_LENGTH;i++)
gene[pop_size-1][i]=random(2);
iatr[pop_size-1][0]=x;
iatr[pop_size-1][1]=y;
iatr[pop_size-1][2]=70+random(30);
iatr[pop_size-1][3]=random(SL_MIN);
}
}
if(world[x][y]==3||world[x][y]==5)
{
if(food_size+1<=MAX_FOOD)
{
food_size++;
fatr[food_size-1][0]=x;
fatr[food_size-1][1]=y;
if(world[x][y]==3)
fatr[food_size-1][2]=0;
else
fatr[food_size-1][2]=1;
fatr[food_size-1][3]=random(TL1-1)+1;
}
}
}
}
void find_empty(int *x,int *y)
{
int ok;
ok=0;
while(ok==0)
{
*x=random(wx);
*y=random(wy);
if(world[*x][*y]==0)
ok=1;
}
}
void make_world()
{
int i,j,k,num,x,y;
int ok,overlap;
char choice[3];
double size;
wx=0;
while(wx<10||wx>MAX_WX)
{
setcolor(15);
disp_hz16("虚拟环境长度(10-60)",10,210,20);
gscanf(300,210,4,0,3,"%s",choice);
wx=atoi(choice);
}
wy=0;
while(wy<10||wy>MAX_WY)
{
setcolor(15);
disp_hz16("虚拟环境宽度(10-32)",10,240,20);
gscanf(300,240,4,0,3,"%s",choice);
wy=atoi(choice);
}
for(i=0;i<wy;i++)
for(j=0;j<wx;j++)
if(i==0||i==wy-1||j==0||j==wx-1)
world[j][i]=4;
else
world[j][i]=0;
size=(double)(wx*wy);
num=(int)(size/40.0);
if(num>MAX_POP)
num=MAX_POP;
for(i=0;i<num;i++)
{
find_empty(&x,&y);
world[x][y]=4;
}
num=(int)(size/5.0);
if(num>MAX_FOOD)
num=MAX_FOOD;
for(i=0;i<num;i++)
{
ok=0;
while(ok==0)
{
x=random(wx);
y=random(wy);
if((world[x][y]!=4)&&(world[x][y-1]==4 || world[x][y+1]==4 || world[x-1][y]==4 || world[x+1][y]==4))
{
world[x][y]=4;
ok=1;
}
}
}
for(y=0;y<wy;y++)
for(x=0;x<wx;x++)
if(world[x][y]==0)
{
num=0;
for(i=-1;i<=1;i++)
for(j=-1;j<=1;j++)
if(get_world(x+j,y+i)==4)
num++;
if(num>=6)
world[x][y]=4;
}
num=(int)(size*R_LIFE);
for(i=0;i<num;i++)
{
find_empty(&x,&y);
world[x][y]=random(2)+1;
}
num=(int)(size*R_FOOD);
for(i=0;i<num;i++)
{
find_empty(&x,&y);
world[x][y]=3;
}
}
void load_world_file()
{
FILE *fpt;
char st[100],c;
int i,j;
if((fpt=fopen("\\ga\\world","r"))==NULL)
exit(-1);
else
{
fscanf(fpt,"%d",&wx);
fscanf(fpt,"%d",&wy);
for(i=0;i<wy;i++)
for(j=0;j<wx;j++)
fscanf(fpt,"%d",&world[j][i]);
fclose(fpt);
}
}
int get_world(int x,int y)
{
if(x>=0 && x<wx && y>=0 && y<wy)
return(world[x][y]);
else
return(-1);
}
int decode_gene(int n,int sb,int bw)
{
int i,sum;
sum=0;
for(i=sb;i<sb+bw;i++)
sum=sum*2+gene[n][i];
return(sum);
}
void move_pos(int n,int x1,int y1,int x2,int y2)
{
int sp,loss;
loss=decode_gene(n,12,1)+1;
iatr[n][2]=iatr[n][2]-loss;
if(iatr[n][2]<=0)
remove_life(n);
else
{
iatr[n][0]=x2;
iatr[n][1]=y2;
sp=gene[n][0]+1;
g_disp_unit(x1,y1,0);
world[x1][y1]=0;
g_disp_unit(x2,y2,sp);
world[x2][y2]=sp;
}
}
void move_randomly(int n)
{
int pat1[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int pat2_3[2][4][2]={{{1,0},{0,1},{-1,0},{0,-1}},{{1,1},{-1,1},{-1,-1},{1,-1}}};
int pat,x1,y1,x2,y2,rndnum;
pat=decode_gene(n,7,2);
x1=iatr[n][0];
y1=iatr[n][1];
if(pat<=1)
{
rndnum=random(8);
x2=x1+pat1[rndnum][0];
y2=y1+pat1[rndnum][1];
}
else
{
rndnum=random(4);
x2=x1+pat2_3[pat-2][rndnum][0];
y2=y1+pat2_3[pat-2][rndnum][1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -