我正在使用p5.js库。
我正在建立我的第一个神经网络 Toy-Neural-Network-JS。我遵循了Coding Train教程,它可以正常工作(对象在随机移动),但是出了点问题,这给了我一个错误(请参见图片)。
这是我的代码。每次杀死所有玩家时,都会发生错误。怎么了我检查了X次,没有看到任何错误。
let balls = [];
let totalBalls = 5;
let players = [];
let tmpplayers = [];
let totalPlayers = 100;
function nextGeneration(){
calcFitness();
for(let i = 0; i < totalPlayers; i++){
players.push(pickOnePlayer());
}
tmpplayers = [];
console.log("next generation");
}
function pickOnePlayer(){
let index = 0;
let r = random(1);
while(r > 0){
r = r - tmpplayers[index].fitness;
index++;
}
index--;
let player = tmpplayers[index];
let child = new Player(player.brain);
child.mutate();
return child;
}
function calcFitness(){
let sum = 0;
for(let player of tmpplayers){
sum += player.score;
}
for(let player of tmpplayers){
player.fitness = player.score / sum;
}
}
class Ball {
constructor(){
this.r = 15;
this.randX = random(this.r, width - this.r);
this.randY = random(this.r, height - this.r);
this.pos = new p5.Vector(this.randX, this.randY);
this.acc = new p5.Vector(random(-5, 5), random(-5, 5));
this.count = 0;
this.color = [random(0, 255), random(0, 255), random(0, 255)];
}
update(){
this.pos.x += this.acc.x;
this.pos.y += this.acc.y;
if(this.pos.x < this.r || this.pos.x > width - this.r){
this.acc.x *= -1;
}
if(this.pos.y < this.r || this.pos.y > height - this.r){
this.acc.y *= -1;
}
}
checkIntersect(another){ // check if ball hits another ball
return dist(this.pos.x, this.pos.y, another.pos.x, another.pos.y) < (this.r + another.r);
}
show(){
// show ball
fill(this.color[0], this.color[1], this.color[2]);
ellipse(this.pos.x, this.pos.y, this.r * 2);
// show ball score
fill(0);
textSize(20);
text(this.count, this.pos.x - (this.r / 2), this.pos.y + (this.r / 2));
}
}
class Player {
constructor(brain){
this.range = 150;
this.r = 15;
this.count = 0;
this.score = 0;
this.fitness = 0;
this.pos = new p5.Vector(width / 2, height / 2);
this.acc = new p5.Vector();
// if brain was passed, copy it, else make new neuralnetwork
if(brain != undefined){
this.brain = brain.copy();
} else {
this.brain = new NeuralNetwork(6, 4, 1);
}
}
mutate(){
this.brain.mutate(x=>x*0.1);
}
move(x, y){
this.acc.x = x;
this.acc.y = y;
this.pos.x += this.acc.x;
this.pos.y += this.acc.y;
if(this.pos.x < this.r || this.pos.x > width - this.r){
this.pos.x -= this.acc.x;
}
if(this.pos.y < this.r || this.pos.y > height - this.r){
this.pos.y -= this.acc.y;
}
}
think(){
let inputs = [];
// set INPUTS of this particular Player
inputs.push(this.pos.x / width);
inputs.push(this.pos.y / height);
inputs.push(this.count);
// get closest ball
let closestBall = balls[0];
let closestD = dist(this.pos.x, this.pos.y, closestBall.pos.x, closestBall.pos.y);
for(let ball of balls){
let d = dist(this.pos.x, this.pos.y, ball.pos.x, ball.pos.y);
if(d < closestD){
closestD = d;
closestBall = ball;
}
}
// set INPUTS of closest Ball
inputs.push(closestBall.pos.x / width);
inputs.push(closestBall.pos.y / height);
inputs.push(closestBall.count);
// predict inputs and then do actions
let output = this.brain.predict(inputs);
if(output < 0.25){
this.move(0, -3); // up
} else if(output >= 0.25 && output < 0.5){
this.move(-3, 0); // left
} else if(output >= 0.5 && output < 0.75){
this.move(0, 3); // down
} else {
this.move(3, 0); // right
}
}
checkIntersect(another){ // check if player hits ball
return dist(this.pos.x, this.pos.y, another.pos.x, another.pos.y) < (this.r + another.r);
}
show(){
//fill(255, 0, 0, 20);
//ellipse(this.pos.x, this.pos.y, this.range * 2);
// show player
fill(0, 255, 0);
ellipse(this.pos.x, this.pos.y, this.r * 2);
// show player score
fill(0);
textSize(20);
text("!" + this.count, this.pos.x - (this.r / 2), this.pos.y + (this.r / 2));
}
}
function setup(){
createCanvas(windowWidth, windowHeight);
// create balls
for(let i = 0; i < totalBalls; i++){
balls.push(new Ball());
}
// create players
for(let i = 0; i < totalPlayers; i++){
players.push(new Player());
}
}
function draw(){
background(51);
// keep spawning new balls
if(balls.length != totalBalls){
while(balls.length != totalBalls){
balls.push(new Ball());
}
}
// reset game and make a nextGeneration out of previous
if(players.length == 0 || frameCount == 1000){
nextGeneration();
}
// some special graphic stuff, NOT IMPORTANT
let rw = round(windowWidth / totalBalls);
for(let i = 0; i < balls.length; i++){
let rh = constrain(balls[i].count, 0, height);
let c = balls[i].color;
c[3] = 50; // transparent background
fill(c);
rect(i * rw, height, rw, -rh);
}
for(let player of players){
player.score++;
player.think();
player.show();
for(let ball of balls){
if(player.checkIntersect(ball)){
if(player.count > ball.count){
player.count += 1;
player.count += ball.count;
balls.splice(balls.indexOf(ball), 1);
} else {
ball.count += 1;
ball.count += player.count;
tmpplayers.push(players.splice(players.indexOf(player), 1)[0]);
}
}
}
}
for(let ball of balls){
ball.update();
ball.show();
for(let another of balls){
if(ball != another){
if(ball.checkIntersect(another)){
if(ball.count > another.count){
ball.count += 1;
ball.count += another.count;
balls.splice(balls.indexOf(another), 1);
} else {
another.count += 1;
another.count += ball.count;
balls.splice(balls.indexOf(ball), 1);
}
}
}
}
}
}
* {
padding: 0;
margin: 0;
overflow: hidden;
}
<script src="https://rawgit.com/CodingTrain/Toy-Neural-Network-JS/master/lib/matrix.js"></script>
<script src="https://rawgit.com/CodingTrain/Toy-Neural-Network-JS/master/lib/nn.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>
答案 0 :(得分:1)
似乎mutate需要函数参数,而不是数字。
在以下行中更改播放器方法var express = require('express');
var cors = require('cors');
var app = express().use("*",cors());
var router = app.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
// Comment out this line:
//res.send('respond with a resource');
// And insert something like this instead:
res.json([{
id: 1,
username: "samsepi0l"
}, {
id: 2,
username: "D0loresH4ze"
}]);
});
module.exports = router;
:
mutate
到
this.brain.mutate(0.1)
这会将每个元素乘以0.1
this.brain.mutate(x=>x*0.1)
let balls = [];
let totalBalls = 5;
let players = [];
let tmpplayers = [];
let totalPlayers = 100;
function nextGeneration(){
calcFitness();
for(let i = 0; i < totalPlayers; i++){
players.push(pickOnePlayer());
}
tmpplayers = [];
console.log("next generation");
}
function pickOnePlayer(){
let index = 0;
let r = random(1);
while(r > 0){
r = r - tmpplayers[index].fitness;
index++;
}
index--;
let player = tmpplayers[index];
let child = new Player(player.brain);
child.mutate();
return child;
}
function calcFitness(){
let sum = 0;
for(let player of tmpplayers){
sum += player.score;
}
for(let player of tmpplayers){
player.fitness = player.score / sum;
}
}
class Ball {
constructor(){
this.r = 15;
this.randX = random(this.r, width - this.r);
this.randY = random(this.r, height - this.r);
this.pos = new p5.Vector(this.randX, this.randY);
this.acc = new p5.Vector(random(-5, 5), random(-5, 5));
this.count = 0;
this.color = [random(0, 255), random(0, 255), random(0, 255)];
}
update(){
this.pos.x += this.acc.x;
this.pos.y += this.acc.y;
if(this.pos.x < this.r || this.pos.x > width - this.r){
this.acc.x *= -1;
}
if(this.pos.y < this.r || this.pos.y > height - this.r){
this.acc.y *= -1;
}
}
checkIntersect(another){ // check if ball hits another ball
return dist(this.pos.x, this.pos.y, another.pos.x, another.pos.y) < (this.r + another.r);
}
show(){
// show ball
fill(this.color[0], this.color[1], this.color[2]);
ellipse(this.pos.x, this.pos.y, this.r * 2);
// show ball score
fill(0);
textSize(20);
text(this.count, this.pos.x - (this.r / 2), this.pos.y + (this.r / 2));
}
}
class Player {
constructor(brain){
this.range = 150;
this.r = 15;
this.count = 0;
this.score = 0;
this.fitness = 0;
this.pos = new p5.Vector(width / 2, height / 2);
this.acc = new p5.Vector();
// if brain was passed, copy it, else make new neuralnetwork
if(brain != undefined){
this.brain = brain.copy();
} else {
this.brain = new NeuralNetwork(6, 4, 1);
}
}
mutate(){
this.brain.mutate(x=>x*0.1);
}
move(x, y){
this.acc.x = x;
this.acc.y = y;
this.pos.x += this.acc.x;
this.pos.y += this.acc.y;
if(this.pos.x < this.r || this.pos.x > width - this.r){
this.pos.x -= this.acc.x;
}
if(this.pos.y < this.r || this.pos.y > height - this.r){
this.pos.y -= this.acc.y;
}
}
think(){
let inputs = [];
// set INPUTS of this particular Player
inputs.push(this.pos.x / width);
inputs.push(this.pos.y / height);
inputs.push(this.count);
// get closest ball
let closestBall = balls[0];
let closestD = dist(this.pos.x, this.pos.y, closestBall.pos.x, closestBall.pos.y);
for(let ball of balls){
let d = dist(this.pos.x, this.pos.y, ball.pos.x, ball.pos.y);
if(d < closestD){
closestD = d;
closestBall = ball;
}
}
// set INPUTS of closest Ball
inputs.push(closestBall.pos.x / width);
inputs.push(closestBall.pos.y / height);
inputs.push(closestBall.count);
// predict inputs and then do actions
let output = this.brain.predict(inputs);
if(output < 0.25){
this.move(0, -3); // up
} else if(output >= 0.25 && output < 0.5){
this.move(-3, 0); // left
} else if(output >= 0.5 && output < 0.75){
this.move(0, 3); // down
} else {
this.move(3, 0); // right
}
}
checkIntersect(another){ // check if player hits ball
return dist(this.pos.x, this.pos.y, another.pos.x, another.pos.y) < (this.r + another.r);
}
show(){
//fill(255, 0, 0, 20);
//ellipse(this.pos.x, this.pos.y, this.range * 2);
// show player
fill(0, 255, 0);
ellipse(this.pos.x, this.pos.y, this.r * 2);
// show player score
fill(0);
textSize(20);
text("!" + this.count, this.pos.x - (this.r / 2), this.pos.y + (this.r / 2));
}
}
function setup(){
createCanvas(windowWidth, windowHeight);
// create balls
for(let i = 0; i < totalBalls; i++){
balls.push(new Ball());
}
// create players
for(let i = 0; i < totalPlayers; i++){
players.push(new Player());
}
}
function draw(){
background(51);
// keep spawning new balls
if(balls.length != totalBalls){
while(balls.length != totalBalls){
balls.push(new Ball());
}
}
// reset game and make a nextGeneration out of previous
if(players.length == 0 || frameCount == 1000){
nextGeneration();
}
// some special graphic stuff, NOT IMPORTANT
let rw = round(windowWidth / totalBalls);
for(let i = 0; i < balls.length; i++){
let rh = constrain(balls[i].count, 0, height);
let c = balls[i].color;
c[3] = 50; // transparent background
fill(c);
rect(i * rw, height, rw, -rh);
}
for(let player of players){
player.score++;
player.think();
player.show();
for(let ball of balls){
if(player.checkIntersect(ball)){
if(player.count > ball.count){
player.count += 1;
player.count += ball.count;
balls.splice(balls.indexOf(ball), 1);
} else {
ball.count += 1;
ball.count += player.count;
tmpplayers.push(players.splice(players.indexOf(player), 1)[0]);
}
}
}
}
for(let ball of balls){
ball.update();
ball.show();
for(let another of balls){
if(ball != another){
if(ball.checkIntersect(another)){
if(ball.count > another.count){
ball.count += 1;
ball.count += another.count;
balls.splice(balls.indexOf(another), 1);
} else {
another.count += 1;
another.count += ball.count;
balls.splice(balls.indexOf(ball), 1);
}
}
}
}
}
}
* {
padding: 0;
margin: 0;
overflow: hidden;
}