Created
May 27, 2016 20:16
-
-
Save ConorOBrien-Foxx/1f819ec2ce33b0cd5cc1dad621f62c02 to your computer and use it in GitHub Desktop.
an extension for variations of game of life
This file contains hidden or 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
var vgol = {}; | |
vgol.rules = {}; | |
// wrapper for making rules | |
vgol.makeRule = function makeRule(rule,deadColor,aliveColor,random,bP,sP){ | |
var pRule = rule.split("/").replace(/\D/g,""); | |
rules.push({ | |
dead: deadColor || "#000000", | |
alive: aliveColor || "#ffffff", | |
birth: rule[0].split(""), | |
survive: rule[1].split(""), | |
birthProb: random ? bP : 1, | |
surviveProb: random ? sP : 1, | |
}); | |
} | |
// generates a random color for the use in makeRule | |
// b is the factor by which the dead cells are darker than the light ones | |
vgol.generateColor = function generateColor(b){ | |
var alive = [0,0,0].map(function(e){return Math.random()*128+128|0}), | |
dead = alive.map(function(e){return e-(b||128)}); | |
return { | |
alive: vgol.rgbToHex(alive), | |
dead: vgol.rgbToHex(dead) | |
}; | |
} | |
// takes the entire grid and changes it to the input state | |
vgol.setGridState = function setGridState(state){ | |
for(var y=0;y<gridH;y++){ | |
for(var x=0;x<gridW;x++){ | |
grid[y][x][1]=state; | |
} | |
} | |
updateGraphics(); | |
} | |
// given N rules, patterns the grid in those rules | |
vgol.nPattern = function nPattern(){ | |
var statesCt = arguments.length; | |
states = Array.from(arguments); | |
for(var i=0;i<statesCt;i++){ | |
for(var y=0;y<gridH;y++){ | |
for(var x=(y+i)%statesCt;x<gridW;x+=statesCt){ | |
grid[y][x][0]=states[i]; | |
} | |
} | |
} | |
updateGraphics(); | |
} | |
// a special subset that takes 2 patterns | |
vgol.everyOther = function everyOther(state1,state2){ | |
vgol.nPattern(state1,state2); | |
} | |
// accepts a region and an optional array of points like this: | |
// [[[RULE,LIVING],[RULE,LIVING]],...]; | |
vgol.area = function(region,points){ | |
if(!(region instanceof vgol.region)) throw new TypeError("Argument not an instance of vgol.region"); | |
points = points || false; | |
this.uX = region.uX; | |
this.uY = region.uY; | |
this.lX = region.lX; | |
this.lY = region.lY; | |
this.grid = []; | |
for(var i=0;i<this.uX-this.lX;i++){ | |
this.grid[i] = []; | |
for(var j=0;j<this.uY-this.lY;j++){ | |
this.grid[i][j] = points ? points[i][j] : [0,0]; | |
} | |
} | |
} | |
// places the area on the grid, taking (bX,bY) as upper-left point for placement | |
vgol.area.prototype.place = function(bX,bY){ | |
//for(var i=bY;i<this.) | |
} | |
// region class, for manipulation of the grid | |
vgol.region = function(uX,uY,lX,lY){ | |
this.uX = uX; | |
this.uY = uY; | |
this.lX = lX; | |
this.lY = lY; | |
} | |
vgol.region.prototype.move = function(sX,sY){ | |
this.uX += sX; | |
this.uY += sY; | |
this.lX += sX; | |
this.lY += sY; | |
} | |
// region class created with width and height | |
vgol.quad = function(uX,uY,w,h){ | |
return new vgol.region(uX,uY,uX+w,uY+h); | |
this.uX = uX; | |
this.uY = uY; | |
this.lX = uX+w; | |
this.lY = uY+h; | |
} | |
// A box from (uX,uY) upper left to (lX,lY) lower right. | |
// moves pattern of state cells RIGHT by sX and DOWN by sY. | |
// m is the mode; default is cell rule, 1 is cell life | |
vgol.transpose = function transpose(uX,uY,lX,lY,sX,sY,m){ | |
m = m || 0; | |
for(var i=lY;i>=uY;--i){ | |
for(var j=lX;j>=uY;--j){ | |
if(typeof grid[i+sY]!=="undefined"&&typeof grid[i+sY][j+sX]!=="undefined"){ | |
var old = +grid[i+sY][j+sX][m]; | |
grid[i+sY][j+sX][m] = grid[i][j][m]; | |
grid[i][j][m] = old; | |
} | |
} | |
} | |
updateGraphics(); | |
} | |
// tranposing using a region | |
vgol.transposeRegion = function transposeRegion(region,sX,sY,m){ | |
if(!(a instanceof vgol.region)) throw new TypeError("Argument not an instance of vgol.region"); | |
vgol.transpose(region.uX,region.uY,region.lX,region.lY,sX,sY,m); | |
} | |
vgol.hexToRgb = function hexToRgb(h){ | |
return (h[0]=="#"?h.slice(1):h).match(/../g).map(function(t){return parseInt(t,16)}); | |
} | |
vgol.compressHex = function(h){ | |
return vgol.hexToRgb(h).map(function(y){return String.fromCharCode(y)}); | |
} | |
vgol.rgbToHex = function rgbToHex(h){ | |
return "#"+h.map(function(e){return e.toString(16).toUpperCase()}).join(""); | |
} | |
vgol.symbol = function symbol(index){ | |
return index == 0 ? "." : String.fromCharCode(48+index); | |
} | |
vgol.compress = function compress(){ | |
// let's compress this. | |
var vgolc = ""; end = ""; | |
for(var i=0;i<rules.length;i++){ | |
vgolc += vgol.symbol(i); | |
vgolc += ":=" + [ | |
rules[i].birth.join(" "), | |
rules[i].survive.join(" "), | |
rules[i].dead.slice("#"==rules[i].dead[0]), | |
rules[i].alive.slice("#"==rules[i].alive[0]), | |
//vgol.compressHex(rules[i].dead).join(""), | |
//vgol.compressHex(rules[i].alive).join(""), | |
+rules[i].random, | |
rules[i].birthProb, | |
rules[i].surviveProb | |
].join("/") + ";"; | |
} | |
vgolc += grid.length + "," + grid[0].length+";"; | |
for(var i=0;i<grid.length;i++){ | |
for(var j=0;j<grid.length;j++){ | |
vgolc += vgol.symbol(grid[i][j][0]); | |
end += grid[i][j][1]; | |
} | |
} | |
return vgolc + ";" + vgol.compressBinary(end); | |
} | |
vgol.decompress = function decompress(x){ | |
var i = 0; | |
while(x[i++]!==","); | |
while(x[--i]!==";"); | |
var rules = x.slice(0,i+1); | |
//return [x.slice(i).search(/;|$/),x.length]; | |
var height = x.substr(i+1,(i+=x.slice(i).search(/;|$/))-i+2); | |
var r = x.slice(i+height.length+2); | |
var width = r.slice(0,r.indexOf(";")); | |
r = r.slice(width.length+1); | |
var g = r.slice(0,r.indexOf(";")).match(RegExp(".{1,"+width+"}","g")); | |
var lives = r.slice(r.indexOf(";")+1); | |
window.a = [rules,height,width,lives,g]; | |
grid = []; | |
for(var y=0;y<Number(height);y++){ | |
grid[y] = []; | |
for(var x=0;x<Number(width);x++){ | |
grid[y][x] = [0,+lives[y][x],0]; | |
} | |
} | |
updateGraphics(); | |
} | |
vgol.numberCompress = function numberCompress(s){ | |
// remove leading zeroes | |
s = s.replace(/^0*/,""); | |
while(s.length%3) s="0"+s; | |
s = s.match(/.../g).map(y=>("0000000000"+(+y).toString(2)).slice(-10)).join(""); | |
while(s.length%8) s="0"+s; | |
return s.match(/.{1,8}/g).map(y=>String.fromCharCode(parseInt(y,2))).join(""); | |
} | |
vgol.compressBinary = function compressBinary(s){ | |
// remove leading zeroes | |
s = s.replace(/^0*/,""); | |
while(s.length%8) s="0"+s; | |
return s.match(/.{1,8}/g).map(y=>String.fromCharCode(parseInt(y,2))).join(""); | |
} | |
vgol.decompressBinary = function decompressBinary(s){ | |
return s.split("").map(t=>("00000000"+t.charCodeAt().toString(2)).slice(-8)).join(""); | |
} | |
vgol.numberDecompress = function numberDecompress(s){ | |
s = s.split("").map(t=>("00000000"+t.charCodeAt().toString(2)).slice(-8)).join(""); | |
while(s.length%10) s="0"+s; | |
return s.match(/.{1,10}/g).map(x=>parseInt(x,2)).join(""); | |
} | |
/* | |
C := [SURVIVE]/[BIRTH]/[DEADCOLOR]/[LIVECOLOR] | |
*/ | |
// grid[y][x] = [ruleNum,state,futureState] | |
//rules = [{"dead":"#000000","alive":"#FFFFFF","birth":[3],"survive":[2,3]},{"dead":"#0000a0","alive":"#80ffff","birth":[0],"survive":[8]},{"dead":"#800000","alive":"#ff0000","birth":[0],"survive":[0]}]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment