CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Игра "Жизнь" на Arduino

Обычно, начиная изучать новый язык программирования – я пробовал написать математическую игру Конвея «Жизнь».

Игра «Жизнь» (англ. Conway's Game of Life) — клеточный автомат(cellular automaton), придуманный английским математиком Джоном Конвеем (англ.) в 1970 году.

И хотя для ардуино – это не так актуально – программирование ведь идёт на С++.
Но, всё же, это новая платформа и нужно реализовать эту замечательную игру и для неё :)
За основу я взял свой старый исходник на С++ и просто модифицировал его для Arduino :)

В скетче реализован случайный засев игрового поля.
Загрузка из массива данных не захотела работать (возможно не хватает памяти :( ) и я его закомментировал.
Замыкания границ не происходит.

Код скетча получился таким:

//////////////////////////////////////////////////////////////////////
//
//
// Arduino LIFE GAME
//
//
//
//   noonv                                                 RoboCraft.ru
//////////////////////////////////////////////////////////////////////
// d - will die in next step
// a - will born in next step

// size of life-massive
int L_SIZE = 15;
int L_SIZEY = 25;

// variables
char l_mas[15+2][25+2]; // life-massive//char l_mas[L_SIZE+2][L_SIZEY+2]; // life-massive
int l_i,l_j; // counter's
int l_age=0; // age of population
int l_coef=0; // coefficient for check cell

void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(0));
  random_mas();
  //load_mas(); // not working :(
}

void loop()
{
	// print Hello :)
	Serial.print("Life  ");

        //	
	// 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]='+';	
	
		Serial.print("Age: ");
		Serial.println(l_age++);
                //
		// 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')
					Serial.print(" ");
				else
					Serial.print(l_mas[l_i][l_j]);
			}
			Serial.println();
		}
                //
		// 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);
		}
	
	delay(500);
	////////////
}

void calculate(int x,int 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;
	}

}

//
// set elements of l_mas zero
//
void null_mas()
{
	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';
	}
}

//
// set elements of l_mas via random 
//
void random_mas()
{

  for(l_i=1;l_i<L_SIZE+1;l_i++)
  {
  for(l_j=1;l_j<L_SIZEY+1;l_j++)
  {
      if(random(10)>5)
      {
        l_mas[l_i][l_j]='*';
        //Serial.print(l_mas[l_i][l_j]);
      }
      else
      {
        l_mas[l_i][l_j]='0';
      }
    }
    //Serial.println("");
  }
}

Загружаем в МК и смотрим, что нам выдаёт монитор COM-порта :)

Живём :)

Разумеется код можно (и нужно) оптимизировать – например, не тратить на клетку целый байт, а использовать один бит ;)


В дальнейшем – можно попробовать подключить к ардуине светодиодную матрицу и выводить информацию туда ;)

Ссылки:
http://ru.wikipedia.org/wiki/Игра_жизнь

По теме:
Одноклеточные самособирающиеся роботы
Светодиодная матрица для ардуино
  • +2
  • 8 октября 2009, 14:57
  • noonv

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.