Reader Level:
ARTICLE

How to Make Conway's Game of Life in HTML5

Posted by Arjun Panwar Articles | HTML 5 January 22, 2012
Here in this article we show how to make a Conway's game application in HTML5.
  • 0
  • 0
  • 5221
Download Files:
 

The game of conway's is one of the example of games because it's related to the cellular automata. The game of life also called simply as life .The game of conway is a board game .In this games follow many different types of patterns occur in the game of life. In more common cases it is impossible to look at a starting position or pattern and see what will happen in the future. Here we find a way to find out is to follow the rules of the game.

There are some rules which as follows :

  • A cell with 0 or 1 neighbor dies because of underpopulation.
  • When a cell with 4 or more neighbors dies because of overpopulation.
  • If any empty space has exactly 3 cells then a new cell is born in that empty space.
  • If none of the above rules apply then the space does not change a live cell remains alive, and an empty space is still empty.

Step 1 : Open any HTML editor (ex. Visual Studio, Notepad etc) and in the source code page (page where you want to write the HTML code) type the following lines.

Here first of all given an title.

<!doctype html>
 
<html>
 
       <head>
 
              <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 
              <link rel="stylesheet" href="css/site.css" type="text/css" media="screen" />
 
              <title>Conway's Game of Life</title
>


Step 2 : This step is writing the canvas tags with a default message in case when the user's browser does not support it. So, apply this condition. 

else {
       alert("Canvas is unsupported in your browser.");

     }

Step 3 : The given code works on there things simply.

  • Here we have to declare how many cells we want on the X/Y axes.
  • In there different cells wide should be a cell and the delay between drawing the next generation of cells.
  • So create 2 arrays, one for storing the initial colony and one for the next generation.
  • We have to fill randomly with live cells in the initial part.
  • We have to draw the initial part and then process the initial part using the game's rules.
     

<script type="text/javascript">
                       $(document).ready(
                                      function () {
                                          Array.matrix = function (m, n, initial) {
                                              var a, i, j, mat = [];
                                              for (i = 0; i < m; i += 1) {

                                                 a = [];
                                                  for (j = 0; j < n; j += 1) {
                                                      a[j] = 0;
                                                  }
                                                  mat[i] = a;
                                              }
                                              return mat;
                                          };
                                           var Life = {};
                                          Life.CELL_SIZE = 8;
                                          Life.X = 576;
                                          Life.Y = 320;
                                          Life.WIDTH = Life.X / Life.CELL_SIZE;
                                          Life.HEIGHT = Life.Y / Life.CELL_SIZE;
                                          Life.DEAD = 0;
                                          Life.ALIVE = 1;
                                          Life.DELAY = 500;
                                          Life.STOPPED = 0;
                                          Life.RUNNING = 1;
                                          Life.minimum = 2;
                                          Life.maximum = 3;
                                          Life.spawn = 3;
                                          Life.state = Life.STOPPED;
                                          Life.interval = null;
                                          Life.grid = Array.matrix(Life.HEIGHT, Life.WIDTH, 0);
                                          Life.counter = 0;
                                          Life.updateState = function () {
                                              var neighbours;
                                               var nextGenerationGrid = Array.matrix(Life.HEIGHT, Life.WIDTH, 0);
                                              for (var h = 0; h < Life.HEIGHT; h++) {
                                                 for (var w = 0; w < Life.WIDTH; w++) {
                                                      neighbours = Life.calculateNeighbours(h, w);
                                                      if (Life.grid[h][w] !== Life.DEAD) {
                                                          if ((neighbours >= Life.minimum) && (neighbours <= Life.maximum)) {
                                                              nextGenerationGrid[h][w] = Life.ALIVE;
                                                          }
                                                      } else {
                                                          if (neighbours === Life.spawn) {
                                                              nextGenerationGrid[h][w] = Life.ALIVE;
                                                          }
                                                      }
                                                  }
                                              }
                                              Life.copyGrid(nextGenerationGrid, Life.grid);
                                              Life.counter++;
                                          };
                                          Life.calculateNeighbours = function (y, x) {
                                              var total = (Life.grid[y][x] !== Life.DEAD) ? -1 : 0;
                                              for (var h = -1; h <= 1; h++) {
                                                  for (var w = -1; w <= 1; w++) {
                                                      if (Life.grid[(Life.HEIGHT + (y + h)) % Life.HEIGHT][(Life.WIDTH + (x + w)) % Life.WIDTH] !== Life.DEAD) {
                                                          total++;
                                                      }
                                                  }
                                              }
                                              return total;
                                          };
                                          Life.copyGrid = function (source, destination) {
                                              for (var h = 0; h < Life.HEIGHT; h++) {
                                                 
/*
                                                  for (var w = 0; w < Life.WIDTH; w++) {
                                                  destination[h][w] = source[h][w];
                                                  }
                                                  */
                                                  destination[h] = source[h].slice(0);
                                              }
                                          };
                                          function Cell(row, column) {
                                              this.row = row;
                                              this.column = column;
                                          };
                                          var gridCanvas = document.getElementById('grid');
                                          var counterSpan = document.getElementById("counter");
                                          var controlLink = document.getElementById("controlLink");
                                          var clearLink = document.getElementById("clearLink");
                                          var minimumSelect = document.getElementById("minimumSelect");
                                          var maximumSelect = document.getElementById("maximumSelect");
                                          var spawnSelect = document.getElementById("spawnSelect");
                                           controlLink.onclick = function () {
                                             switch (Life.state) {
                                                  case Life.STOPPED:
                                                      Life.interval = setInterval(function () {
                                                          update();
                                                      }, Life.DELAY);
                                                      Life.state = Life.RUNNING;
                                                      break;
                                                  default:
                                                      clearInterval(Life.interval);
                                                      Life.state = Life.STOPPED;
                                              }
                                          };
                                          clearLink.onclick = function () {
                                              Life.grid = Array.matrix(Life.HEIGHT, Life.WIDTH, 0);
                                              Life.counter = 0;
                                              clearInterval(Life.interval);
                                              Life.state = Life.STOPPED;
                                              updateAnimations();
                                          }
                                           minimumSelect.onchange = function () {
                                             clearInterval(Life.interval);
                                              Life.state = Life.STOPPED;
                                              Life.minimum = minimumSelect.value;
                                              updateAnimations();
                                          }
                                          maximumSelect.onchange = function () {
                                              clearInterval(Life.interval);
                                              Life.state = Life.STOPPED;
                                              Life.maximum = maximumSelect.value;
                                              updateAnimations();
                                          }
                                           spawnSelect.onchange = function () {
                                              clearInterval(Life.interval);
                                              Life.state = Life.STOPPED;
                                              Life.spawn = spawnSelect.value;
                                              updateAnimations();
                                          }
                                          function update() {
                                              Life.updateState();
                                              //updateInput();
                                              //updateAI();
                                              //updatePhysics();
                                              updateAnimations();
                                              //updateSound();
                                              //updateVideo();
                                          };
                                          function updateAnimations() {
                                              for (var h = 0; h < Life.HEIGHT; h++) {
                                                  for (var w = 0; w < Life.WIDTH; w++) {
                                                      if (Life.grid[h][w] === Life.ALIVE) {
                                                          context.fillStyle = "#000";
                                                      } else {
                                                          context.fillStyle = "#FF0000";
                                                          //context.clearRect();
                                                      }
                                                      context.fillRect(
                                                                                                w * Life.CELL_SIZE + 1,
                                                                                                h * Life.CELL_SIZE + 1,
                                                                                                Life.CELL_SIZE - 1,
                                                                                                Life.CELL_SIZE - 1);
                                                  }
                                              }
                                              counterSpan.innerHTML = Life.counter;
                                          };
                                          if (gridCanvas.getContext) {
                                              var context = gridCanvas.getContext('2d');
                                              var offset = Life.CELL_SIZE;
                                              for (var x = 0; x <= Life.X; x += Life.CELL_SIZE) {
                                                  context.moveTo(0.5 + x, 0);
                                                  context.lineTo(0.5 + x, Life.Y);
                                              }
                                              for (var y = 0; y <= Life.Y; y += Life.CELL_SIZE) {
                                                 context.moveTo(0, 0.5 + y);
                                                  context.lineTo(Life.X, 0.5 + y);
                                              }
                                              context.strokeStyle = "#254117";
                                              context.stroke();
                                              function canvasOnClickHandler(event) {
                                                  var cell = getCursorPosition(event);
                                                  var state = Life.grid[cell.row][cell.column] == Life.ALIVE ? Life.DEAD : Life.ALIVE;
                                                  Life.grid[cell.row][cell.column] = state;
                                                  updateAnimations();
                                              };
                                              function getCursorPosition(event) {
                                                  var x;
                                                  var y;
                                                  if (event.pageX || event.pageY) {
                                                      x = event.pageX;
                                                      y = event.pageY;
                                                  } else {
                                                      x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                                                      y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                                                  }
                                                  x -= gridCanvas.offsetLeft;
                                                  y -= gridCanvas.offsetTop;
                                                  var cell = new Cell(Math.floor((y - 4) / Life.CELL_SIZE), Math.floor((x - 2) / Life.CELL_SIZE));
                                                  return cell;
                                              };
                                              gridCanvas.addEventListener("click", canvasOnClickHandler, false);
                                          } else {
                                              alert("Canvas is unsupported in your browser.");
                                          }
                                      }
                             );
                                      function minimumSelect_onclick() {
 
                                      } 
        </script>
                   <script type="text/javascript">
                       var _gaq = _gaq || [];
                       _gaq.push(['_setAccount', 'UA-2662092-4']);
                       _gaq.push(['_trackPageview']);
                       (function () {
                           var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
                           ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                           var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
                       })()
                   </script
>

<script type="text/javascript">
                       var _gaq = _gaq || [];
                       _gaq.push(['_setAccount', 'UA-2662092-4']);
                       _gaq.push(['_trackPageview']);
                        (function () {
                           var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
                          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                           var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
                       })();
                   </script

Step 4 : This application contains  body follow the code given below.

<body>
                   <div id="container">
                             <div id="header">
                                      <h1>Conway's Game of Life</h1>
                             </div>
                             <div id="left-content">
                                      <h2>Game</h2>
                                      <p>Generation counter: <span id="counter">0</span></p>
                                      <canvas id="grid" width="577" height="321"></canvas>
                             </div>
                             <div id="right-content">
                                      <h2>Controls</h2>
                                      <a id="controlLink" href="javascript:void(0)">Start/Stop</a><br />
                                       <a id="clearLink" href="javascript:void(0)">Clear Grid</a>
                                     <select id="minimumSelect" disabled="disabled" onclick="return minimumSelect_onclick()">                                       
                                      </select><br />
                                      <select id="maximumSelect" disabled="disabled">                                               
                                      </select><br />
                                      <select id="spawnSelect" disabled="disabled">
                                      </select><br />
                                      <p>
                                      </p>
                             </div>
                   </div>
          </body
>

Step 5 : After write this code the application an run in browser we have to see figure given below.

 conway game.jpg

Step 6 : After click on the game board we have to find it.

conwa.jpg

We have to play any thing with cells.

conway.jpg

Step 7 :  With start/stop button on click and clear the game board with use of the clear button.

befor run.jpg

After making on cells click on start button we have to find this figure given below .

after run.jpg

Resources

Here are some useful resources:

COMMENT USING

Trending up