2011-05-15 8 views
2

나는 Conway의 Game of Life를 직접 작성하여 Javascript를 선택했습니다. 순수한 DHTML입니다. 내가 배운 기본 사항은 있지만 정상적인 Game of Life 행동과 일치하지 않는 것 같습니다. 예를 들어, 글라이더와 같은 패턴은 '미끄러지지 않습니다', 발진기는 진동하지 않습니다. 나는 다양한 논리를 시도하면서 많은 시간을 보냈으며 10 번 이상 재 작성했다.Javascript에서의 Conway의 게임 게임 - 셀룰러 로직 문제

글라이더 패턴을 만든 경우 한 세대가 지나면 정사각형의 정물로 바뀝니다. 여기

합니다 (주석 코드에 대한 죄송합니다) 자바 스크립트 코드 :

var chanceOfLiveCells = 0.1; 
var gridReference = null; 
var gridDimension = 15; 
var cells = null; 
var cellsAlive = 0; 
var cellsDead = 0; 
var currentGeneration = 0; 

function init() { 

    gridReference = document.getElementById('grid'); 
    cells = new Array(); 

    drawGrid(); 
    placeRandomCells(); 
    nextGeneration(); 

} 

function drawGrid() { 

    var gridArray = new Array(); 
    var counter = 0; 

    for(var x = 0; x <= gridDimension - 1; x = x + 1) { 

     gridArray.push('<tr>'); 

     for(var y = 0; y <= gridDimension - 1; y = y + 1) { 

      //gridArray.push('<td id="' + counter + '">' + x + ', ' + y + ' (' + counter + ')' + '</td>'); 
      gridArray.push('<td id="' + counter + '"></td>'); 
      cells.push(counter); 
      counter = counter + 1; 

     } 

     gridArray.push('</tr>'); 

    } 

    grid = gridArray.join(''); 
    gridReference.innerHTML = grid; 

} 

function nextGeneration() { 

    currentGeneration = currentGeneration + 1; 

    for(var x = 0; x <= gridDimension - 1; x = x + 1) { 

     for(var y = 0; y <= gridDimension - 1; y = y + 1) { 

      var neighbours = cellNeighbourCount(x, y); 

      if(isCellLive(x, y) == true) { 

       if(neighbours < 2) { 

        setDeadCell(x, y); 
        cellsDead = cellsDead + 1; 

       } 

       if(neighbours == 2 || neighbours == 3) { 

        setLiveCell(x, y); 
        cellsAlive = cellsAlive + 1; 

       } 

       if(neighbours > 3) { 

        setDeadCell(x, y); 
        cellsDead = cellsDead + 1; 

       } 

      } 

      else if(isCellLive(x, y) == false){ 

       if(neighbours == 3) { 

        setLiveCell(x, y); 
        cellsAlive = cellsAlive + 1; 

       } 

      } 

     } 

    } 

    document.getElementById('currentGeneration').innerHTML = currentGeneration; 
    document.getElementById('cellsAlive').innerHTML = cellsAlive; 
    document.getElementById('cellsDead').innerHTML = cellsDead; 

    cellsAlive = 0; 
    cellsDead = 0; 

    setTimeout('nextGeneration()', 200); 

} 

function placeRandomCells() { 

    for(var x = 0; x <= gridDimension - 1; x = x + 1) { 

     for(var y = 0; y <= gridDimension - 1; y = y + 1) { 

      if(Math.random() < chanceOfLiveCells) { 

       setLiveCell(x, y); 

      } 

      else { 

       setDeadCell(x, y); 

      } 

     } 

    } 

} 

function setLiveCell(x, y) { 

    document.getElementById(getCell(x, y)).style.backgroundColor = 'red'; 

} 

function setDeadCell(x, y) { 

    document.getElementById(getCell(x, y)).style.backgroundColor = 'maroon'; 

} 

function cellNeighbourCount(x, y) { 

    var count = 0; 

    if(isCellLive(x - 1, y) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x - 1, y + 1) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x, y + 1) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x + 1, y + 1) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x + 1, y) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x + 1, y - 1) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x, y - 1) == true) { 

     count = count + 1; 

    } 

    if(isCellLive(x - 1, y - 1) == true) { 

     count = count + 1; 

    } 

    return count; 

} 

function isCellLive(x, y) { 

    if(document.getElementById(getCell(x, y)).style.backgroundColor == 'red') { 

     return true; 

    } 

    return false; 

} 

function getCell(x, y) { 

    if(x >= gridDimension) { 

     x = 0; 

    } 

    if(y >= gridDimension) { 

     y = 0; 

    } 

    if(x < 0) { 

     x = gridDimension - 1; 

    } 

    if(y < 0) { 

     y = gridDimension - 1; 

    } 

    return cells[x * gridDimension + y]; 

} 

function createSquare() { 

    setLiveCell(4, 4); 
    setLiveCell(4, 5); 
    setLiveCell(4, 6); 
    setLiveCell(5, 6); 
    setLiveCell(6, 6); 
    setLiveCell(6, 5); 
    setLiveCell(6, 4); 
    setLiveCell(5, 4); 

} 

function createBlinker() { 

    setLiveCell(4, 5); 
    setLiveCell(5, 5); 
    setLiveCell(6, 5); 

} 

function createBeacon() { 

    setLiveCell(4, 4); 
    setLiveCell(4, 5); 
    setLiveCell(5, 4); 
    setLiveCell(5, 5); 
    setLiveCell(6, 6); 
    setLiveCell(6, 7); 
    setLiveCell(7, 6); 
    setLiveCell(7, 7); 

} 

답변

1

더 기능이 없다 'renderNextGeneration()'

하여 setInterval() 당신이있어 무엇을 더 적절하고 유지 보수 할 수 있습니다 하기.

Firefox의 '오류 콘솔'은 자바 스크립트 오류 디버깅에 큰 도움이됩니다.


패치를 적용하려면 패치를 실행해야합니다. 그건 내 시스템에서하는거야.

[email protected]:~/stackoverflow/gameoflife$ bzr diff -r18 bad.js 
=== modified file 'gameoflife/bad.js' 
--- gameoflife/bad.js 2011-05-15 14:09:12 +0000 
+++ gameoflife/bad.js 2011-05-16 04:14:40 +0000 
@@ -1,10 +1,11 @@ 
-var chanceOfLiveCells = 0.1; 
+var chanceOfLiveCells = 0.0; 
var gridReference = null; 
var gridDimension = 15; 
var cells = null; 
var cellsAlive = 0; 
var cellsDead = 0; 
var currentGeneration = 0; 
+var timer = null; 

function init() { 

@@ -13,7 +14,8 @@ 

    drawGrid(); 
    placeRandomCells(); 
- nextGeneration(); 
+ createBlinker(); 
+ timer = setInterval(nextGeneration, 200); 

} 

@@ -45,7 +47,7 @@ 
} 

function nextGeneration() { 
- 
+ alert("next generation"); 
    currentGeneration = currentGeneration + 1; 

    for(var x = 0; x <= gridDimension - 1; x = x + 1) { 
@@ -93,15 +95,16 @@ 
     } 

    } 
- 
+  
+ repaint(); 
    document.getElementById('currentGeneration').innerHTML = currentGeneration; 
    document.getElementById('cellsAlive').innerHTML = cellsAlive; 
    document.getElementById('cellsDead').innerHTML = cellsDead; 
+ if (cellsAlive == 0) clearInterval(timer); 

    cellsAlive = 0; 
    cellsDead = 0; 

- setTimeout('nextGeneration()', 200); 

} 

@@ -127,17 +130,40 @@ 

    } 

+ repaint(); 
+ 
+} 
+function repaint() { 
+ 
+ for(var x = 0; x <= gridDimension - 1; x = x + 1) { 
+ 
+  for(var y = 0; y <= gridDimension - 1; y = y + 1) { 
+ 
+   repaintCell(x, y); 
+ 
+  } 
+ 
+ } 
+ 
+} 
+ 
+function repaintCell(x, y) { 
+ 
+ cell = document.getElementById(getCell(x, y)); 
+ color = cell.style.color; 
+ cell.style.backgroundColor = color; 
+ 
} 

function setLiveCell(x, y) { 

- document.getElementById(getCell(x, y)).style.backgroundColor = 'red'; 
+ document.getElementById(getCell(x, y)).style.color = 'red'; 

} 

function setDeadCell(x, y) { 

- document.getElementById(getCell(x, y)).style.backgroundColor = 'maroon'; 
+ document.getElementById(getCell(x, y)).style.color = 'maroon'; 

} 

@@ -249,7 +275,7 @@ 
    setLiveCell(6, 5); 
    setLiveCell(6, 4); 
    setLiveCell(5, 4); 
- 
+ repaint() 
} 

function createBlinker() { 
@@ -257,7 +283,7 @@ 
    setLiveCell(4, 5); 
    setLiveCell(5, 5); 
    setLiveCell(6, 5); 
- 
+ repaint(); 
} 

function createBeacon() { 
@@ -270,5 +296,5 @@ 
    setLiveCell(6, 7); 
    setLiveCell(7, 6); 
    setLiveCell(7, 7); 
- 
+ repaint(); 
} 

논리 오류는 루프를 진행하면서 셀을 죽이는 것입니다. 코드가 살아 있어야하는 죽은 세포에 도달 할 때까지 이미 하나 이상의 이웃을 죽였습니다.

+0

그냥 nextGeneration()이라고 가정합니다. – Mark

+0

오류라고는 말할 수 없지만 논리가 문제가되어 오류 콘솔이 쓸모가 없습니다. – Mark

+0

@jcomeau_ictx "코드를 수정했습니다. 여기 diff가 있습니다." – Raynos