啊,QT
简介
因为在QT上遇到了很谜的BUG,数据死活push进不了vector里,只能先在VS上写个没有界面的版本然后用很肮脏的代码来输出世界的信息。
稍微介绍一下项目的组成吧,God类保存世界的必要信息,比如地图信息,世界的能量流转的比例,基础数值等,并提供一些修改地图信息的函数。Creature类管理生物体的必要信息和基本行动。
God类
class God
{
public:
creature c_map[MAP_X][MAP_Y];
bool lockForRun;//haven`t use
int life_num; //count how many creature have burn,which use for id
int alive; //count how many alive creature now
int year;
std::vector<pointForPaint> log; //for GUI output,
std::vector<int>map[MAP_X]; //a map for free position
int cntlv[6];
God();
void initWorld();
void createLv1(int num);
void capture_f_t(int x1, int y1, int x2, int y2); //capture a position ,from (x1,y1) to(x2,y2)
int getNewId();
bool isFull(); //judge if the world is full of creatures
void saveLog(int x, int y,int lv /*QColor color*/);
//tools for access data in vector
int getIndex(int x,int val);
void erasexy(int x, int y);
};
Creature 类
class creature
{
public:
creature();
~creature();
some get and set methors.....
int Getmax_cnt()
void Addcnt(int activity_id)
void Setcnt(int activity_id, int cnt)
/* Base activities*/
void activity_mov();
void activity_eat();
void activity_sleep();
void activity_burn();
void kill();
/*sudden change the creature`s status,which may lead to be better or worse*/
void sudden_change(int type);
void sudden_change();
void schdule();
/*some tools for other methors*/
void setCreature(int x, int y, God* hiro);
void setLife(int level);
int findEmpty(int x, int y, int range);
int findEatable(int x, int y, int level, int vision);
private:
int lifelevel; //for 0-5,0 mean die
int id; //unique
int energy; //something just like HP
int max_energy;
int age;
int move; //creature can go to each place in Rect[x-move,y-move,x+move,y+move]
int step; //times that creature can act in an year
int death; //in every year,energy-=death;
int vision; //vision that effect eat() and burn()
int x; //position
int y;
double mutation; //sudden change rate
int m_size; //memory size ,but haven`t use yet
double m_logic; // a 0-1 rate to judge whether this year`s action will be effect by the memory or not
int m_activities_cnt[NUM_ACTIVITIES]; //count the activities times ,which means memory;
God *hiro; //for a creature to access the world`s status like the map,id,etc..
};
上面是大致的类定义,具体代码还是丢github吧。
调节世界运转的主要参数是在tools.h里:
Tools.h参数
/*map message ,will be input by file in the future version*/
#define MAP_X 100
#define MAP_Y 100
#define MAP_SIZE 10000
/*base rate and constant for the world to run*/
#define LEVEL_UP_K 2
#define CHANGE_RATE 0.05
/*base num for a creature to reduce energy every step*/
#define DIE_K 5
/*energy cost rate ,eat a creature can only get COST_RATE*be_eated.energy*/
#define COST_RATE 0.5
/*base energy for the LV1*/
#define BASE_ENERGY 20
/*used as the energy input for this world,*/
#define SUN 200
/*creture must have CAN_BURN*max_energy so that both mother and baby can alive */
#define CAN_BURN 1.8 after burn
#define AGE_K 2
有注释了我就不再一一展开了吧,,,,,
下面我再把一些运算规则写一下:
属性的演算规则:
对于每一回合:
energy-=death
age--;
if(!energy||!age ) kill this creature;
繁殖:
if(father.energy>=CAN_BURN*father.max_energy)
father.burn();
father-=father.max_energy
∴繁衍需要父亲有CAN_BURN*father.max_energy以上的能力值,来保证繁衍以后父亲不会因为缺少能量而太快死亡;
child复制父亲的所有属性值(包括记忆)并以更大的几率发生一次突变;
睡眠:
energy+=this->death>>1;
可以通过睡眠减缓能量消耗,但是不会超过每回合消耗值;
捕食:
随机选择地图上自身视野范围内,等级<=自身等级的对象进行捕食,被捕食对象死亡,捕食者.energy+=被捕食者.energy*COST_RATE,(这里是模仿能量在不同等级之间传递的消耗比)
移动:
随机选择地图上自身移动范围内的空位置并移动;
突变:
if(刚出生):突变率*2,上限0.8
else:
随机选择一项属性进行突变,对于大部分属性,随机±rand_from_to(-范围上限,范围上限),例如:
this->move += ran_f_t(-1, 1);
this->death += ran_f_t(-(DIE_K / 2), DIE_K / 2);
当突变的对象是等级的时候,发生单向进化,所有基础值增加默认量,
唯独energy*=LEVEL_UP_K,能量指数增长
其实完全可以把世界的参数做成文本输入,在没有界面的情况下也可以做个更优雅的log输出,但是时间有限,而且不知道里面还有没有什么奇奇怪怪的数据BUG,现在我的世界参数都还没有调好,很容易就走极端【啊,当个神真不容易】
日后有时间再继续修改吧,hiro_lifegame ver 0.1先到此为止吧orz。
后记
其实我知道代码写得比较脏,尤其是在不同 的IDE切换下,很多自动生成的代码格式揉杂在一起,命名规则也不统一,代码到了后期越来越乱,耦合也越来越高,这些我都是知道的QAQ,但是不能再继续玩lifegame下去了,这个学期还有操作系统,计算机组成原理的大实验,计算机网络,编译原理,数据库,并行编程,数据挖掘,一个一年前留下的项目坑要完结,,,还要准备下学期找实习,好幸福啊(>﹏<)
其实开始写这个lifegame是因为偶然点了百度推荐的细胞自动机,然后发现了一些博主写的lifegame,加上我一直对人工生命很感兴趣,很希望能用自己的code进化,繁衍出一定程度的“智能”【区别于行为树】,整个lifegame编写的时候,我仿照高中生物学到的能量守恒的相关流动信息,然而这个系统目前在没有外来能量输入的时候,明显能量不守恒的【假设能量消耗已经在-=death里计算】,怎么把这个世界的参数修改得更合理,可以让这个世界繁衍下去,并且最终得出高等级的,能力优秀,地理位置合理,记忆和逻辑能力都合理的个体,这是我的一个小愿望。
SAO的UW篇描述了一个繁衍出来的AI世界,虽然我对UW篇不算特别喜欢,但是我真的对人工智能很感兴趣的,希望有一天,我可以什么都不做,静静地看着“我的世界”居民日出而作,日落而息,看着这个世界的变化。
写这个玩具还是挺多收获的,我才发现我其实编码能力已经很弱,很多具体的语法细节其实已经完全不会了,项目的框架设计上还有很多的不足,一直懒搞自动化测试,QT谜之BUG,,,,各种各样的问题,都在这一周的空余时间里体现出来了,要补回去还有很长的路要走orz
于是lifegame暂时告一段落,我还会回来的【五星红旗高高挂】