Egoblog.cz - Petr Kobelka

Game of life - celularni automat

V příspěvku Vám představuji velmi jednoduchý skript pro generování hry života. Vyzkoušejte.


PHP | Komentáře (0) | Shlédnuto 1103 × | Vloženo: 4. dubna 2013

V případě tohoto skript je implementována problematika celulárního automatu - hry života.

Hra na boha - hra života v PHP

V podstatě je o akademickou záležitost, máte k dispozici nějaké pole, nastavíte výchozí masku a pravidla pro generování kolonie. Pak už jen sledujete, jak se vaší kolonii daří. Jde o PHP skript, který jsem yvtvořilů někdy v roce 2009. Tehdy mě zajímala tato problematika a chtěl jsem si zkusit něco takového vytvořit. Skript je dost jednoduchý, napsaný rychle tak, aby fungoval.

set_time_limit(0);
define('N', "\n");

echo '<html>'.N.
     '<body>'.N.
     '<h1>GAME OF LIVE</h1>'.N.
     '<br />'.N.
     'GENERACE: <input type="text" value="" id="pocet_generace" />'.N.
     '<br /><br />'.N.
     '<div id="petriho_miska"></div>'.N.
     '</body>'.N.
     '</html>'.N;
     
flush();

define('POLE_X', 30);
define('POLE_Y', 40);
define('CELL_SIZE', 10);

//pole, ktere eviduje aktualni stav
$petriho_miska = array();

//inicializace pole - prazdne pole
function inicializuj(&$pole) {
 
  for ($x = 0; $x <  POLE_X; $x++)
  {
    for ($y = 0; $y <  POLE_Y; $y++)
    {
      $pole[$x][$y] = 0;
    }
  }
}

/*
    Y ->
    0 1 2 3 4 5 6 7 8 9
X 0 . . . . . . . . . .
  1 . . . . . . . . . .
  2 . . . . . . . . . .
  3 . . . . x . . . . .
  4 . . . . X . . . . .
  5 . . . X X . X . . .
  6 . . . X . X X . . .
  7 . . . . . . . . . .
  8 . . . . . . . . . .
  9 . . . . . . . . . .
*/
inicializuj($petriho_miska);
//nastavime nejaky pocatecni vzorec
$petriho_miska[3][4] = 1;
$petriho_miska[5][6] = 1;
$petriho_miska[4][4] = 1;
$petriho_miska[4][5] = 1;
$petriho_miska[3][5] = 1;
$petriho_miska[6][6] = 1;
$petriho_miska[5][6] = 1;
$petriho_miska[3][6] = 1;

/*
    Y ->
    0 1 2 3 4 5 6 7 8 9
X 0 . . . . . . . . . .
  1 . . . . . . . . . .
  2 . . . . . X . . . .
  3 . . . . x X . . . .
  4 . . . X . X . . . .
  5 . . . . . X . . . .
  6 . . . . . X . . . .
  7 . . . . . . . . . .
  8 . . . . . . . . . .
  9 . . . . . . . . . .
*/
inicializuj($petriho_miska);
$petriho_miska[2][5] = 1;
$petriho_miska[6][5] = 1;
$petriho_miska[5][5] = 1;
$petriho_miska[4][5] = 1;
$petriho_miska[3][5] = 1;
$petriho_miska[3][4] = 1;
$petriho_miska[4][3] = 1;

/*
    Y ->
    0 1 2 3 4 5 6 7 8 9
X 0 . . . . . . . . . .
  1 . . . . . . . . . .
  2 . . . X X . . . . .
  3 . . . X . X . . . .
  4 . . . X X . . . . .
  5 . . . X . . . . . .
  6 . . . X . X . . . .
  7 . . . . . . . . . .
  8 . . . . . . . . . .
  9 . . . . . . . . . .
*/
inicializuj($petriho_miska);
$petriho_miska[2][3] = 1;
$petriho_miska[2][4] = 1;
$petriho_miska[3][3] = 1;
$petriho_miska[3][5] = 1;
$petriho_miska[4][3] = 1;
$petriho_miska[4][4] = 1;
$petriho_miska[5][3] = 1;
$petriho_miska[6][3] = 1;
$petriho_miska[6][5] = 1;

/*
    Y ->
    0 1 2 3 4 5 6 7 8 9
X 0 . . . . . . . . . .
  1 . . X . . . . X X .
  2 . X X X . . X . X .
  3 . . X . . . . X . .
  4 . . . . . . . . . .
  5 . . . . . . . . . .
  6 . . . . . . . X . .
  7 . X X X . X X X X .
  8 . X X . . . . X X .
  9 . . . . . . . . X .
*/
inicializuj($petriho_miska);
$petriho_miska[2][2] = 1;
$petriho_miska[1][2] = 1;
$petriho_miska[2][1] = 1;
$petriho_miska[2][3] = 1;
$petriho_miska[3][2] = 1;

$petriho_miska[1][7] = 1;
$petriho_miska[1][8] = 1;
$petriho_miska[2][8] = 1;
$petriho_miska[2][6] = 1;
$petriho_miska[3][7] = 1;
$petriho_miska[7][5] = 1;
$petriho_miska[7][1] = 1;
$petriho_miska[8][1] = 1;
$petriho_miska[8][2] = 1;
$petriho_miska[7][3] = 1;
$petriho_miska[7][2] = 1;

$petriho_miska[7][8] = 1;
//$petriho_miska[8][8] = 1;
$petriho_miska[7][7] = 1;
$petriho_miska[7][6] = 1;
$petriho_miska[6][7] = 1;
$petriho_miska[8][7] = 1;
$petriho_miska[8][8] = 1;
$petriho_miska[9][8] = 1;
//$petriho_miska[][] = 1;

define('POCET_GENERACI', 200);
define('POCET_PRO_ZEMRE', 1);
define('POCET_PRELIDNENI_ZEMRE', 4);
define('POCET_NOVA', 3);
define('SLEEP_TIME', 100000); //hodnota v sec. | 0.5sec = 500000

function vykresli($generace) {
  global $petriho_miska;

  //vytvorime vystup
  $src = '<table style="border: 1px solid #000000; border-collapse: collapse;" cellspacing="0" cellpadding="0">';
  for ($x = 0; $x <  POLE_X; $x++)
  {
    $src .= '<tr>';
    for ($y = 0; $y <  POLE_Y; $y++)
    {
      if ($petriho_miska[$x][$y] === 1)
      {
        $src .= '<td style="background-color: #009900; width: '.CELL_SIZE.'px; height: '.CELL_SIZE.'px; border: 1px solid #000000;"></td>';
      }
      else
      {
        $src .= '<td style="border: 1px solid #000000; width: '.CELL_SIZE.'px; height: '.CELL_SIZE.'px;"></td>';
      }
    }
    $src .= '</tr>';
  }
  $src .= '</table>';
 
  //echo $src;flush();
 
  //posleme jej do pozadovaneho zobrazeni
  echo '<script type="text/javascript">'.N.
       '  document.getElementById(\'pocet_generace\').value = '.$generace.'; '.N.
       '  document.getElementById(\'petriho_miska\').innerHTML = \''.$src.'\'; '.
       '</script>'.N;
  flush();
}

function pocet_zivych($x, $y) {

  $pocet = 0;
 
  $pocet += (je_ziva($x-1, $y-1) === 1)? 1:0;
  $pocet += (je_ziva($x-1, $y)   === 1)? 1:0;
  $pocet += (je_ziva($x-1, $y+1) === 1)? 1:0;
  $pocet += (je_ziva($x,   $y-1) === 1)? 1:0;
  $pocet += (je_ziva($x,   $y+1) === 1)? 1:0;
  $pocet += (je_ziva($x+1, $y-1) === 1)? 1:0;
  $pocet += (je_ziva($x+1, $y)   === 1)? 1:0;
  $pocet += (je_ziva($x+1, $y+1) === 1)? 1:0;
 
  return $pocet;
}

function je_ziva($x, $y) {
  global $petriho_miska;
 
  if ($x < 0 || $y < 0 || $x > (POLE_X - 1) || $y > (POLE_Y - 1))
  {
    return false;
  }
  else
  {
    return $petriho_miska[$x][$y];
  }
}

function prepocitej() {
  global $petriho_miska;

  $tmp_array = $petriho_miska;

  for ($x = 0; $x < POLE_X; $x++)
  {
    for ($y = 0; $y < POLE_Y; $y++)
    {
      $pocet = pocet_zivych($x, $y);
      
      if (($pocet <= POCET_PRO_ZEMRE) ||
          ($pocet >= POCET_PRELIDNENI_ZEMRE))
      {
        $tmp_array[$x][$y] = 0;
      }
      elseif ($pocet >= POCET_NOVA && $pocej < POCET_PRELIDNENI_ZEMRE)
      {
        $tmp_array[$x][$y] = 1;
      }
    }
  }
  $petriho_miska = $tmp_array;
  $tmp_array = array();
}

/**
 * pocitej a zij
 */
$aktualni_generace = 0;
while ($aktualni_generace++ < POCET_GENERACI)
{
  //echo $aktualni_generace.'<br />'; flush();
 
  vykresli($aktualni_generace);
  usleep(SLEEP_TIME);
  prepocitej();
  flush();
}

vykresli($aktualni_generace);
flush();

Zdroje na webu

  • http://cs.wikipedia.org/wiki/Hra_%C5%BEivota
Petr Kobelka | Egoblog.cz | Tvorba www stránek - www.petrkobelka.cz

Petr Kobelka
Autor je zkušeným web developerem a programátorem s více než 10 letými zkušenostmi. Pracuje jako programátor pro známou Olomouckou společnost zabývající se tvorbou internetových a intranetových řešení. Spolu se zaměstnáním pracuje na volné noze a zabývá se tvorbou internetových stránek. Ve volném čase rád fotí, jezdí na kole, plave a cestuje.

Komentáře

E-mail je potřeba pouze pro vygenerování Gravataru!

Oups, žádné komentáře? Buďtě první !!!

Blog píše Petr Kobelka

Petr Kobelka - egoblog.cz

Žádám všechny, kteří mají zájem vkládat komentáře, aby se řídili pravidly NETikety. Komentáře, porušující tato pravidla můžou být bez varování smazány.