"Суха, мой друг,теория везде,
А древо жизни пышно зеленеет!"
Гёте. Фауст
Доброго времени суток, уважаемые читатели!
И опять мы продолжаем разговор об этих увлекательных клеточных автоматах!
Исходник игры на C++, как вы наверное заметили, использует только
квадратное поле, размер стороны квадрата задаётся через дерективу препроцессора
#define L_SIZE 20
Впрочем легко переделать исходник на случай прямоугольного поля. Он приведён ниже.
//////////////////////////////////////////////////////////////////////
//
// 7.cpp
// for LIFE GAME
// issue N7
// Started: 03.07.03 12:32:26
//
// XIII
//////////////////////////////////////////////////////////////////////
// d - will die in next step
// a - will born in next step
#ifndef _7_CPP_
#define _7_CPP_ 1
#include<fstream.h>
#include<conio.h>
char *prog_name="life v0.71";
// size of life-massive
#define L_SIZE 20
#define L_SIZEY 60
typedef unsigned int uint;
// variables
char *file_name="life.txt";
fstream fs; // for manipulations with file
char l_mas[L_SIZE+2][L_SIZEY+2]; // life-massive
int l_i,l_j; // counter's
uint l_age=0; // age of population
uint l_coef=0; // coefficient for check cell
// functions
int in_file(char*); // get data from file and set life-massive
void calculate(uint,uint); // calculate one cell
int main()
{
// print Hello :)
cout<<"+---------------+\n";
cout<<"| Life |\n";
cout<<"| |\n";
cout<<"| XIII |\n";
cout<<"+---------------+"<<endl;
cout<<"press eny key to play; for Exit press q"<<endl;
// set border
for(l_i=0;l_i<L_SIZEY+2;l_i++)
l_mas[0][l_i]=l_mas[L_SIZE+1][l_i]='-';
for(l_j=0;l_j<L_SIZE+2;l_j++)
l_mas[l_j][0]=l_mas[l_j][L_SIZEY+1]='|';
l_mas[L_SIZE+1][0]=l_mas[0][L_SIZEY+1]='+';
l_mas[0][0]=l_mas[L_SIZE+1][L_SIZEY+1]='+';
// set elements of l_mas zero
for(l_i=1;l_i<L_SIZE+1;l_i++)
{
for(l_j=1;l_j<L_SIZEY+1;l_j++)
l_mas[l_i][l_j]='0';
}
// get data
if(in_file(file_name))
return 1; // error open file
while(getch()!='q')
{
cout<<"Age: "<<l_age++<<endl;
// print life-massive
for(l_i=0;l_i<L_SIZE+2;l_i++)
{
for(l_j=0;l_j<L_SIZEY+2;l_j++)
{
if(l_mas[l_i][l_j]=='d')
l_mas[l_i][l_j]='0'; // amen 8-)
if(l_mas[l_i][l_j]=='a')
l_mas[l_i][l_j]='*'; // new cell
if(l_mas[l_i][l_j]=='0')
cout<<" ";
else
cout<<l_mas[l_i][l_j];
}
cout<<endl;
}
// calculate next configuration
for(l_i=1;l_i<L_SIZE+1;l_i++)
{
for(l_j=1;l_j<L_SIZEY+1;l_j++)
calculate(l_i,l_j);
}
}
////////////
return 0;
}
int in_file(char*file)
{// get data from file and set life-massive
fs.open(file,ios::in);
if(!fs)
{// can't open file
cout<<"Error open file!\t"<<file_name<<endl;
return 1;
}
// get data
for(l_i=1;l_i<L_SIZE+1;l_i++)
{
for(l_j=1;l_j<L_SIZEY+1;l_j++)
fs>>l_mas[l_i][l_j];
}
fs.close();
return 0;
}
void calculate(uint x,uint y)
{// calculate one cell with x,y
switch(l_mas[x][y])
{
case 'a':
case 'd':
case '+':
case '|':
case '-':
break;
case '0':
case '*':
//-------------------------------------//
l_coef=0;
if(l_mas[x][y-1]=='*'|| l_mas[x][y-1]=='d') // west
l_coef++;
if(l_mas[x-1][y-1]=='*'|| l_mas[x-1][y-1]=='d')// north-west
l_coef++;
if(l_mas[x-1][y]=='*'||l_mas[x-1][y]=='d')// north
l_coef++;
if(l_mas[x-1][y+1]=='*'||l_mas[x-1][y+1]=='d')// north-east
l_coef++;
if(l_mas[x][y+1]=='*'||l_mas[x][y+1]=='d')// east
l_coef++;
if(l_mas[x+1][y+1]=='*'||l_mas[x+1][y+1]=='d')// south-east
l_coef++;
if(l_mas[x+1][y]=='*'||l_mas[x+1][y]=='d')// south
l_coef++;
if(l_mas[x+1][y-1]=='*'||l_mas[x+1][y-1]=='d')// south-west
l_coef++;
switch(l_coef)
{
case 0:
case 1: // will die
if(l_mas[x][y]=='*')
l_mas[x][y]='d';
break;
// case 2:// stable =)
// if(l_mas[x][y]=='*')
// l_mas[x][y]='*';
// break;
case 3: // will born
if(l_mas[x][y]=='0')
l_mas[x][y]='a';
break;
case 4: // will die
case 5:
case 6:
case 7:
case 8:
if(l_mas[x][y]=='*')
l_mas[x][y]='d';
break;
default:
break;
}
//-------------------------------------//
break;
default:
break;
}
}
#endif
|
Теперь в такой более просторной вселенной можно понаблюдать движение паровоза,
пример файла life.txt для данной конфигурации приведён ниже.
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
0000000****0000000000000000000000000000000000000000000000000
000000*000*0000000000000000000000000000000000000000000000000
0000000000*0000000000000000000000000000000000000000000000000
00**00*00*00000000000000000000000000000000000000000000000000
00***0000000000000000000000000000000000000000000000000000000
00**00*00*00000000000000000000000000000000000000000000000000
0000000000*0000000000000000000000000000000000000000000000000
000000*000*0000000000000000000000000000000000000000000000000
0000000****0000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
он будет двигаться с запада на восток. Здорово, правда? Согласитесь такие простые
правила, а уже возможно создание таких сложных фигур, способных перемещаться
в нашем пространстве.
Note:
Для Linux вызов функции getch() можно заменить
на getc(stdin) или getchar() ,
которые объявлены в файле stdio.h , но тогда для каждого следующего шага нужно будет нажимать
Enter.
Надеюсь никто не был против того, что в исходнике я ипользовал комментарии на
английском? На это существует несколько весьма веских причин.
Так же я думаю, что в дополнительных комментариях программа не нуждается, если вам
что-то не ясно, то пишите.
|
Надеюсь вы скачали программу с сайта
http://www.famlife.narod.ru. Потому как
наша программа конечно работает :), но согласитесь она весьма неуклюжа и приведена
для примера как собственно происходит обработка правил игры. Программа же FAM Life
под ОС Windows имеет более дружественный интерфейс=). Загляните в меню Игра->Стандартные фигуры...
там вы обнаружите очень интересные конфигурации, которые вам уже знакомы, если вы
прочитали статью, которую я рекомендовал в конце прошлого выпуска(она находится на том же сайте).
Наиболее интересные из них - глайдер(я приводил его в прошлом выпуске),
космические корабли(они движутся по прямой)
****
*****
*****
*****
глайдерное ружьё(на каждом 30-ом шаге порождает глайдер!)
************
*************
************************
*************************
**************************
************************************
***********************************
*************************
************************
как вам эта конфигурация? круто не правда ли?
Так же программа FAM Life позволяет изменять стандартные правила игры на другие. В нашей
программе это можно реализовать изменяя правила
switch - case для переменной l_coef.
Попробовали свои правила? как видите всё не так просто и правила Конвея взяты им не с потолка :)
Играйте и до встречи!
|