cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <!-- CODED BY valmassoi -->

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"/>

<div>
  <h1>Conway's Game of Life using ReactJS</h1>
  <div id="app"></div>
 <div class = "well">
    <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" target="_blank"><i class="fa fa-info-circle" aria-hidden="true"></i> Read about the Game of Life</a><br>
    <a href="https://www.youtube.com/watch?v=E8kUJL04ELA" target="_blank"><i class="fa fa-youtube-play" aria-hidden="true"></i> Watch John Conway explain his Game of Life</a>
   <h4>Rules:</h4>
   <ul>
      <li>Any live cell with fewer than two live neighbours dies, as if caused by under-population.</li>
      <li>Any live cell with two or three live neighbours lives on to the next generation.</li>
      <li>Any live cell with more than three live neighbours dies, as if by over-population.</li>
      <li>Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.</li>
   </ul>
 </div>
</div>
<!--
I choose to use svg, I used a 2d array then had a setItervale function that checks the output, figure out the next state of the 2d array and updates it.
-->
            
          
!
            
              $lt-grey: #E8E8E8

body
  margin: 20px
  background: grey
button
  margin: 0px 5px 5px 0px
  background: steelblue
  vertical-align: top
  padding: 5px 15px
  color: white
  text-align: center
  background: #2980b9
  border: 0
  cursor: pointer
  -webkit-box-shadow: inset 0 -2px #2475ab
  box-shadow: inset 0 -2px #2475ab
.dead
  fill: white
  // cursor:pointer why not working?
.alive
  fill: steelblue
  // stroke: white
.dieing
  fill: grey
.well
  width: 840px
  margin-top: 10px
svg
  box-shadow: 0px 0px 20px #000
a
  color: steelblue
h4
  margin-bottom: 15px
            
          
!
            
              //0 dead  //1 alive

const columns = 70, rows = 50, box=12, speed=50;
const width=box*columns, height=box*rows;
let run = 0;
class Layout extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = {
      cells: [[]],
      gen: 0,
      running: false
    }
  }
  
  // -- Init Populate -- //
  componentWillMount() {
    this.setRandos();
  }
  setRandos(){
    let twoDee = [], tempArr = [];
    for(let i=0; i<rows; i++){
      for(let j=0; j<columns; j++){
        let num = _.random(0,1);
        tempArr.push(num);
      }
      twoDee.push(tempArr);
      tempArr=[];
    }
    this.setState({ cells: twoDee, gen: 0 });
    this.Run();
  }
  
  // -- Controlls -- //
  Run() {
    if(!this.state.running){
      console.log("Run");
      this.setState({ running: true }); //gen: 0
      run = setInterval(function(){this.checkNeighbor();}.bind(this), speed);
    }
  }
  Pause() {
    if(this.state.running){
      console.log("Pause");
      clearInterval(run);
      this.setState({ running: false });
    }
  }
  Clear() {
    console.log("Clear");
    clearInterval(run);
    this.setState({ running: false });
    let twoDee = [], tempArr = [];
    for(let i=0; i<rows; i++){
      for(let j=0; j<columns; j++){
        tempArr.push(0);
      }
      twoDee.push(tempArr);
      tempArr=[];
    }
    this.setState({ cells: twoDee, gen: 0 });
  }
  
  // -- Neighbors -- //
  
  checkNeighbor(){
 //   if(this.state.running){
      let nextLife = JSON.parse(JSON.stringify(this.state.cells));//initialize nextLife  IMMUTABLE
      console.log(nextLife);
      for(let i=0; i<rows; i++){//y
        for(let j=0; j<columns; j++){//x
          this.theHood(j,i, nextLife);//not best to pass variable this way
        }
      }
 //   }
  }
  
  theHood(x,y, nextLife){
    let neighbor = 0;//reset count each iteration
    //count alive neighbors
    if(y>0 && x>0 && this.state.cells[y-1][x-1]===1){neighbor++;};//TL    // check for edges
    if(y>0 && this.state.cells[y-1][x]===1){neighbor++;};//TM
    if(y>0 && x+1<columns && this.state.cells[y-1][x+1]===1){neighbor++;};//TR
    
    if(x>0 && this.state.cells[y][x-1]===1){neighbor++;};//L
    if(x+1<columns && this.state.cells[y][x+1]===1){neighbor++;};//R
    
    if(y+1<rows && x>0 && this.state.cells[y+1][x-1]===1){neighbor++;};//BL
    if(y+1<rows && this.state.cells[y+1][x]===1){neighbor++;};//BM
    if(y+1<rows && x+1<columns && this.state.cells[y+1][x+1]===1){neighbor++;};//BR
    
    //check rules
    if (this.state.cells[y][x] === 1){//alive rules
      if (neighbor <2){
        //dies
        nextLife[y][x]=0;
      }
      if (neighbor === 2 || neighbor === 3){
        //lives
        nextLife[y][x]=1;
      }
      if (neighbor > 3){
        //dies
        nextLife[y][x]=0;
      }
    }
    else{
      if (neighbor === 3){
        //becomes alive
        nextLife[y][x]=1;
      }
    }
    if(x==columns-1 && y==rows-1){
      console.log("go to next Gen");
      this.setState({ cells: nextLife, gen: ++this.state.gen});
    }//update state after last
  }
  
  manual(x, y){
    console.log(x,y);
    let tempArr = this.state.cells;
    (tempArr[y][x])===0 ? tempArr[y][x]=1 : tempArr[y][x]=0;
    this.setState({ cells: tempArr });
  }
  render() {
    return (
      <div>
        <button onClick={this.Run.bind(this)}>Run</button>
        <button onClick={this.Pause.bind(this)}>Pause</button>
        <button onClick={this.Clear.bind(this)}>Clear</button>
        <button onClick={this.setRandos.bind(this)}>New Random</button>
        <h4>Generation: {this.state.gen}</h4>

         <svg width={width} height={height}>
          {this.state.cells.map(function(row, y) {
            return row.map(function(life, x) {
              return (
                <rect key={`${x},${y}`} x={x*box} y={y*box} width={box} height={box} className={(life===1) ? 'alive':'dead'} stroke='grey' strokeWidth={.25} onClick={this.manual.bind(this, x, y)}/>
              );
            }.bind(this))
          }.bind(this))}
        </svg>
      </div>
    );
  }
}

const app = document.getElementById('app');
ReactDOM.render(<Layout/>, app);

            
          
!
999px
Loading ..................

Console