代码 - 笔问题:为什么我的元胞自动机反应项目不起作用?
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
这里是 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