Conway's Game of Life as a React web app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Board.tsx 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import React from 'react';
  2. import Cell from './Cell';
  3. import Controls from './Controls';
  4. import { generateNewGrid, updateGridDimensions } from './lib';
  5. const DEFAULT_WIDTH = 30;
  6. const DEFAULT_HEIGHT = 20;
  7. const DEFAULT_SPEED = 100;
  8. const DEFAULT_CELL_SIZE = 30;
  9. const INITIAL_GRID = Array(DEFAULT_HEIGHT).fill(
  10. Array(DEFAULT_WIDTH).fill(false),
  11. );
  12. interface State {
  13. grid: boolean[][];
  14. running: boolean;
  15. cellSize: number;
  16. speed: number;
  17. width: number;
  18. height: number;
  19. }
  20. class Board extends React.Component<{}, State> {
  21. timer: NodeJS.Timeout | null;
  22. constructor(props: {}) {
  23. super(props);
  24. this.state = {
  25. grid: [...INITIAL_GRID],
  26. running: false,
  27. cellSize: DEFAULT_CELL_SIZE,
  28. speed: DEFAULT_SPEED,
  29. width: DEFAULT_WIDTH,
  30. height: DEFAULT_HEIGHT,
  31. };
  32. this.timer = null;
  33. }
  34. start = () => {
  35. this.timer = setInterval(() => {
  36. const grid = generateNewGrid(this.state.grid);
  37. this.setState({ grid });
  38. }, this.state.speed);
  39. };
  40. stop = () => {
  41. if (this.timer) clearInterval(this.timer);
  42. };
  43. reset = () => {
  44. this.setState({ grid: [...INITIAL_GRID] });
  45. this.stop();
  46. this.setState({ running: false });
  47. this.setState({ cellSize: DEFAULT_CELL_SIZE });
  48. this.setState({ width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT });
  49. };
  50. toggleCell = (x: number, y: number) => {
  51. const newGrid = [...this.state.grid];
  52. const newRow = [...newGrid[y]];
  53. newRow[x] = !newGrid[y][x];
  54. newGrid[y] = newRow;
  55. this.setState({ grid: newGrid });
  56. };
  57. toggleRunning = () => {
  58. if (this.state.running) this.stop();
  59. if (!this.state.running) this.start();
  60. this.setState({ running: !this.state.running });
  61. };
  62. updateSpeed = (speed: number) => {
  63. this.setState({ speed });
  64. if (this.state.running) {
  65. this.stop();
  66. this.start();
  67. }
  68. };
  69. updateCellSize = (f: (size: number) => number) => {
  70. this.setState({ cellSize: f(this.state.cellSize) });
  71. };
  72. updateDimensions = (dimensions: { width?: number; height?: number }) => {
  73. if (dimensions.width) {
  74. this.setState({ width: dimensions.width });
  75. }
  76. if (dimensions.height) {
  77. this.setState({ height: dimensions.height });
  78. }
  79. const grid = updateGridDimensions(
  80. { width: this.state.width, height: this.state.height },
  81. dimensions,
  82. this.state.grid,
  83. );
  84. this.setState({ grid });
  85. };
  86. render() {
  87. const { grid, running, speed, width, height, cellSize } = this.state;
  88. return (
  89. <div className="container">
  90. <Controls
  91. running={running}
  92. speed={speed}
  93. width={width}
  94. height={height}
  95. toggle={this.toggleRunning}
  96. updateCellSize={this.updateCellSize}
  97. updateDimensions={this.updateDimensions}
  98. updateSpeed={this.updateSpeed}
  99. reset={this.reset}
  100. />
  101. <div className="board-container">
  102. <div className="board">
  103. {grid.map((row, y) => (
  104. <div className="row" key={y} style={{ height: cellSize }}>
  105. {row.map((cell, x) => (
  106. <Cell
  107. disabled={running}
  108. x={x}
  109. y={y}
  110. cellSize={cellSize}
  111. alive={cell}
  112. toggle={this.toggleCell}
  113. key={x}
  114. />
  115. ))}
  116. </div>
  117. ))}
  118. </div>
  119. </div>
  120. </div>
  121. );
  122. }
  123. }
  124. export default Board;