The Game Of Life

In this example below you will see how to do a The Game Of Life with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by captnstarburst, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright captnstarburst ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>The Game Of Life</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://fonts.googleapis.com/css?family=Risque" rel="stylesheet">
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css'>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <div id="root"></div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/captnstarburst/the-game-of-life-KZNWjd */
body {
  background: #2D383A;
}

.top-row {
  padding-top: 5%;
}

.header {
  font-family: "Risque", cursive;
  color: #C8C8CD;
  text-shadow: 5px 5px 1px black;
  font-size: 3em;
}

.cell-sm {
  width: 5px;
  height: 5px;
  border-top: 1px solid black;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
  display: inline-block;
  float: left;
  background: white;
}

.cell-md {
  width: 10px;
  height: 10px;
  border-top: 1px solid black;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
  display: inline-block;
  float: left;
  background: white;
}

.cell-lg {
  width: 15px;
  height: 15px;
  border-top: 1px solid black;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
  display: inline-block;
  float: left;
  background: white;
}

.board {
  width: 650px;
  height: 350px;
  background: white;
  margin: auto;
}

.btn-row {
  padding-top: 1%;
}

.fa {
  color: black;
  font-size: 1em;
}

.alive-new {
  background: blue;
}

.alive-old {
  background: purple;
}

.small {
  font-size: 1.5em;
}

button {
  margin: .1%;
}

.btn-custom {
  background: #2D383A;
  border: 2px solid white;
  color: white;
}

.btn-custom:hover {
  background: black;
}

.active {
  background: black;
}

.btn {
  cursor: pointer;
}

.counter-bg {
  position: fixed;
  top: 0;
  right: 50px;
  width: 5%;
}
.counter-bg p {
  text-align: center;
  text-decoration: underline;
}

.footer-row {
  padding-top: 5%;
}


/*Downloaded from https://www.codeseek.co/captnstarburst/the-game-of-life-KZNWjd */
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Header = function Header() {
  return React.createElement(
    "div",
    { className: "row top-row" },
    React.createElement(
      "div",
      { className: "col text-center" },
      React.createElement(
        "h1",
        { className: "header" },
        "The Game Of Life"
      ),
      React.createElement(
        "p",
        { className: "header small" },
        React.createElement(
          "small",
          null,
          "Add cells while playing or clear the board and set up your own game"
        )
      )
    )
  );
};

var Footer = function Footer() {
  return React.createElement(
    "div",
    { className: "row footer-row" },
    React.createElement(
      "div",
      { className: "col text-center" },
      React.createElement(
        "a",
        { href: "https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life", target: "_blank" },
        "Learn More"
      )
    )
  );
};

var Counter = function (_React$Component) {
  _inherits(Counter, _React$Component);

  function Counter() {
    _classCallCheck(this, Counter);

    return _possibleConstructorReturn(this, (Counter.__proto__ || Object.getPrototypeOf(Counter)).apply(this, arguments));
  }

  _createClass(Counter, [{
    key: "render",
    value: function render() {
      return React.createElement(
        "div",
        { className: "counter-bg" },
        React.createElement(
          "p",
          { className: "header" },
          React.createElement(
            "small",
            null,
            this.props.generation
          )
        )
      );
    }
  }]);

  return Counter;
}(React.Component);

var ControlButtons = function (_React$Component2) {
  _inherits(ControlButtons, _React$Component2);

  function ControlButtons() {
    _classCallCheck(this, ControlButtons);

    return _possibleConstructorReturn(this, (ControlButtons.__proto__ || Object.getPrototypeOf(ControlButtons)).apply(this, arguments));
  }

  _createClass(ControlButtons, [{
    key: "render",
    value: function render() {
      return React.createElement(
        "div",
        { className: "row" },
        React.createElement(
          "div",
          { className: "col text-center" },
          React.createElement(
            "button",
            { className: "btn btn-primary disabled", onClick: this.props.play },
            "Play ",
            React.createElement("i", { className: "fa fa-play-circle-o", "aria-hidden": "true" })
          ),
          React.createElement(
            "button",
            { className: "btn btn-warning", onClick: this.props.pause },
            "Pause ",
            React.createElement("i", { className: "fa fa-pause-circle-o", "aria-hidden": "true" })
          ),
          React.createElement(
            "button",
            { className: "btn btn-danger", onClick: this.props.clear },
            "Clear",
            React.createElement("i", { className: "fa fa-window-close-o", "aria-hidden": "true" })
          )
        )
      );
    }
  }]);

  return ControlButtons;
}(React.Component);

var GameBoard = function (_React$Component3) {
  _inherits(GameBoard, _React$Component3);

  function GameBoard(props) {
    _classCallCheck(this, GameBoard);

    var _this3 = _possibleConstructorReturn(this, (GameBoard.__proto__ || Object.getPrototypeOf(GameBoard)).call(this, props));

    _this3.state = {
      boardArr: [],
      previous: _this3.props.generation
    };
    return _this3;
  }

  _createClass(GameBoard, [{
    key: "seedBoard",
    value: function seedBoard(totalCells) {

      var board = [];

      if (this.props.clear) {
        for (var i = 0; i < totalCells; i++) {
          board.push(0);
        }
        this.setState({
          boardArr: board
        });
      } else {
        for (var _i = 0; _i < totalCells; _i++) {
          board.push(this.randomNumberSetter());
        }

        this.setState({
          boardArr: board
        });

        this.props.play();
      }
    }
  }, {
    key: "randomNumberSetter",
    value: function randomNumberSetter() {
      var dObj = new Date();

      var milli = dObj.getTime().toString();

      var max = parseInt(milli.slice(7));

      var num1 = parseInt(milli.slice(9, 11));

      var num2 = parseInt(milli.slice(11));

      var rng = Math.floor(Math.random() * (max - 0) + 0);

      if (rng % num1 === 0 || rng % num2 === 0 || rng % 5 === 0) {
        return 1;
      } else {
        return 0;
      }
    }
  }, {
    key: "onCellClick",
    value: function onCellClick(e) {
      var catagories = e.target.className.split(" ");

      if (catagories.length !== 2) {
        var board = this.state.boardArr;
        board[e.target.id] = 1;
        this.setState({
          boardArr: board
        });
      }
    }
  }, {
    key: "game",
    value: function game() {
      var board = this.state.boardArr.slice();
      var updatedBoard = [];
      var width = void 0;
      var height = void 0;
      var corners = [0];

      if (this.props.size === "sm") {
        width = 43;
        height = 23;
      } else if (this.props.size === "md") {
        width = 65;
        height = 35;
      } else {
        width = 130;
        height = 70;
      }

      corners.push(width - 1);
      corners.push((height - 1) * width);
      corners.push(height * width - 1);

      for (var i = 0; i < board.length; i++) {
        // console.log(boi);
        var neighbors = 0;

        //Corners
        if (corners.includes(i)) {
          if (i === corners[0]) {
            if (board[i + width - 1]) {
              neighbors++;
            }
            if (board[i + 1]) {
              neighbors++;
            }
            if (board[width * height - 1]) {
              neighbors++;
            }
            if (board[width * height - (Math.abs(i - width) - 1)]) {
              neighbors++;
            }
            if (board[width + width - 1]) {
              neighbors++;
            }
            if (board[width + 1]) {
              neighbors++;
            }
            if (board[width * height - width]) {
              neighbors++;
            }
            if (board[width]) {
              neighbors++;
            }
          } else if (i === corners[1]) {
            if (board[i - 1]) {
              neighbors++;
            }
            if (board[i - width + 1]) {
              neighbors++;
            }
            if (board[width * height - (Math.abs(i - width) + 1)]) {
              neighbors++;
            }
            if (board[width * height - i - 1]) {
              neighbors++;
            }
            if (board[i + width - 1]) {
              neighbors++;
            }
            if (board[i + 1]) {
              neighbors++;
            }
            if (board[width * height - 1]) {
              neighbors++;
            }
            if (board[i + width]) {
              neighbors++;
            }
          } else if (i === corners[2]) {
            if (board[i + width - 1]) {
              neighbors++;
            }
            if (board[i + 1]) {
              neighbors++;
            }
            if (board[i - 1]) {
              neighbors++;
            }
            if (board[i - width + 1]) {
              neighbors++;
            }
            if (board[width * height - i - 1]) {
              neighbors++;
            }
            if (board[i - i + 1]) {
              neighbors++;
            }
            if (board[i - width]) {
              neighbors++;
            }
            if (board[i - i]) {
              neighbors++;
            }
          } else {
            if (board[i - 1]) {
              neighbors++;
            }
            if (board[i - width + 1]) {
              neighbors++;
            }
            if (board[i - width - 1]) {
              neighbors++;
            }
            if (board[i - width - width + 1]) {
              neighbors++;
            }
            if (board[i - i + width - 2]) {
              neighbors++;
            }
            if (board[i - i]) {
              neighbors++;
            }
            if (board[i - width]) {
              neighbors++;
            }
            if (board[i - i + width - 1]) {
              neighbors++;
            }
          }
        }
        //Top
        else if (i > 0 && i < width - 1) {
            if (board[i - 1]) {
              neighbors++;
            }
            if (board[i + 1]) {
              neighbors++;
            }
            if (board[width * height - (Math.abs(i - width) - 1)]) {
              neighbors++;
            }
            if (board[width * height - (Math.abs(i - width) + 1)]) {
              neighbors++;
            }
            if (board[i + width - 1]) {
              neighbors++;
            }
            if (board[i + width + 1]) {
              neighbors++;
            }
            if (board[width * height - Math.abs(i - width)]) {
              neighbors++;
            }
            if (board[i + width]) {
              neighbors++;
            }
          }
          //Bottom
          else if (i > (height - 1) * width && i < width * height - 1) {
              if (board[i - 1]) {
                neighbors++;
              }
              if (board[i + 1]) {
                neighbors++;
              }
              if (board[i - width - 1]) {
                neighbors++;
              }
              if (board[i - width + 1]) {
                neighbors++;
              }
              if (board[height - 1 * width - 1]) {
                neighbors++;
              }
              if (board[height - 1 * width + 1]) {
                neighbors++;
              }
              if (board[height - 1 * width]) {
                neighbors++;
              }
              if (board[i - width]) {
                neighbors++;
              }
            }
            //Left Side
            else if (i % width === 0) {
                if (board[i + width - 1]) {
                  neighbors++;
                }
                if (board[i + 1]) {
                  neighbors++;
                }
                if (board[i - 1]) {
                  neighbors++;
                }
                if (board[i - width + 1]) {
                  neighbors++;
                }
                if (board[i + width + width - 1]) {
                  neighbors++;
                }
                if (board[i + width + 1]) {
                  neighbors++;
                }
                if (board[i - width]) {
                  neighbors++;
                }
                if (board[i + width]) {
                  neighbors++;
                }
              }
              //Right Side
              else if (i % width - 1 === 0) {
                  if (board[i - 1]) {
                    neighbors++;
                  }
                  if (board[i - width + 1]) {
                    neighbors++;
                  }
                  if (board[i - width - 1]) {
                    neighbors++;
                  }
                  if (board[i - width - width + 1]) {
                    neighbors++;
                  }
                  if (board[i + width - 1]) {
                    neighbors++;
                  }
                  if (board[i + 1]) {
                    neighbors++;
                  }
                  if (board[i - width]) {
                    neighbors++;
                  }
                  if (board[i + width]) {
                    neighbors++;
                  }
                } else {
                  if (board[i - 1]) {
                    neighbors++;
                  }
                  if (board[i + 1]) {
                    neighbors++;
                  }
                  if (board[i - width - 1]) {
                    neighbors++;
                  }
                  if (board[i - width + 1]) {
                    neighbors++;
                  }
                  if (board[i + width - 1]) {
                    neighbors++;
                  }
                  if (board[i + width + 1]) {
                    neighbors++;
                  }
                  if (board[i - width]) {
                    neighbors++;
                  }
                  if (board[i + width]) {
                    neighbors++;
                  }
                }

        if (neighbors === 2) {
          updatedBoard.push(board[i]);
        } else if (neighbors === 3) {
          updatedBoard.push(1);
        } else {
          updatedBoard.push(0);
        }
      }

      this.setState({
        boardArr: updatedBoard
      });
    }
  }, {
    key: "render",
    value: function render() {
      if (this.props.shouldGenerate) {
        // console.log(this.props.size);
        this.setState({
          boardArr: []
        });

        if (this.props.size === "sm") {
          this.seedBoard(989);
        } else if (this.props.size === "md") {
          this.seedBoard(2275);
        } else if (this.props.size === "lg") {
          this.seedBoard(9100);
        }
        this.props.hasGenerated();
      }

      if (this.props.generation !== this.state.previous && this.props.shouldPlay) {

        this.game();
        this.setState({
          previous: this.props.generation
        });
      }

      var list = this.state.boardArr.map(function (key, i) {
        // console.log(this.props.size);
        if (key) {
          if (this.props.size === "sm") {
            return React.createElement("div", {
              className: "cell-lg alive-new",
              id: i,
              onClick: this.onCellClick.bind(this)
            });
          } else if (this.props.size === "md") {
            return React.createElement("div", {
              className: "cell-md alive-new",
              id: i,
              onClick: this.onCellClick.bind(this)
            });
          } else if (this.props.size === "lg") {
            return React.createElement("div", {
              className: "cell-sm alive-new",
              id: i,
              onClick: this.onCellClick.bind(this)
            });
          }
        } else {
          if (this.props.size === "sm") {
            return React.createElement("div", {
              className: "cell-lg",
              id: i,
              onClick: this.onCellClick.bind(this)
            });
          } else if (this.props.size === "md") {
            return React.createElement("div", {
              className: "cell-md",
              id: i,
              onClick: this.onCellClick.bind(this)
            });
          } else if (this.props.size === "lg") {
            return React.createElement("div", {
              className: "cell-sm",
              id: i,
              onClick: this.onCellClick.bind(this)
            });
          }
        }
      }.bind(this));

      return React.createElement(
        "div",
        { className: "justify-content-center" },
        React.createElement(
          "div",
          { className: "board" },
          list
        )
      );
    }
  }]);

  return GameBoard;
}(React.Component);

var BoardButtons = function (_React$Component4) {
  _inherits(BoardButtons, _React$Component4);

  function BoardButtons() {
    _classCallCheck(this, BoardButtons);

    var _this4 = _possibleConstructorReturn(this, (BoardButtons.__proto__ || Object.getPrototypeOf(BoardButtons)).call(this));

    _this4.state = {
      button1IsActive: false,
      button2IsActive: true,
      button3IsActive: false
    };
    return _this4;
  }

  _createClass(BoardButtons, [{
    key: "onBoardSizeButton",
    value: function onBoardSizeButton(e) {
      var id = e.target.id;
      var intId = parseInt(id.slice(5));

      if (this.state.button1IsActive) {
        switch (intId) {
          case 2:
            this.setState({
              button1IsActive: !this.state.button1IsActive,
              button2IsActive: true
            });
            this.props.boardSizeChange(intId);
            break;
          case 3:
            this.setState({
              button1IsActive: !this.state.button1IsActive,
              button3IsActive: true
            });
            this.props.boardSizeChange(intId);
            break;
        }
      } else if (this.state.button2IsActive) {
        switch (intId) {
          case 1:
            this.setState({
              button2IsActive: !this.state.button2IsActive,
              button1IsActive: true
            });
            this.props.boardSizeChange(intId);
            break;
          case 3:
            this.setState({
              button2IsActive: !this.state.button2IsActive,
              button3IsActive: true
            });
            this.props.boardSizeChange(intId);
            break;
        }
      } else if (this.state.button3IsActive) {
        switch (intId) {
          case 1:
            this.setState({
              button3IsActive: !this.state.button3IsActive,
              button1IsActive: true
            });
            this.props.boardSizeChange(intId);
            break;
          case 2:
            this.setState({
              button3IsActive: !this.state.button3IsActive,
              button2IsActive: true
            });
            this.props.boardSizeChange(intId);
            break;
        }
      }
    }
  }, {
    key: "render",
    value: function render() {
      var buttons = void 0;
      if (this.state.button1IsActive) {
        buttons = React.createElement(
          "div",
          { className: "col text-center" },
          React.createElement(
            "button",
            {
              className: "btn btn-custom active",
              id: "size_1",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "43 X 23"
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-custom ",
              id: "size_2",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "65 X 35"
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-custom",
              id: "size_3",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "130 X 70"
          )
        );
      } else if (this.state.button2IsActive) {
        buttons = React.createElement(
          "div",
          { className: "col text-center" },
          React.createElement(
            "button",
            {
              className: "btn btn-custom ",
              id: "size_1",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "43 X 23"
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-custom active",
              id: "size_2",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "65 X 35"
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-custom",
              id: "size_3",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "130 X 70"
          )
        );
      } else if (this.state.button3IsActive) {
        buttons = React.createElement(
          "div",
          { className: "col text-center" },
          React.createElement(
            "button",
            {
              className: "btn btn-custom ",
              id: "size_1",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "43 X 23"
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-custom ",
              id: "size_2",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "65 X 35"
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-custom active",
              id: "size_3",
              onClick: this.onBoardSizeButton.bind(this)
            },
            "130 X 70"
          )
        );
      }

      return React.createElement(
        "div",
        { className: "row" },
        buttons
      );
    }
  }]);

  return BoardButtons;
}(React.Component);

var App = function (_React$Component5) {
  _inherits(App, _React$Component5);

  function App() {
    _classCallCheck(this, App);

    var _this5 = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this));

    _this5.state = {
      generation: 1,
      newBoard: true,
      boardSize: "md",
      play: true,
      clear: false,
      intervalId: ""
    };
    return _this5;
  }

  _createClass(App, [{
    key: "tick",
    value: function tick() {
      this.setState({
        generation: ++this.state.generation
      });
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      var intervalId = setInterval(this.tick.bind(this), 100);
      this.setState({
        intervalId: intervalId,
        play: true
      });
    }
  }, {
    key: "newBoardShouldGenerate",
    value: function newBoardShouldGenerate() {
      this.setState({
        newBoard: true,
        generation: 1
      });
    }
  }, {
    key: "onNewBoardGenerated",
    value: function onNewBoardGenerated() {
      // this.onPlay();
      this.setState({
        newBoard: false,
        clear: false
      });
      // this.onPlay();
    }
  }, {
    key: "onBoardSizeChange",
    value: function onBoardSizeChange(input) {
      this.onPause();
      switch (input) {
        case 1:
          this.setState({
            boardSize: "sm"
          });
          break;
        case 2:
          this.setState({
            boardSize: "md"
          });
          break;
        case 3:
          this.setState({
            boardSize: "lg"
          });
          break;
      }
      this.newBoardShouldGenerate();
    }
  }, {
    key: "onPause",
    value: function onPause() {
      if (this.state.play) {
        this.setState({
          play: false
        });
        clearInterval(this.state.intervalId);
      }
    }
  }, {
    key: "onPlay",
    value: function onPlay() {

      if (!this.state.play) {

        var intervalId = setInterval(this.tick.bind(this), 100);
        this.setState({
          intervalId: intervalId,
          play: true
        });
      }
    }
  }, {
    key: "onClear",
    value: function onClear() {
      this.onPause();
      this.setState({
        clear: true
      });
      this.newBoardShouldGenerate();
    }
  }, {
    key: "render",
    value: function render() {
      return React.createElement(
        "div",
        null,
        React.createElement(
          "div",
          { className: "container-fluid" },
          React.createElement(Counter, { generation: this.state.generation }),
          React.createElement(Header, null),
          React.createElement(ControlButtons, {
            pause: this.onPause.bind(this),
            play: this.onPlay.bind(this),
            clear: this.onClear.bind(this)
          })
        ),
        React.createElement(GameBoard, {
          size: this.state.boardSize,
          shouldGenerate: this.state.newBoard,
          hasGenerated: this.onNewBoardGenerated.bind(this),
          generation: this.state.generation,
          shouldPlay: this.state.play,
          play: this.onPlay.bind(this),
          clear: this.state.clear
        }),
        React.createElement(
          "div",
          { className: "container-fluid" },
          React.createElement(BoardButtons, { boardSizeChange: this.onBoardSizeChange.bind(this) }),
          React.createElement(Footer, null)
        )
      );
    }
  }]);

  return App;
}(React.Component);

ReactDOM.render(React.createElement(App, null), document.querySelector("#root"));

Comments