here is the code for making a 2d array to be used as a board for conways game of life in node.js. i am having a problem with displaying the board. the output looks like this.
['-','-','-']
['-','-','-']
['-','-','-']
however i want it to look like this
---
---
---
this is the code right now. Does anyone have any suggestions?
var createBoard = (width, height) => {
board = [];
row = [];
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++) {
row.push("-");
}
board.push(row);
row =[];
}
return (board);
}
var displayBoard = (board) =>{
for (var i = 0; i < board.length; i++) {
console.log(board[i]);
}
}
gameBoard = createBoard(3,3);
displayBoard(gameBoard);
You need to join the elements of the array to form a string.
var createBoard = (width, height) => {
board = [];
row = [];
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++) {
row.push("-");
}
board.push(row);
row = [];
}
return (board);
}
var displayBoard = (board) => {
for (var i = 0; i < board.length; i++) {
console.log(board[i].join(""));
}
}
gameBoard = createBoard(3, 3);
displayBoard(gameBoard);
To fix your issue you should iterate over the array and add it to a string, like this:
var displayBoard = (board) =>{
var buffer = '';
for (var i = 0; i < board.length; i++) {
for (var x = 0; x < board[i].length; x++) {
buffer += board[i][x];
}
buffer += '\n';
}
console.log(buffer);
}
This should print it like this:
---
---
---
Related
I am following the Nature of Code tutorial by Code Train and when I tested the code I got the TypeError. It pointed to function FromArray, line 19. I am trying to follow his coding challenge on teaching the neural network xor, where he visualizes the xor problem. The code I have so far should produce a flicking black and white screen. Here is a specific error message I got:
at Function.fromArray (matrix.js:19)
at NeuralNetwork.train (nn.js:61)
at draw (sketch.js:44)
at e.d.redraw (p5.min.js:33)
at e.<anonymous> (p5.min.js:32)
at e.<anonymous> (p5.min.js:32)
at new e (p5.min.js:32)
at e (p5.min.js:32).
I tried rewatching some of the videos to see if I missed something and I even checked with his code on GitHub but I still get that error. I tried searching for what to do with TypeError but most answers I found on forums.
Please help. Also, his tutorial series is really good.
//This is my code for the matrix math (Matrix.js):
// let m = new Matrix(3,2);
class Matrix {
constructor(rows, cols) {
this.rows = rows;
this.cols = cols;
this.data = [];
for (let i = 0; i < this.rows; i++) {
this.data[i] = [];
for (let j = 0; j < this.cols; j++) {
this.data[i][j] = 0;
}
}
}
static fromArray(arr) {
let m = new Matrix(arr.length, 1);
for (let i = 0; i < arr.length; i++) {
m.data[i][0] = arr[i];
}
return m;
}
static subtract(a, b) {
// Return a new Matrix a-b
let result = new Matrix(a.rows, a.cols);
for (let i = 0; i < result.rows; i++) {
for (let j = 0; j < result.cols; j++) {
result.data[i][j] = a.data[i][j] - b.data[i][j];
}
}
return result;
}
toArray() {
let arr = [];
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
arr.push(this.data[i][j]);
}
}
return arr;
}
randomize() {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] = Math.random() * 2 - 1;
}
}
}
add(n) {
if (n instanceof Matrix) {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] += n.data[i][j];
}
}
} else {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] += n;
}
}
}
}
static transpose(matrix) {
let result = new Matrix(matrix.cols, matrix.rows);
for (let i = 0; i < matrix.rows; i++) {
for (let j = 0; j < matrix.cols; j++) {
result.data[j][i] = matrix.data[i][j];
}
}
return result;
}
static multiply(a, b) {
// Matrix product
if (a.cols !== b.rows) {
console.log('Columns of A must match rows of B.')
return undefined;
}
let result = new Matrix(a.rows, b.cols);
for (let i = 0; i < result.rows; i++) {
for (let j = 0; j < result.cols; j++) {
// Dot product of values in col
let sum = 0;
for (let k = 0; k < a.cols; k++) {
sum += a.data[i][k] * b.data[k][j];
}
result.data[i][j] = sum;
}
}
return result;
}
multiply(n) {
if (n instanceof Matrix) {
// hadamard product
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] *= n.data[i][j];
}
}
} else {
// Scalar product
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] *= n;
}
}
}
}
map(func) {
// Apply a function to every element of matrix
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
let val = this.data[i][j];
this.data[i][j] = func(val);
}
}
}
static map(matrix, func) {
let result = new Matrix(matrix.rows, matrix.cols);
// Apply a function to every element of matrix
for (let i = 0; i < matrix.rows; i++) {
for (let j = 0; j < matrix.cols; j++) {
let val = matrix.data[i][j];
result.data[i][j] = func(val);
}
}
return result;
}
print() {
console.table(this.data);
}
}
if (typeof module !== 'undefined') {
module.exports = Matrix;
}
//This the code that trains the neural network:
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
function dsigmoid(y) {
// return sigmoid(x) * (1 - sigmoid(x));
return y * (1 - y);
}
class NeuralNetwork {
constructor(input_nodes, hidden_nodes, output_nodes) {
this.input_nodes = input_nodes;
this.hidden_nodes = hidden_nodes;
this.output_nodes = output_nodes;
this.weights_ih = new Matrix(this.hidden_nodes, this.input_nodes);
this.weights_ho = new Matrix(this.output_nodes, this.hidden_nodes);
this.weights_ih.randomize();
this.weights_ho.randomize();
this.bias_h = new Matrix(this.hidden_nodes, 1);
this.bias_o = new Matrix(this.output_nodes, 1);
this.bias_h.randomize();
this.bias_o.randomize();
this.learning_rate = 0.1;
}
feedforward(input_array) {
// Generating the Hidden Outputs
let inputs = Matrix.fromArray(input_array);
let hidden = Matrix.multiply(this.weights_ih, inputs);
hidden.add(this.bias_h);
// activation function!
hidden.map(sigmoid);
// Generating the output's output!
let output = Matrix.multiply(this.weights_ho, hidden);
output.add(this.bias_o);
output.map(sigmoid);
// Sending back to the caller!
return output.toArray();
}
train(input_array, target_array) {
// Generating the Hidden Outputs
let inputs = Matrix.fromArray(input_array);
let hidden = Matrix.multiply(this.weights_ih, inputs);
hidden.add(this.bias_h);
// activation function!
hidden.map(sigmoid);
// Generating the output's output!
let outputs = Matrix.multiply(this.weights_ho, hidden);
outputs.add(this.bias_o);
outputs.map(sigmoid);
// Convert array to matrix object
let targets = Matrix.fromArray(target_array);
// Calculate the error
// ERROR = TARGETS - OUTPUTS
let output_errors = Matrix.subtract(targets, outputs);
// let gradient = outputs * (1 - outputs);
// Calculate gradient
let gradients = Matrix.map(outputs, dsigmoid);
gradients.multiply(output_errors);
gradients.multiply(this.learning_rate);
// Calculate deltas
let hidden_T = Matrix.transpose(hidden);
let weight_ho_deltas = Matrix.multiply(gradients, hidden_T);
// Adjust the weights by deltas
this.weights_ho.add(weight_ho_deltas);
// Adjust the bias by its deltas (which is just the gradients)
this.bias_o.add(gradients);
// Calculate the hidden layer errors
let who_t = Matrix.transpose(this.weights_ho);
let hidden_errors = Matrix.multiply(who_t, output_errors);
// Calculate hidden gradient
let hidden_gradient = Matrix.map(hidden, dsigmoid);
hidden_gradient.multiply(hidden_errors);
hidden_gradient.multiply(this.learning_rate);
// Calcuate input->hidden deltas
let inputs_T = Matrix.transpose(inputs);
let weight_ih_deltas = Matrix.multiply(hidden_gradient, inputs_T);
this.weights_ih.add(weight_ih_deltas);
// Adjust the bias by its deltas (which is just the gradients)
this.bias_h.add(hidden_gradient);
// outputs.print();
// targets.print();
// error.print();
}
}
//And this does the sketch and outputs the results:
let nn;
//Test Data
let training_data = [
{
inputs: [0,1],
targets: [1]
},
{
inputs: [1,0],
targets: [1]
},
{
inputs: [0,0],
targets: [0]
},
{
inputs: [1,1],
targets: [0]
},
];
function setup() {
//Test Data
// for (let i = 0; i < 50000; i++) {
// let data = random(training_data);
// nn.train(data.inputs, data.targets);
// }
// console.log(nn.feedforward([1,0]));
// console.log(nn.feedforward([0,1]));
// console.log(nn.feedforward([1,1]));
// console.log(nn.feedforward([0,0]));
createCanvas(400, 400);
nn = new NeuralNetwork(2, 2, 1);
}
function draw() {
background(0)
for (let i = 0; i < 1000; i++) {
let data = random(training_data);
nn.train(data.inputs, data.outputs);
}
let resolution = 10;
let cols = width / resolution;
let rows = height / resolution;
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
fill(random(255));
rect(i*resolution,j*resolution,resolution, resolution)
}
}
}
I want to predefine the 2d-array containing an array of objects like this below image:
I am trying this way:
var grid = [];
iMax = 3;
jMax = 2;
count = 0;
for (let i = 0; i < iMax; i++) {
grid[i] = [];
for (let j = 0; j < jMax; j++) {
grid[i][j] = count;
count++;
}
}
In your code you're building up the two-dimensional array, but you are filling the rows with numbers (i.e. your setting the count) instead of an array of objects. So if you want to achieve the exact same structure as provided in the screenshot, you can do:
const rows = 4;
const cols = 4;
const elementCount = 3;
function buildGrid(rows,cols, elementCount) {
const grid = [];
for(let i=0; i < rows; i++) {
grid[i] = [];
for(let j=0; j < cols; j++) {
grid[i].push(Array.from({length:elementCount}, () => ({})));
}
}
return grid;
}
const grid = buildGrid(rows,cols,elementCount);
console.log(grid);
I am trying to create and initialize a bidimensional array in javascript inside an AngularJS application as follows:
$scope.invalidVote = [];
for (var i = 0; i < $scope.arry1.length; i += 1) {
$scope.answersCount[i] = $scope.arry1[i].arry2.length;
for(var j = 0; j < $scope.arry1[i].arry2.length; j += 1) {
$scope.invalidVote[i][j] = false;
}
}
But it doesn't work, What is the right way to do that?
try this:
$scope.invalidVote = [];
for (var i = 0; i < $scope.arry1.length; i++) {
$scope.answersCount[i] = $scope.arry1[i].arry2.length;
$scope.invalidVote[i] = [];
for(var j = 0; j < $scope.arry1[i].arry2.length; j++) {
$scope.invalidVote[i][j] = false;
}
}
I'm assuming $scope.arry1[i] is an array that contain other arrays and is already fill with values.
So your code should look like:
$scope.invalidVote = $scope.arry1;
for (var i = 0; i < $scope.arry1.length; i += 1)
{
$scope.answersCount[i] = $scope.arry1[i].length;
for(var j = 0; j < $scope.arry1[i].length; j += 1)
{
$scope.invalidVote[i][j] = false;
}
}
'$scope.invalidVote = $scope.arry1;' declaring "invalidVote" like this ensure it contains the same amount of indexes.
I am brand new to JavaScript and still figuring out the way things interact, so I apologize if this is obvious. I am ultimately trying to create a sliding tile puzzle, but at the moment I need to create a 2 dimensional array that will populate my grid with values (1-8). Basically all of my information thus far has been gathered from internet searches as my other resources have proven to be pretty useless.
Here is my code that generates a grid:
function newPuzzle(r, c)
{
var table = document.createElement("table");
for (var i = 0; i < r; i++)
{
var row = document.createElement('tr');
for (var j = 0; j < c; j++)
{
var column = document.createElement('td');
if (i%2 == j%2)
{
column.className = "even";
}
else
{
column.className = "odd";
}
row.appendChild(column);
}
table.appendChild(row);
}
document.body.appendChild(table);
populateTable();
}
At the end I've called the populateTable() function (which I'm not even sure will work) and here is the code for that:
function populateTable()
{
var cell = new Array(_r);
for (var i = 0; i < _r; i++)
{
cell[i] = new Array(_c);
}
for (var i = 0; i < cell.length; ++i)
{
var entry = cell[i];
for (var j = 0; j < entry.length; ++j)
{
var gridTable = document.getElementByTagName("table");
var _cells = gridTable.rows[i].cells[j].innerHTML = "2";
//the 2 is just for testing
}
}
}
Any insight would be very appreciated.
Your code basically had two issues, when I ran it:
In your method populateTable() the variables _r and _c were not defined, so I passed them in as arguments.
The method document.getElementByTagName does not exists, it's plural document.getElementsByTagName which in turn returns an array of all <table> elements so you have to select which one you want - I opted for the first one since I assume you only have one table on your page.
Here are the changes:
function newPuzzle(r, c)
{
var table = document.createElement("table");
for (var i = 0; i < r; i++)
{
var row = document.createElement('tr');
for (var j = 0; j < c; j++)
{
var column = document.createElement('td');
if (i%2 == j%2)
{
column.className = "even";
}
else
{
column.className = "odd";
}
row.appendChild(column);
}
table.appendChild(row);
}
document.body.appendChild(table);
// here we pass _r and _c as arguments
populateTable(r,c);
}
function populateTable(_r,_c)
{
var cell = new Array(_r);
for (var i = 0; i < _r; i++)
{
cell[i] = new Array(_c);
}
for (var i = 0; i < cell.length; ++i)
{
var entry = cell[i];
for (var j = 0; j < entry.length; ++j)
{
// getElementsByTagName returns an array of all table elements
var gridTable = document.getElementsByTagName("table");
// we select the first table element with the array index [0]
var _cells = gridTable[0].rows[i].cells[j].innerHTML = "2";
//the 2 is just for testing
}
}
}
An interactive JS fiddle: https://jsfiddle.net/Ls76kk2a/2/
An optimization tip: Give your table a unique ID like this:
var table = document.createElement("table");
table.id = "mySuperCoolTable";
Then you can be sure you get the right one with:
var gridTable = document.getElementById("mySuperCoolTable");
This only returns one (or none) table because the ID must be unique.
Response to your comment:
Here's an example how to populate all elements but the last one:
function populateTable(_r,_c)
{
var cell = new Array(_r);
for (var i = 0; i < _r; i++)
{
cell[i] = new Array(_c);
for (var j = 0; j < _c; j++) {
cell[i][j] = i*_c + j;
}
}
// fix the last one
cell[_r-1][_c-1] = "X";
for (var i = 0; i < cell.length; ++i)
{
var entry = cell[i];
for (var j = 0; j < entry.length; ++j)
{
var gridTable = document.getElementsByTagName("table");
var _cells = gridTable[0].rows[i].cells[j].innerHTML = cell[i][j];
}
}
}
And here's the JS fiddle: https://jsfiddle.net/Ls76kk2a/3/
I have the following code
for(i = 0; i < num; i++) {
var yPos = 10*i;
var numCells = wid/30;
for(j = 0; j < numCells; j++) {
blocks[i][j] = 1;
}
}
With
blocks = new Array();
However, when I execute the code I receive an error stating that:
can't convert undefined to object
Any ideas? :/
var blocks = [];
for(i = 0; i < num; i++) {
var yPos = 10*i;
var numCells = wid/30;
blocks[i] = []; // here is a fix
for(j = 0; j < numCells; j++) {
blocks[i][j] = 1;
}
}
In your particular case, since all the rows are initialised to be the same (a series of 1s), you can also do
var blocks = new Array(),
blockRow = new Array();
for (var i = 0; i < numCells; i++) {
blockRow.push(1);
}
for (var i = 0; i < num; i++) {
blocks.push(blockRow.slice()); // slice() makes a copy of blockRow
}