|
44.6 Кб |
|
| Написал на шарпе реализацию игры "Жизнь", но она почему-то работает неправильно, может кто подскажет, в чем ошибка?
Сорс, я так понимаю, выкладывать сюда нежелательно (без подсветки), так что прикрепил архив с проектом (Microsoft VS Express 2010).
В чем именно выражается неправильность? Например не работает глайдер. | |
|
|
|
|
|
|
|
для: 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. И код оценки числа соседей, мягко говоря, далек от совершенства, вне связи с указанной логической ошибкой. | |
|
|
|
|
|
|
|
для: Trianon
(12.01.2011 в 02:02)
| | Спасибо за ответ.
Вообще я так и думал, и до этого писал с двумя массивами данных (второй заполнялся в момент вычисления и по окончании вычисления клонировался в исходный и очищался), но так как глайдер и там не работал, решил попробовать переписать так... А может он правильно работал? Глайдер должен бесконечно "лететь"? Или он через несколько итераций уничтожается? Я уже даже на листке бумаги попробовал его "пустить", и тут он через, кажется, пять итераций перешел в бесконечную фигуру (две точки рядом, с равной абсциссой)...
Насчет кода подсчета числа, да, с час думал над тем, как красивее написать, в итоге так и не додумался... Может подскажете как лучше? | |
|
|
|
|
|
|
|
для: 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>
|
Это, безусловно,не самый оптимальный расчет.
Но хоть как-то | |
|
|
|
|
|
|
|
для: Trianon
(12.01.2011 в 15:28)
| | Спасибо за помощь, нашел свою ошибку, довольно идиотскую... | |
|
|
|
|
|
|
|
для: 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>
|
| |
|
|
|
|
|
|
|
для: Trianon
(12.01.2011 в 18:07)
| | Отлично, и у меня ружье работает. Опубликовать что-ли на хабре очередную реализацию этой игры? На фоне всеобщей истерии о "Жизне" :) Вроде на шарпе еще не делали. | |
|
|
|