Last active
August 29, 2015 13:59
-
-
Save coryk135/10799089 to your computer and use it in GitHub Desktop.
Golang Game of Life ported to JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
</head> | |
<body> | |
<canvas id="canvas" width="1000" height="1000"></canvas> | |
<script src="life.js"></script> | |
<body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rand = { | |
Intn: function(n) { | |
var val = Math.floor(Math.random() * n); | |
if (val == n) val--; | |
return val; | |
} | |
} | |
// Functions can be treated like classes. | |
// Think of this as the constructor | |
// Field represents a two-dimensional field of cells. | |
function Field(s, w, h) { | |
this.s = s | |
this.w = w | |
this.h = h | |
} | |
// The next function is just a helper funciton that creates a new | |
// field for you. | |
// NewField returns an empty field of the specified width and height. | |
function NewField(w, h) { | |
var s = new Array(h); | |
for (i = 0; i < s.length; i++) { | |
s[i] = new Array(w); | |
} | |
return new Field(s, w, h); | |
} | |
// Field.prototype.<Function_Name> = function(){} | |
// This adds a method to the prototype of a function | |
// In this sense we are adding a "method" to the "class" Field | |
// Set sets the state of the specified cell to the given value. | |
Field.prototype.Set = function(x, y, b) { | |
this.s[y][x] = b | |
} | |
Field.prototype.Alive = function(x, y) { | |
x += this.w | |
x %= this.w | |
y += this.h | |
y %= this.h | |
return this.s[y][x] | |
} | |
Field.prototype.Next = function(x, y) { | |
// Count the adjacent cells that are alive. | |
var alive = 0 | |
for (i = -1; i <= 1; i++) { | |
for (j = -1; j <= 1; j++) { | |
if ((j != 0 || i != 0) && this.Alive(x+i, y+j)) { | |
alive++ | |
} | |
} | |
} | |
// Return next state according to the game rules: | |
// exactly 3 neighbors: on, | |
// exactly 2 neighbors: maintain current state, | |
// otherwise: off. | |
return alive == 3 || alive == 2 && this.Alive(x, y) | |
} | |
function Life(a, b, w, h) { | |
this.a = a | |
this.b = b | |
this.w = w | |
this.h = h | |
} | |
function NewLife(w, h) { | |
var a = NewField(w, h) | |
for (i = 0; i < (w * h / 4); i++) { | |
a.Set(rand.Intn(w), rand.Intn(h), true) | |
} | |
return new Life(a, NewField(w, h), w, h); | |
} | |
Life.prototype.Step = function() { | |
// Update the state of the next field (b) from the current field (a). | |
for (y = 0; y < this.h; y++) { | |
for (x = 0; x < this.w; x++) { | |
this.b.Set(x, y, this.a.Next(x, y)) | |
} | |
} | |
// Swap fields a and b. | |
var temp = this.a; this.a = this.b; this.b = temp; | |
} | |
Life.prototype.String = function() { | |
var buf = "" | |
for (y = 0; y < this.h; y++) { | |
for (x = 0; x < this.w; x++) { | |
b = ' ' | |
if (this.a.Alive(x, y)) { | |
b = '*' | |
} | |
buf += b | |
} | |
buf += '\n' | |
} | |
return buf | |
} | |
var id; | |
function main() { | |
var canvas = document.getElementById('canvas'); | |
var ctx = canvas.getContext('2d'); | |
var width = 100; | |
var height = 100; | |
l = NewLife(100, 100) | |
id = setInterval(function(){ | |
l.Step(); | |
var chars = l.String(); | |
ctx.fillStyle = "rgb(255,255,255)"; | |
ctx.clearRect(0,0,1000,1000); | |
ctx.fillStyle = "rgb(200,0,0)"; | |
var i = 0; | |
var j = 0; | |
var r,g,b; | |
for(var c = 0; c < chars.length; c++){ | |
var char = chars[c]; | |
if(char == "\n"){ | |
i++; | |
j=0; | |
} else { | |
if(char == "*"){ | |
r = Math.floor(Math.random()*255); | |
g = Math.floor(Math.random()*255); | |
b = Math.floor(Math.random()*255); | |
ctx.fillStyle = "rgb("+r+","+g+","+b+")"; | |
ctx.fillRect(i*10,j*10, 10, 10); | |
} | |
j++; | |
} | |
} | |
/* | |
for(var i = 0; i<width; i+=1){ | |
for(var j = 0; j<height; j+=1){ | |
if(cells[i][j].alive){ | |
ctx.fillRect(i*10,j*10, 10, 10); | |
} | |
} | |
} | |
*/ | |
}, 40); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment