Skip to content

Instantly share code, notes, and snippets.

@ConorOBrien-Foxx
Created May 27, 2016 20:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ConorOBrien-Foxx/1f819ec2ce33b0cd5cc1dad621f62c02 to your computer and use it in GitHub Desktop.
Save ConorOBrien-Foxx/1f819ec2ce33b0cd5cc1dad621f62c02 to your computer and use it in GitHub Desktop.
an extension for variations of game of life
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