Моделирование Виртуальной Вычислительной Системы.
 
Выпуск №7
home URL
автор рассылки: noonv (noonv@narod.ru)

"Суха, мой друг,теория везде,
А древо жизни пышно зеленеет!"
Гёте. Фауст

Доброго времени суток, уважаемые читатели!

И опять мы продолжаем разговор об этих увлекательных клеточных автоматах!

Исходник игры на 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.
Попробовали свои правила? как видите всё не так просто и правила Конвея взяты им не с потолка :)

Играйте и до встречи!

[noonv@volodia noonv]$ logout

XIII

Рейтинг@Mail.ru
Хостинг от uCoz