123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import React from 'react';
- import Cell from './Cell';
- import Controls from './Controls';
- import { generateNewGrid, updateGridDimensions } from './lib';
-
- const DEFAULT_WIDTH = 30;
- const DEFAULT_HEIGHT = 20;
- const DEFAULT_SPEED = 100;
- const DEFAULT_CELL_SIZE = 30;
-
- const INITIAL_GRID = Array(DEFAULT_HEIGHT).fill(
- Array(DEFAULT_WIDTH).fill(false),
- );
-
- interface State {
- grid: boolean[][];
- running: boolean;
- cellSize: number;
- speed: number;
- width: number;
- height: number;
- }
-
- class Board extends React.Component<{}, State> {
- timer: NodeJS.Timeout | null;
-
- constructor(props: {}) {
- super(props);
- this.state = {
- grid: [...INITIAL_GRID],
- running: false,
- cellSize: DEFAULT_CELL_SIZE,
- speed: DEFAULT_SPEED,
- width: DEFAULT_WIDTH,
- height: DEFAULT_HEIGHT,
- };
- this.timer = null;
- }
-
- start = () => {
- this.timer = setInterval(() => {
- const grid = generateNewGrid(this.state.grid);
- this.setState({ grid });
- }, this.state.speed);
- };
-
- stop = () => {
- if (this.timer) clearInterval(this.timer);
- };
-
- reset = () => {
- this.setState({ grid: [...INITIAL_GRID] });
- this.stop();
- this.setState({ running: false });
- this.setState({ cellSize: DEFAULT_CELL_SIZE });
- this.setState({ width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT });
- };
-
- toggleCell = (x: number, y: number) => {
- const newGrid = [...this.state.grid];
- const newRow = [...newGrid[y]];
- newRow[x] = !newGrid[y][x];
- newGrid[y] = newRow;
- this.setState({ grid: newGrid });
- };
-
- toggleRunning = () => {
- if (this.state.running) this.stop();
- if (!this.state.running) this.start();
- this.setState({ running: !this.state.running });
- };
-
- updateSpeed = (speed: number) => {
- this.setState({ speed });
- if (this.state.running) {
- this.stop();
- this.start();
- }
- };
-
- updateCellSize = (f: (size: number) => number) => {
- this.setState({ cellSize: f(this.state.cellSize) });
- };
-
- updateDimensions = (dimensions: { width?: number; height?: number }) => {
- if (dimensions.width) {
- this.setState({ width: dimensions.width });
- }
-
- if (dimensions.height) {
- this.setState({ height: dimensions.height });
- }
-
- const grid = updateGridDimensions(
- { width: this.state.width, height: this.state.height },
- dimensions,
- this.state.grid,
- );
-
- this.setState({ grid });
- };
-
- render() {
- const { grid, running, speed, width, height, cellSize } = this.state;
-
- return (
- <div className="container">
- <Controls
- running={running}
- speed={speed}
- width={width}
- height={height}
- toggle={this.toggleRunning}
- updateCellSize={this.updateCellSize}
- updateDimensions={this.updateDimensions}
- updateSpeed={this.updateSpeed}
- reset={this.reset}
- />
- <div className="board-container">
- <div className="board">
- {grid.map((row, y) => (
- <div className="row" key={y} style={{ height: cellSize }}>
- {row.map((cell, x) => (
- <Cell
- disabled={running}
- x={x}
- y={y}
- cellSize={cellSize}
- alive={cell}
- toggle={this.toggleCell}
- key={x}
- />
- ))}
- </div>
- ))}
- </div>
- </div>
- </div>
- );
- }
- }
-
- export default Board;
|