代码 - 笔问题:为什么我的元胞自动机反应项目不起作用?

Code - Pen Issues: why does my cellular automata react project not work?

这里是 project.

它应该在屏幕上显示一个交互式网格,带有一些按钮和关于如何最好地与系统交互的说明,但我想我做错了什么。它适用于我的本地环境。

JS:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

const size = 40;

// global state of the array, and previous state
var state_0 = [];
var state_1 = [];

// for langtons ant
var ant = {
  pos:[],
  n: 0,
  e: 0,
  w: 0,
  s: 0,
};

var ants = [];

// keeps track of the type of rule being implemented
var algorithm_states = 0;

// keeps track of whether the program is running or not
var running = 0;

// executes algorithm each timestep
var timestep = 40;
var step_interval;
var counter = 0;

// clears the board, color only
function wipe(){
  for(var k = 0; k < size; k++){
    for(var kk = 0; kk < size; kk++){
      var _id = String(k) + "," + String(kk);
      var _btn = document.getElementById(_id);
      _btn.style.backgroundColor = null;
    }
  }
}

var t_count = 0;
function test(){
  switch (t_count % 2) {
    case 0:
        for(var k = 0; k < size; k++){
          for(var kk = 0; kk < size; kk++){
            var _id = String(k) + "," + String(kk);
            var _btn = document.getElementById(_id);
            var use_curr = 0;
            var alg = new Algs(k, kk, algorithm_states, use_curr);
            if(alg.value === 1){
              if(algorithm_states === 0){
                state_1[k][kk] = 1;
                _btn.style.backgroundColor = '#555';
              }else{
                console.log("LA");
              }
            }else{
              if(algorithm_states === 0){
                state_1[k][kk] = 0;
                _btn.style.backgroundColor = null;
              }else{
                console.log("LA");
              }
            }
          }
        }
      break;
    case 1:
        wipe();
        for(var m = 0; m < size; m++){
          for(var mm = 0; mm < size; mm++){
            state_0[m][mm] = state_1[m][mm];
          }
        }
      break;
    default:
  }
  t_count++;
}

// runs an alternative cycle of 0,1 eact timestep
function run_alg(active){
  if(active){
    step_interval = window.setInterval(()=>{
      switch (counter % 2) {
        case 0:
            for(var k = 0; k < size; k++){
              for(var kk = 0; kk < size; kk++){
                var _id = String(k) + "," + String(kk);
                var _btn = document.getElementById(_id);
                var use_curr = 0;
                var alg = new Algs(k, kk, algorithm_states, use_curr);
                if(alg.value === 1){
                  state_1[k][kk] = 1;
                  _btn.style.backgroundColor = '#555';
                }else{
                  state_1[k][kk] = 0;
                  _btn.style.backgroundColor = null;
                }
              }
            }
          break;
        case 1:
            wipe();
            for(var m = 0; m < size; m++){
              for(var mm = 0; mm < size; mm++){
                state_0[m][mm] = state_1[m][mm];
              }
            }
          break;
        default:
      }
      counter++;
    },timestep);
  }else{
    counter = 0;
    clearInterval(step_interval);
  }
}

class Head extends React.Component{
  algClick(i){
    algorithm_states = i;
    for(var m = 0; m < size; m++){
      for(var mm = 0; mm < size; mm++){
        state_0[m][mm] = 0;
        state_1[m][mm] = 0;
      }
    }
  }
  // handles start and reset button functionality
  startResetClick(i){

    switch(i){
      default:
      // here we disable all buttons while the algorithm is running
      case 0:
        running = 1;
        for(var j = 0; j < size; j++){
          for(var jj = 0; jj < size; jj++){
            var id = String(j) + "," + String(jj);
            var btn = document.getElementById(id);
            btn.disabled = true;
          }
        }
        run_alg(true);
        break;
      // here we clear the board and state arrays, and enable interactivity again
      case 1:
        running = 0;
        for(var k = 0; k < size; k++){
          for(var kk = 0; kk < size; kk++){
            state_0[k][kk] = 0;
            state_1[k][kk] = 0;
            var _id = String(k) + "," + String(kk);
            var _btn = document.getElementById(_id);
            _btn.style.backgroundColor = null;
            _btn.disabled = false;
            run_alg(false);
          }
        }

        // re - initialise langtons ant direction
        ant = [null, 1, 0, 0, 0];

        break;
    }
  }
  render(){
    return(
      <header>
        <button className = "main">
          Main
        </button>
        <div className="dropdown">
          <span>RULE Drop-Down</span>
          <div className="dropdown-content">
            {/* algorithms mapped to their indicies in list */}
            <button onClick={() => this.algClick(0)}>Game Of Life</button>
            <button onClick={() => this.algClick(1)}>Langtons Ant</button>
            <button onClick={() => test()}>test</button>
          </div>
        </div>
        {/* start button mapped to 0, reset button mapped to 1 */}
        <button className = "start" onClick={() => this.startResetClick(0)}>START</button>
        <button className = "stop" onClick={() => this.startResetClick(1)}>RESET</button>
        <p className = "instructions">To get started,
          choose an algorithm using the RULE Drop-Down, pick some squares,
          then press START to see how that algorithm evolves the space
          around it over time. To stop the evolution, and try a new
          initial pattern, press RESET, and follow these rules again. </p>
      </header>
    )
  }
}

class Square extends React.Component {
  // this class needs to be interactive from other classes, so we give it arguments
  constructor(props){
    super(props);
    this.state = {
      active: null,
      x: props.x,
      y: props.y,
    }
  }

  handleClick = (e) => {
    // changes state of clicked cell, and handles color
    this.state.active = !this.state.active;

    switch (this.state.active) {
      case false:
          e.target.style.backgroundColor = null;
          state_0[this.state.x][this.state.y] = 0;

        break;
      case true:
          e.target.style.backgroundColor = '#555';
          state_0[this.state.x][this.state.y] = 1;

        break;
      default:
    }
  }

  render() {
    return (
      <button id = {[this.state.x, this.state.y]} className="square" onClick={this.handleClick}>
      </button>
    );
  }
}

//creates interactive board
class Board extends React.Component{
  render(){
    const rows = [], cols = [];
    // initialise board
    for(var i = 0;  i < size; i++){
      rows[i] = i;
      cols[i] = i;
      // keep track of state of each cell
      state_0[i] = [];
      state_1[i] = [];
      for(var ii = 0;  ii < size; ii++){
        state_0[i][ii] = 0;
        state_1[i][ii] = 0;
      }
    }

    // initialise langtons ant direction
    ant = [null, 1, 0, 0, 0];

    // board rendering: size x size board
    return(
      <div id = "board_c">
        {[...rows].map((x) => {
            return(
              <div className="board-row" key = {x}>
                {[...cols].map((y) => (<Square keys={[x,y]} key={x+y} x={x} y={y}/>))}
              </div>
            )
          })
        }
      </div>
    )
  }
}

// creates full page
class Game extends React.Component {
  render() {
    return (
      <div className="game">
        <header className = "header">
          <Head/>
        </header>
        <body>
          <div className="game-board">
            <Board />
          </div>
        </body>
      </div>
    );
  }
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

class Algs{
  constructor(x, y, algorithm, arr_01){
    this.x = x;
    this.y = y;
    this.algorithm = algorithm_states;
    this.arr_01 = arr_01;
  }

  get value(){
    switch (this.algorithm) {
      case 0:
          return this.Game_Of_Life();
        break;
      case 1:
          return this.Langtons_Ant();
        break;
      default:
    }
  }

  //game of life
  //Any live cell with two or three live neighbours survives.
  //Any dead cell with three live neighbours becomes a live cell.
  //All other live cells die in the next generation. Similarly, all other dead cells stay dead.

  Game_Of_Life(){
    var arr_type;
    if(this.arr_01 === 0){
      arr_type = state_0;
    }
    else{
      arr_type = state_1;
    }
    var _n0, _n1, _n2, _n3, _n4, _n5, _n6, _n7;

    if(this.x > 0){
        _n0 = arr_type[this.x - 1][this.y];
    }

    if(this.x < size - 1){
        _n1 = arr_type[this.x + 1][this.y];
    }

    if(this.y > 0){
        _n2 = arr_type[this.x][this.y - 1];
    }

    if(this.y < size - 1){
        _n3 = arr_type[this.x][this.y + 1];
    }

    if(this.x > 0 && this.y > 0){
        _n4 = arr_type[this.x - 1][this.y - 1];
    }

    if(this.x < size - 1 && this.y < size - 1){
        _n5 = arr_type[this.x + 1][this.y + 1];
    }

    if(this.x > 0 && this.y < size - 1){
        _n6 = arr_type[this.x - 1][this.y + 1];
    }

    if(this.x < size - 1 && this.y > 0){
        _n7 = arr_type[this.x + 1][this.y - 1];
    }

    var sum = _n0 + _n1 + _n2 + _n3 + _n4 + _n5 + _n6 + _n7;

    if(arr_type[this.x][this.y] === 0){
      if(sum === 3){
        return 1;
      }else{
        return 0;
      }
    }
    else if(arr_type[this.x][this.y] === 1){
      if(sum === 2 || sum === 3){
        return 1;
      }else{
        return 0;
      }
    }else{
      return 0;
    }
  }

  //langtons ant
  //At a white square, turn 90° clockwise, flip the color of the square, move forward one unit
  //At a black square, turn 90° counter-clockwise, flip the color of the square, move forward one unit

  Langtons_Ant(){
    var arr_type;


  }
}

function switch_color(butt){
  if(butt.style.backgroundColor = null){
    butt.style.backgroundColor = '#555';
  }else{
    butt.style.backgroundColor = null;
  }
}

CSS:

body {
  font: 14px "Century Gothic", Futura, sans-serif;
  margin: 20px;
}

ol, ul {
  padding-left: 30px;
}

.header{
  background-color: "black";
}

.main {
  position: absolute;
  left: 5%
}

.game-board{
  position: absolute;
  top: 10%;
  left:25%;
}

.board-row:after {
  clear: both;
  content: "";
  display: table;
}

.status {
  margin-bottom: 10px;
}

.square {
  border: 1px solid #999;
  float: left;
  font-size: 10px;
  font-weight: bold;
  line-height: 15px;
  height: 16px;
  margin-right: -1px;
  margin-top: -1px;
  padding: 0;
  text-align: center;
  width: 16px;
}

.square:focus {
  outline: none;
}

.kbd-navigation .square:focus {
  background: #ddd;
}

.game {
  display: flex;
  flex-direction: row;
}

.game-info {
  margin-left: 20px;
}

.dropdown {
  position: absolute;
  top: 15%;
  left: 5%;
  display: inline-block;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
}

.dropdown:hover .dropdown-content {
  display: block;
}

.start{
  position: absolute;
  right: 15%;
}
.stop{
  position: absolute;
  right: 5%;
}

.instructions{
  position: absolute;
  top: 10%;
  left: 78%;
  right:5%;
}

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />

    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>

  </body>
</html>

对于任何好奇的人,这将是一个交互式元胞自动机模拟器!

非常感谢任何帮助!

K

所以这里是 solution,需要的是添加正确的笔设置。

https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js
https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js
https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js