/*Downloaded from https://www.codeseek.co/0damian/game-of-life-pEqWRv */
var GameOfLife = React.createClass({
displayName: 'GameOfLife',
getInitialState: function getInitialState() {
return {
width: Number(this.props.width),
interval: 250,
count: 0,
active: false
};
},
componentWillMount: function componentWillMount() {
this.setState({
gridArray: this.makeGridArray(this.props.width)
});
},
makeGridArray: function makeGridArray(width) {
var maxX = width,
maxY = width - 30,
max = maxX * maxY,
gridArray = [],
i,
j,
cell,
neighbours;
for (i = 1; i <= maxY; i++) {
for (j = 1; j <= maxX; j++) {
var neighbours = this.getNeighbours([j, i]);
cell = {
x: j,
y: i,
status: 'dead',
neighbours: neighbours
};
gridArray.push(cell);
}
}
var seed = seedArray.sort();
for (var k = 0; k < gridArray.length; k++) {
if (seed.indexOf(k) > -1) {
gridArray[k].status = 'newborn';
seed.shift();
}
}
return gridArray;
},
getNeighbours: function getNeighbours(arr) {
var x = arr[0],
y = arr[1],
output;
output = [{ x: x, y: y - 1 }, { x: x + 1, y: y - 1 }, { x: x + 1, y: y }, { x: x + 1, y: y + 1 }, { x: x, y: y + 1 }, { x: x - 1, y: y + 1 }, { x: x - 1, y: y }, { x: x - 1, y: y - 1 }];
for (var i = 0; i < 8; i++) {
if (!output[i].x) output[i].x = this.state.width;
if (output[i].x > this.state.width) output[i].x = 1;
if (!output[i].y) output[i].y = this.state.width - 30;
if (output[i].y > this.state.width - 30) output[i].y = 1;
}
return output;
},
playPauseGame: function playPauseGame(e) {
e.preventDefault();
if (e.target.value == 'play') {
this.setState({
active: true
});
this.cycle = setInterval(this.cycleLife, this.state.interval);
} else {
clearInterval(this.cycle);
this.setState({
active: false
});
}
},
clearGame: function clearGame(e) {
e.preventDefault();
this.setState({
gridArray: this.makeGridArray(this.state.width),
count: 0
});
},
resizeGrid: function resizeGrid(e) {
e.preventDefault();
var newWidth = Number(e.target.name);
if (this.state.width != newWidth) {
this.setState({
width: Number(e.target.name),
gridArray: this.makeGridArray(newWidth)
});
}
},
setInterval: function setInterval(e) {
e.preventDefault();
if (this.state.interval != Number(e.target.name)) {
this.setState({
interval: e.target.name
});
}
},
handleCellClick: function handleCellClick(data) {
var newGrid = this.state.gridArray;
for (var k = 0; k < newGrid.length; k++) {
if (newGrid[k].x == data.x && newGrid[k].y == data.y) {
newGrid[k].status == 'dead' ? newGrid[k].status = 'newborn' : newGrid[k].status = 'dead';
this.setState({
gridArray: newGrid
});
break;
}
}
},
cycleLife: function cycleLife() {
var grid = this.state.gridArray,
toBirth = [],
toKill = [],
toMature = [];
for (var l = 0; l < grid.length; l++) {
var livingNeighbours = 0;
for (var m = 0; m < grid[l].neighbours.length; m++) {
var arrIndex = (grid[l].neighbours[m].y - 1) * this.state.width + grid[l].neighbours[m].x - 1;
if (grid[arrIndex].status != 'dead') livingNeighbours++;
}
if (grid[l].status == 'dead' && livingNeighbours == 3) toBirth.push(l);else if (grid[l].status != 'dead') {
if (livingNeighbours < 2 || livingNeighbours > 3) toKill.push(l);else toMature.push(l);
}
}
toBirth.map(function (cell) {
grid[cell].status = 'newborn';
});
toKill.map(function (cell) {
grid[cell].status = 'dead';
});
toMature.map(function (cell) {
grid[cell].status = 'mature';
});
var count = this.state.count;
this.setState({
gridArray: grid,
count: count + 1
});
},
render: function render() {
var cells = this.state.gridArray.map(function (cell) {
return React.createElement(Cell, {
x: cell.x,
y: cell.y,
status: cell.status,
neighbours: cell.neighbours,
gridWidth: this.state.width,
onCellClick: this.handleCellClick
});
}, this);
return React.createElement(
'main',
null,
React.createElement(
'h1',
null,
'Game of Life'
),
React.createElement(
'div',
{ className: 'ctrl ctrl-one' },
React.createElement('input', {
type: 'button',
className: this.state.active ? 'active' : '',
alt: 'play',
value: this.state.active ? "pause" : "play",
onClick: this.playPauseGame
}),
React.createElement('input', {
type: 'button',
value: 'clear',
disabled: this.state.active,
onClick: this.clearGame
})
),
React.createElement(
'div',
{ className: 'explain' },
React.createElement(
'svg',
{ viewBox: '0 0 10 10' },
React.createElement('circle', {
cx: '5',
cy: '5',
r: '5',
fill: '#b5b5b5'
})
),
React.createElement(
'span',
null,
'dead'
),
React.createElement(
'svg',
{ viewBox: '0 0 10 10' },
React.createElement('circle', {
cx: '5',
cy: '5',
r: '5',
fill: 'royalblue'
})
),
React.createElement(
'span',
null,
'newborn'
),
React.createElement(
'svg',
{ viewBox: '0 0 10 10' },
React.createElement('circle', {
cx: '5',
cy: '5',
r: '5',
fill: 'orangered'
})
),
React.createElement(
'span',
null,
'mature'
),
React.createElement(
'p',
{
style: { textAlign: 'center' }
},
'life cycle: ' + this.state.count
)
),
React.createElement(
'div',
{ className: 'grid' },
cells
),
React.createElement(
'div',
{ className: 'ctrl ctrl-two' },
React.createElement(
'h2',
null,
'grid'
),
React.createElement('input', {
type: 'button',
value: 'small',
name: '50',
onClick: this.resizeGrid
}),
React.createElement('input', {
type: 'button',
value: 'medium',
name: '70',
onClick: this.resizeGrid
}),
React.createElement('input', {
type: 'button',
value: 'large',
name: '90',
onClick: this.resizeGrid
})
),
React.createElement(
'div',
{ className: 'ctrl ctrl-two' },
React.createElement(
'h2',
null,
'speed'
),
React.createElement('input', {
type: 'button',
value: 'slow',
name: '1000',
disabled: this.state.active,
onClick: this.setInterval
}),
React.createElement('input', {
type: 'button',
value: 'medium',
name: '250',
disabled: this.state.active,
onClick: this.setInterval
}),
React.createElement('input', {
type: 'button',
value: 'fast',
name: '100',
disabled: this.state.active,
onClick: this.setInterval
})
),
React.createElement(
'a',
{
href: 'https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life',
target: '_blank'
},
'what is this?'
)
);
}
});
var Cell = React.createClass({
displayName: 'Cell',
handleCellClick: function handleCellClick(e) {
e.preventDefault();
this.props.onCellClick({
x: this.props.x,
y: this.props.y,
neighbours: this.props.neighbours
});
},
selectFill: function selectFill() {
if (this.props.status == 'dead') return '#b5b5b5';else if (this.props.status == 'newborn') return 'royalblue';else return 'orangered';
},
render: function render() {
if (this.props.x == this.props.gridWidth) {
return React.createElement(
'span',
null,
React.createElement(
'svg',
{ viewBox: '0 0 10 10' },
React.createElement('circle', {
cx: '5',
cy: '5',
r: '5',
fill: this.selectFill(),
onClick: this.handleCellClick
})
),
React.createElement('br', null)
);
} else {
return React.createElement(
'svg',
{ viewBox: '0 0 10 10' },
React.createElement('circle', {
cx: '5',
cy: '5',
r: '5',
fill: this.selectFill(),
onClick: this.handleCellClick
})
);
}
}
});
var seedArray = [102, 103, 104, 353, 354, 355, 404, 405, 406, 161, 162, 163, 113, 62, 683, 684, 685, 686, 636, 586, 535, 532, 632, 141, 142, 191, 192, 243, 244, 293, 294, 956, 957, 808, 758, 757, 804, 854, 810, 861, 761, 762, 961, 962, 864, 914, 656, 657, 608, 558, 604, 554, 457, 456, 661, 662, 610, 560, 461, 462, 614, 564, 693, 694, 743, 794, 745];
ReactDOM.render(React.createElement(GameOfLife, { width: '50' }), document.getElementById('app'));