Автор работы: Пользователь скрыл имя, 06 Октября 2013 в 12:41, лабораторная работа
Искусственная жизнь (Artifical life) - это понятие, введенное Крисом Лангтоном
(Chris Langton) для обозначения множества компьютерных механизмов, которые
используются для моделирования естественных систем. Искусственная жизнь применяется для моделирования процессов в экономике, поведения животных и насекомых, а также взаимодействия различных объектов.
Искусственная жизнь представляет собой целую науку с множеством
аспектов. Мы рассматривали одно из ее направлений - синтетическая наука о по-
ведении (Synthetic ethology). Ее очень четко описывает
Если есть хотя бы одно травоядное, то сравниваются координаты создаваемого травоядного с координатами уже существующих. Если находится такое травоядное, что координаты совпадают, то создаваемое травоядное помещается на одну клетку влево, если там свободно, иначе случайным образом помещается на поле. При этом если оно оказывается за краем поля, то помещается с противоположного края поля (принцип тороида). Если в клетке свободно, то вызываются функции добавления в структуру (AddHerbs) и рисования (RectDC).
Функция AddHerbs
void H::AddHerbs(herbs *her, int x, int y, int cnd)
{
her[hercnt].cc.x=x;
her[hercnt].cc.y=y;
her[hercnt].cond=cnd;
her[hercnt].id=hercnt;
her[hercnt].energy=100;
hercnt++;
}
Подаваемые в функцию
Функция (RectDC)
void H::RectDC(CDC *DC, int xx, int yy, int rr, int mod)
{
CPen pen;
int x1=0,x2=0,y1=0,y2=0;
if (mod == 2)
pen.CreatePen(0xff, 5, RGB(redher,greenher,blueher));
else if (mod == 3)
pen.CreatePen(0xff, 5, RGB(redcar,greencar,bluecar));
DC->SelectObject(&pen);
DC->Rectangle((xx*20)-20,(yy*
if (rr==1) y1=15;
if (rr==2) x1=15;
if (rr==3) y2=15;
if (rr==4) x2=15;
DC->Rectangle((xx*20)-20+x1,(
}
Эта функция рисования либо травоядных, либо хищников в зависимости от переменной mod, которая подается в функцию и задается при нажатии на кнопки создания объектов. Цвет объектов определяется переменными:
Цвет травоядных
Цвет хищников
Эти переменные изменяются в функциях ChangeColorHerbs, ChangeColorCarns в зависимости от уровня энергии объекта.
void H::ChangeColorHerbs(herbs *her, int id)
{
double rr=0;
double gg=0;
double bl=0;
for (int ih=100; ih>=0; ih--)
{
rr=rr+2.55;
gg=gg+2.55;
bl=255;
if (her[id].energy==ih)
{
redher=rr;
greenher=gg;
blueher=bl;
break;
}
}
}
При нажатии на кнопку Move запускается таймер, в котором выполняются функции взаимодействия объектов:
if (b == 10)
{
b=0; a=0;
}
if (a==b)
{
hh.Turn(GetDC(), hh.her, hh.car, hh.pl, 1);
hh.Redraw(GetDC(), hh.her, hh.car, hh.pl);
b++; a=0;
}
else if (a<b)
{
hh.Moving(GetDC(), hh.her, hh.car, hh.pl);
hh.Redraw(GetDC(), hh.her, hh.car, hh.pl);
a++;
}
CString hr;
CString cr;
CString plt;
list.AddString("plants");
for (int ip=0; ip<hh.plcnt; ip++)
{
if (hh.pl[ip].energy<100) hh.pl[ip].energy++;
else if (hh.pl[ip].energy>=100)
{
hh.pl[ip].energy=hh.pl[ip].
hh.multipl(GetDC(), hh.pl, ip);
}
plt.Format("%d: %d", hh.pl[ip].id, hh.pl[ip].energy);
list.AddString(plt);
if (hh.pl[ip].energy<=0)
{
hh.DelPlants(hh.pl, ip);
}
}
list.AddString("Herbivore");
for (int ih=0; ih<hh.hercnt; ih++)
{
hh.FindPl(hh.pl, hh.her, hh.her[ih].cc.x, hh.her[ih].cc.y, ih);
if (hh.her[ih].energy<101) hh.her[ih].energy = hh.her[ih].energy-2;
else if (hh.her[ih].energy>=101)
{
hh.her[ih].energy=hh.her[ih].
hh.multiher(GetDC(), hh.her, ih, 2);
}
hr.Format("%d: %d", hh.her[ih].id, hh.her[ih].energy);
list.AddString(hr);
if (hh.her[ih].energy<=0)
{
hh.DelHerbs(hh.her, ih);
}
}
list.AddString("Carnivore");
for (int ic=0; ic<hh.carcnt; ic++)
{
hh.FindHer(hh.her, hh.car, hh.car[ic].cc.x, hh.car[ic].cc.y, ic);
if (hh.car[ic].energy<101) hh.car[ic].energy = hh.car[ic].energy-1;
else if (hh.car[ic].energy>=101)
{
hh.car[ic].energy=hh.car[ic].
hh.multicar(GetDC(), hh.car, ic, 3);
}
cr.Format("%d: %d", hh.car[ic].id, hh.car[ic].energy);
list.AddString(cr);
if (hh.car[ic].energy<=0)
{
hh.DelCarns(hh.car, ic);
}
}
CString iter;
iter.Format("%d", hh.iterations);
SetDlgItemText(IDC_iterat,
hh.iterations++;
Каждый шаг вызывается функция FindPl:
void H::FindPl(plant *pl, herbs *her, int x, int y, int id)
{
for (int ip=0; ip<plcnt; ip++)
{
if (pl[ip].cc.x == x && pl[ip].cc.y == y)
{
her[id].energy=her[id].energy+
DelPlants(pl, ip);
}
}
}
В данной функции происходит проверка, если травоядное входит в клетку, где находится растение, то травоядное съедает это растение. Энергия растения прибавляется к энергии травоядного. Само растение удаляется функцией DelPlants:
void H::DelPlants(plant *pl, int id)
{
for (int ip=0; ip<plcnt; ip++)
{
pl[ip].cc.x=pl[ip+1].cc.x;
pl[ip].cc.y=pl[ip+1].cc.y;
pl[ip].cond=pl[ip+1].cond;
pl[ip].id=pl[ip+1].id;
pl[ip].energy=pl[ip+1].energy;
}
plcnt--;
}
Далее каждый шаг энергия травоядного уменьшается на две единицы. Если объект «поедает» другой объект, и уровень его энергии становится больше 100, то объект размножается. Уровень энергии этого объекта уменьшается в два раза. Когда уровень энергии объекта доходит до нуля, этот объект «умирает» – удаляется из структуры.
Поле, на котором происходит взаимодействие объектов, имеет размер 21х21 – 441. Количество растений, травоядных и хищников в сумме не должно превышать 441.
Рис. 10. Пример работы программы
На этом рисунке видно отображение уровня энергии и зависимость цвета объектов от уровня энергии.
На следующих рисунках покажем процесс «съедания» растения травоядным.
Рис. 11. Пример работы программы
Травоядное движется в направлении к растению. Его уровень энергии равен 96, а уровень энергии растения равен 22. Когда травоядное «съест» растение, уровень энергии превысит 100. И поэтому травоядное размножится.
Рис. 12. Пример работы программы
Взаимодействие хищников с травоядными происходит аналогичным образом.