123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import React from 'react';
- import Cell from './Cell';
- import Controls from './Controls';
- import { generateNewGrid } from './lib';
-
- const DEFAULT_WIDTH = 20;
- const DEFAULT_HEIGHT = 10;
- const DEFAULT_SPEED = 500;
-
- const INITIAL_GRID = Array(DEFAULT_HEIGHT).fill(
- Array(DEFAULT_WIDTH).fill(false),
- );
-
- interface State {
- grid: boolean[][];
- running: boolean;
- 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,
- 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] });
- };
-
- 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();
- }
- };
-
- updateDimensions = (dimensions: { width?: number; height?: number }) => {
- if (dimensions.width) {
- this.setState({ width: dimensions.width });
- }
-
- if (dimensions.height) {
- this.setState({ height: dimensions.height });
- }
-
- const width = dimensions.width ?? this.state.width;
- const height = dimensions.height ?? this.state.height;
-
- const grid = [...this.state.grid];
- while (grid.length < height) {
- grid.push(Array(width).fill(false));
- }
-
- const newGrid = grid.map((row) => {
- while (row.length < width) {
- row.push(false);
- }
-
- return row;
- });
-
- this.setState({ grid: newGrid });
- };
-
- render() {
- const { grid, running, speed, width, height } = this.state;
-
- return (
- <div className="container">
- <Controls
- running={running}
- speed={speed}
- toggle={this.toggleRunning}
- width={width}
- height={height}
- 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}>
- {row.map((cell, x) => (
- <Cell
- disabled={running}
- x={x}
- y={y}
- alive={cell}
- toggle={this.toggleCell}
- key={x}
- />
- ))}
- </div>
- ))}
- </div>
- </div>
- </div>
- );
- }
- }
-
- export default Board;
|