Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Неправильно работает "Жизнь"
 
 автор: nikita2206   (12.01.2011 в 00:25)   письмо автору
44.6 Кб
 
 

Написал на шарпе реализацию игры "Жизнь", но она почему-то работает неправильно, может кто подскажет, в чем ошибка?
Сорс, я так понимаю, выкладывать сюда нежелательно (без подсветки), так что прикрепил архив с проектом (Microsoft VS Express 2010).
В чем именно выражается неправильность? Например не работает глайдер.

  Ответить  
 
 автор: Trianon   (12.01.2011 в 02:02)   письмо автору
 
   для: nikita2206   (12.01.2011 в 00:25)
 

                   if (x > 0 && y > 0 && Lifes[x - 1, y - 1]) Count++;
                    if (y > 0 && Lifes[x, y - 1]) Count++;
                    if (y > 0 && x < Size - 1 && Lifes[x + 1, y - 1]) Count++;
                    if (x < Size - 1 && Lifes[x + 1, y]) Count++;
                    if (x < Size - 1 && y < Size - 1 && Lifes[x + 1, y + 1]) Count++;
                    if (y < Size - 1 && Lifes[x, y + 1]) Count++;
                    if (x > 0 && y < Size - 1 && Lifes[x - 1, y + 1]) Count++;
                    if (x > 0 && Lifes[x - 1, y]) Count++;

                    if (Lifes[x, y] && (Count < 2 || Count > 3))
                    {
                        Lifes[x, y] = false;
                        hasChanged = true;
                        hasAnyoneChanged = true;
                    }
                    if (!Lifes[x, y] && Count == 3)
                    {
                        Lifes[x, y] = true;
                        hasChanged = true;
                        hasAnyoneChanged = true;
                    }


Потому что по правилам, изменения планируемые для поколения N по состоянию поколения N-1 никак не могут затронуть вычисления этого самого плана поколенпя N.
У Вас же при подсчете Count запросто может быть оценена клетка, которая еще не изменилась, но уже спланирована для изменения. Причем оценена по своему будущему состоянию.


PS. И код оценки числа соседей, мягко говоря, далек от совершенства, вне связи с указанной логической ошибкой.

  Ответить  
 
 автор: nikita2206   (12.01.2011 в 13:32)   письмо автору
 
   для: Trianon   (12.01.2011 в 02:02)
 

Спасибо за ответ.
Вообще я так и думал, и до этого писал с двумя массивами данных (второй заполнялся в момент вычисления и по окончании вычисления клонировался в исходный и очищался), но так как глайдер и там не работал, решил попробовать переписать так... А может он правильно работал? Глайдер должен бесконечно "лететь"? Или он через несколько итераций уничтожается? Я уже даже на листке бумаги попробовал его "пустить", и тут он через, кажется, пять итераций перешел в бесконечную фигуру (две точки рядом, с равной абсциссой)...

Насчет кода подсчета числа, да, с час думал над тем, как красивее написать, в итоге так и не додумался... Может подскажете как лучше?

  Ответить  
 
 автор: Trianon   (12.01.2011 в 15:28)   письмо автору
 
   для: nikita2206   (12.01.2011 в 13:32)
 

Чтобы показать, нужно хоть как-то знать язык. :)
Выбрал из двух языков, которых я не знаю, javascript - просто чтобы понагляднее.

<html>
<body>
<table border=0>
<script type=text/javascript >
  dc = document;  w = window;
  ww=hh=16;
    dc.writeln('<tr>');
    for(j = 0; j < 32; j++)
      dc.write('<td width=20></td>');
    dc.writeln('</tr>');
  for(i=0; i < hh; i++)
  {
    dc.writeln('<tr><td>|<td>');
    for(j = 0; j < ww; j++)
    {
      a = (i+j)&0?'*':'';
      ix = '_'+i+'_'+j;
      dc.write('<td id="'+ix+'"> '+a+' </td>');
    }
    dc.writeln('<td>|<td></tr>');
  }

</script>
<table>

<script type=text/javascript>

  function set(x, y, s)
  {
    h = dc.getElementById('_'+x+'_'+y);
    h.innerHTML = s?'*': ' ';
    s1[x][y]=s;
  }
  s1 = [], s2 = [];
  for(i = 0; i < ww; i++)
  for(s1[i]=[],s2[i]=[],j = 0; j < hh; j++)
    s1[i][j] = s2[i][j] = 0;

  s2[5][5] = 1;   s2[5][6] = 1;  s2[5][7] = 1;
  s2[6][5] = 1;
                  s2[7][6] = 1;

  function tran()
  {
    for(i = 0; i < hh; i++)
    for(j = 0; j < ww; j++)
      if(s1[i][j] != (x=s2[i][j]))
         set(i, j, x);
  }
  tran();

  function life()
  {
    for(i = 0; i < hh; i++)
    for(j = 0; j < ww; j++)
    { ct = 0; 
      for(i1 = i-1; i1<=i+1; i1++)
      for(j1 = j-1; j1<=j+1; j1++)
        ct+=s1[(i1+hh)%hh][(j1+ww)%ww];
      s2[i][j] = (ct < 3||4 < ct)?0 : ct == 3 ? 1 : s1[i][j];
    }
    tran();
    setTimeout('life()', 400);
  }
  life();
</script>

Это, безусловно,не самый оптимальный расчет.
Но хоть как-то

  Ответить  
 
 автор: nikita2206   (12.01.2011 в 17:03)   письмо автору
 
   для: Trianon   (12.01.2011 в 15:28)
 

Спасибо за помощь, нашел свою ошибку, довольно идиотскую...

  Ответить  
 
 автор: Trianon   (12.01.2011 в 18:07)   письмо автору
 
   для: nikita2206   (12.01.2011 в 17:03)
 

вот вариант без закольцовки, но с глайдерным ружъем. :)

<html>
<body>

<script type=text/javascript >
  dc = document;  w = window;
 function init()
 {
  dc.writeln('<table border=0><tr>');
  for(j = 0; j < 32; j++)
    dc.write('<td width=20></td>');
  dc.writeln('</tr>');
  for(i=0; i < hh; i++)
  {
    dc.writeln('<tr><td>|<td>');
    for(j = 0; j < ww; j++)
    {
      a = (i+j)&0?'*':'';
      ix = '_'+i+'_'+j;
      dc.write('<td id="'+ix+'"> '+a+' </td>');
    }
    dc.writeln('<td>|<td></tr>');
  }
  dc.writeln('</table>');
 }

  s1 = [], s2 = [];

  function set(x, y, s)
  {
    var h = dc.getElementById('_'+x+'_'+y);
    h.innerHTML = s?'*': ' ';
    s1[x][y]=s;
  }


  function gen(l)
  {
     var a=[]; a['.'] = 0, a['*'] = 1;
     var r=[];
     var m = l.split('');
     for (j = 0; j < m.length; j++)
          r[j] = a[m[j]];
     return r;
  }

 function init()
 {
  dc.writeln('<table border=0><tr>');
  for(j = 0; j < ww; j++)
    dc.write('<td width=20></td>');
  dc.writeln('</tr>');
  for(i=0; i < hh; i++)
  {
    dc.writeln('<tr><td>|<td>');
    for(j = 0; j < ww; j++)
    {
      a = (i+j)&0?'*':'';
      ix = '_'+i+'_'+j;
      dc.write('<td id="'+ix+'"> '+a+' </td>');
    }
    dc.writeln('<td>|<td></tr>');
  }
  dc.writeln('</table>');
 }

  var i=0, j=0;
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..........................*.......................');
  s2[i++]= gen( '.......................****....*..................');
  s2[i++]= gen( '..............*.......****.....*..................');
  s2[i++]= gen( '.............*.*......*..*.........**.............');
  s2[i++]= gen( '............*...**....****.........**.............');
  s2[i++]= gen( '.**.........*...**.....****.......................');
  s2[i++]= gen( '.**.........*...**........*.......................');
  s2[i++]= gen( '.............*.*..................................');
  s2[i++]= gen( '..............*...................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  s2[i++]= gen( '..................................................');
  ww=s2[i-1].length;
  hh=i;
  init();


  for(i = 0; i < hh; i++)
     s1[i]=gen( '..................................................');


  function tran()
  {
    for(i = 0; i < hh; i++)
    for(j = 0; j < ww; j++)
      if(s1[i][j] != (x=s2[i][j]))
         set(i, j, x);
  }
  tran();

  function life()
  {
    for(i = 1; i < hh-1; i++)
    for(j = 1; j < ww-1; j++)
    {
        ct=s1[i-1][j-1]+s1[i-1][j  ]+s1[i-1][j+1]
          +s1[i  ][j-1]+s1[i  ][j  ]+s1[i  ][j+1]
          +s1[i+1][j-1]+s1[i+1][j  ]+s1[i+1][j+1];
      s2[i][j] = (ct < 3||4 < ct)?0 : ct == 3 ? 1 : s1[i][j];
    }
    tran();
    setTimeout('life()', 500);
  }
  life();
</script>

  Ответить  
 
 автор: nikita2206   (12.01.2011 в 19:25)   письмо автору
 
   для: Trianon   (12.01.2011 в 18:07)
 

Отлично, и у меня ружье работает. Опубликовать что-ли на хабре очередную реализацию этой игры? На фоне всеобщей истерии о "Жизне" :) Вроде на шарпе еще не делали.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования