A Pen by Juan Ferreyra on CodePen.
Last active
September 11, 2016 03:40
-
-
Save juanlet/fb9794b2fb62a7d14a2a170a03be8abd to your computer and use it in GitHub Desktop.
zKvzBY
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
<div id="container" class="container text-center"> | |
</div> |
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
class Header extends React.Component { | |
render(){ | |
return ( <h1 className="title text-center">The Game Of Life</h1>); | |
} | |
} | |
class Cell extends React.Component { | |
toggleState(){ | |
const i=this.props.row; | |
const j=this.props.column; | |
this.props.changeCellHandler(i,j); | |
} | |
render(){ | |
var style="cell"; | |
if(this.props.alive){ | |
style+=" alive"; | |
} | |
return ( <div className={style} id={this.props.id} onClick={this.toggleState.bind(this)}></div>); | |
} | |
} | |
class Board extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {lifeStateMatrix:[],boardWidth:50,boardHeight:30,simulationIsRunning:false, generationNumber: 0}; | |
} | |
componentWillMount(){ | |
this.setBoardSizeAndStatusMatrix(70,50); | |
} | |
//add all the neighbours of a position to an Array to check later how many neighbours the position has | |
applyLifeRules(i,j){ | |
const minX=0, minY=0,maxX=this.state.boardWidth,maxY=this.state.boardHeight; | |
let totalLiveNeighbours=0; | |
let currentStatusMatrix=this.state.lifeStateMatrix; | |
//check for limits | |
const topLeft= i-1 >=minX && j-1>=minY; | |
const topMiddle= j-1>=minY; | |
const topRight= i+1<maxX && j-1>=minY; | |
const right=i+1<maxX; | |
const bottomRight= i+1<maxX && j+1<maxY; | |
const bottomMiddle= j+1<maxY; | |
const bottomLeft= i-1>=minX && j+1<maxY; | |
const left= i-1>=minX; | |
//addPairs if they are within the limits of the matrix | |
if(topLeft){ | |
if(currentStatusMatrix[i-1][j-1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(topMiddle){ | |
if(currentStatusMatrix[i][j-1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(topRight){ | |
if(currentStatusMatrix[i+1][j-1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(right){ | |
if(currentStatusMatrix[i+1][j]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(bottomRight){ | |
if(currentStatusMatrix[i+1][j+1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(bottomMiddle){ | |
if(currentStatusMatrix[i][j+1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(bottomLeft){ | |
if(currentStatusMatrix[i-1][j+1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(left){ | |
if(currentStatusMatrix[i-1]){ | |
totalLiveNeighbours+=1; | |
} | |
} | |
if(totalLiveNeighbours>0 && i==0 && j==1){ | |
console.log('totalNeib',totalLiveNeighbours,"left",left,"topLeft",topLeft,"topMiddle",topMiddle,"topRight",topRight,"right",right,"bottomright",bottomRight,"bottomMiddle",bottomMiddle,"bottomLeft",bottomLeft); | |
} | |
if(i===0 && j===0){ | |
console.log(totalLiveNeighbours); | |
} | |
if(currentStatusMatrix[i][j] && totalLiveNeighbours < 2){ | |
//underpopulation. cell dies | |
return false; | |
}else if(currentStatusMatrix[i][j] && totalLiveNeighbours>3){ | |
//overpopulation. cell dies | |
return false; | |
}else if(currentStatusMatrix[i][j] && currentStatusMatrix[i][j]>=2 && currentStatusMatrix[i][j]<=3){ | |
return true; | |
}else if(!currentStatusMatrix[i][j] && totalLiveNeighbours===3){ | |
//a new cell is born | |
return true; | |
}else{ | |
return false | |
} | |
} | |
changeCell(i,j){ | |
//put the cell as alive and add the pairs that have the cell as the neighbour if the simulation is not running | |
let newArray=this.state.lifeStateMatrix; | |
newArray[i][j]= !this.state.lifeStateMatrix[i][j]; | |
this.setState({ lifeStateMatrix: newArray}); | |
} | |
moveToNextGeneration(){ | |
let nextGenMatrix=[] | |
console.log("maxX",this.state.boardWidth,"maxY",this.state.boardHeight); | |
for(let i=0,maxX=this.state.boardWidth; i<maxX ;i++){ | |
let nextGenRow=[]; | |
for(let j=0,maxY=this.state.boardHeight; j<maxY;j++){ | |
nextGenRow.push(this.applyLifeRules(i,j)); | |
} | |
nextGenMatrix.push(nextGenRow); | |
} | |
this.setState({ lifeStateMatrix: nextGenMatrix}); | |
} | |
setBoardSizeAndStatusMatrix(x,y){ | |
let lifeStateMatrix=[]; | |
for(let i=0,len=x;i<len;i++){ | |
let rowStatus=[]; | |
for(let j=0,len=y;j<len;j++){ | |
rowStatus.push(false); | |
} | |
lifeStateMatrix.push(rowStatus); | |
} | |
this.setState({ lifeStateMatrix: lifeStateMatrix, boardWidth: x, boardHeight: y}); | |
} | |
start(){ | |
this.setState({ simulationIsRunning:true},()=>{ | |
}); | |
this.moveToNextGeneration(); | |
} | |
pause(){ | |
this.setState({ simulationIsRunning:false}); | |
} | |
clear(x,y){ | |
this.setState({ simulationIsRunning:false}); | |
this.setState({lifeStateMatrix: []}); | |
this.setBoardSizeAndStatusMatrix(x,y); | |
} | |
render(){ | |
let generatedId=0, cellsRenderMatrix=[], x= this.state.boardWidth, y= this.state.boardHeight; | |
let clickableState; | |
if(this.state.simulationIsRunning){ | |
clickableState=" none" | |
}else{ | |
clickableState=" auto" | |
} | |
for(let i=0,len=x;i<len;i++){ | |
let rowRender=[]; | |
for(let j=0,len=y;j<len;j++){ | |
rowRender.push(<Cell id={generatedId} | |
changeCellHandler={this.changeCell.bind(this)} row={i} column={j} | |
alive={this.state.lifeStateMatrix[i][j]} />); generatedId++; | |
} | |
cellsRenderMatrix.push(rowRender); | |
} | |
return ( | |
<div className="holder well"> | |
<Header /> | |
<div className="topButtons"> | |
<button className="run btn gridPicker" onClick={this.start.bind(this)}>Run</button> | |
<button className="pause btn gridPicker" onClick={this.pause.bind(this)}>Pause</button> | |
<button className="clear btn gridPicker" onClick={this.clear.bind(this,x,y)}>Clear</button> | |
<span id="generation">Generation: {this.state.generationNumber}</span> | |
</div> | |
<div className="board" style={{width: (y*10)+"px", pointerEvents: clickableState}}> | |
{cellsRenderMatrix} | |
</div> | |
<div className="bottomButtons"> | |
<button className="fiftyThirty btn gridPicker" onClick={this.setBoardSizeAndStatusMatrix.bind(this,50,30)}>50x30</button> | |
<button className="fiftyThirty btn gridPicker" onClick={this.setBoardSizeAndStatusMatrix.bind(this,70,50)}>70x50</button> | |
<button className="fiftyThirty btn gridPicker" onClick={this.setBoardSizeAndStatusMatrix.bind(this,100,80)}>100x80</button> | |
</div> | |
</div>); | |
} | |
} | |
ReactDOM.render( | |
<Board />, | |
document.getElementById('container') | |
); |
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
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.js"></script> |
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
body | |
background-color: #455A64 | |
box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22) | |
.holder | |
background-color: #607D8B | |
border: none | |
font-family: 'Black Ops One', cursive | |
margin: 0 auto | |
box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22) | |
.topButtons | |
margin-bottom: 1% | |
.bottomButtons | |
margin-top: 1% | |
.gridPicker | |
margin: 1% | |
.title | |
color: white | |
margin-top: 2% | |
margin-bottom: 2% | |
font-size: 3em | |
text-shadow: 2px 2px #000 | |
.board | |
background-color: grey | |
overflow: hidden | |
margin: 0 auto | |
//pointer-events: none | |
.cell | |
background-color: #303F9F | |
width: 10px | |
height: 10px | |
border: 1px solid green | |
float: left | |
.alive | |
background-color: red | |
#generation | |
margin-left: 2% | |
font-size: 2em |
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
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> | |
<link href="https://fonts.googleapis.com/css?family=Black+Ops+One" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment