Inserting value in array table js - javascript

I have the following array table:
var ticket1 = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
I want to insert values in the above array. How do I do that?
I have tried this:
ticket1[0, 0] = 20;
ticket[1, 0] = 30;
ticket[2, 0] = 40;
Expected result:
[20, 0, 0, 0, 0, 0, 0, 0, 0],
[30, 0, 0, 0, 0, 0, 0, 0, 0],
[40, 0, 0, 0, 0, 0, 0, 0, 0]
Actual result:
[20, 30, 40, 0, 0, 0, 0, 0, 0]

Consider the following example.
$(function() {
var ticket1 = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
ticket1[0][0] = 20;
ticket1[1][0] = 30;
ticket1[2][0] = 40;
$.each(ticket1, function(k, v) {
$("<p>").html(v.join(", ")).appendTo("div");
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>
Reference: https://www.w3schools.com/js/js_arrays.asp
When using a Matrix, or an Array of Arrays, you still access each Array Index. So ticket1[0] will access the first element, which is an Array of Integers, so ticket1[0][0] accesses the first index of the first array.
You can make a more complex function to update / change elements in the Matrix.
Array.prototype.mPush = function(x, y, e) {
this[x][y] = e;
return this;
}
$(function() {
var ticket1 = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
ticket1.mPush(0, 0, 20);
ticket1.mPush(1, 0, 30);
ticket1[2][0] = 40;
$.each(ticket1, function(k, v) {
$("<p>").html(v.join(", ")).appendTo("div");
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>

function add(var){
ticket.push(var)
}
Eg:
ticket.push(2)

ticket1[0][0] = 20;
posted by ozer and twisty

Related

Javascript 2d array select around from single point

Say I have a 15x15 2d array
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
See the character A? at y:9 and x:4 (index starts with 0).
What I want to do here is to update the array where I select or update the 0s around the A to, say, asterisk (*).
For an example, lets say I want 0s around the A as far as 3 indexes to be updated as *
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, *, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, *, *, *, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, *, *, *, *, *, 0, 0, 0, 0, 0, 0, 0, 0],
[0, *, *, *, A, *, *, *, 0, 0, 0, 0, 0, 0, 0],
[0, 0, *, *, *, *, *, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, *, *, *, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, *, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
What is the most efficient way to achieve this?
EDIT
What I've tried:
var s_length = 4, coordinate_y_x = [9, 4]
for (let i1 = 0; i1 < s_length; i1++) {
for (let i = 0; i < s_length; i++) {
if (map[coordinate_y_x[0] - i][coordinate_y_x[1]] != undefined) map[coordinate_y_x[0] - i][coordinate_y_x[1]] = 1
if (map[coordinate_y_x[0]][coordinate_y_x[1] - i]!= undefined) map[coordinate_y_x[0]][coordinate_y_x[1] - i] = 1
}
for (let i = s_length; i > 0; i--) {
console.log("loop2");
if (map[coordinate_y_x[0] + i][coordinate_y_x[1]]!= undefined) map[coordinate_y_x[0] + i][coordinate_y_x[1]] = 1
if (map[coordinate_y_x[0]][coordinate_y_x[1] + i]!= undefined) map[coordinate_y_x[0]][coordinate_y_x[1] + i] = 1
}
}
I managed to change what's left, right, top, and bottom from this code with given point and length, but I can't seem to figure out how to do the rest (between directions)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, A, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
One way is with a somewhat spiral matrix walk, but instead of a "square" walk, yours will be diagonal / "diamond" shape. Additionally, we don't really care about the "connectiveness" of the path, so I'll jump around a bit. That is, when a walk has finished a ring, it isn't important that the next ring start on a neighboring cell of the previous ring's last step.
In your example data, I've marked the cells that the algorithm would visit in order (1st, 2nd, 3rd, etc.)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 15, 7, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 14, 6, 2, 8, 18, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 13, 5, 1, A, 3, 9, 19, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 24, 12, 4, 10, 20, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 23, 11, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Note, I've chosen to always start from the left side of the origin, but that is arbitrary. You could start from the top, right, or bottom side.
So our three loops (in order) will be
The length we want to "expand" by can be thought of as a separate "ring." So loop each ring.
Next, loop each "side" of that ring.
Finally, loop each "step" along that side.
To keep things symmetric, each side will only occupy a single "corner" cell. So for example when looping the 3rd ring, each side would only be 3 steps each. Here I have each side labeled as a, b, c, and d.
* * * b * * *
* * a * b * *
* a * * * b *
a * * X * * c
* d * * * c *
* * d * c * *
* * * d * * *
Otherwise the only tricky part is figuring out how to change directions as you loop each side.
A very simple way to do this is store "deltas," how much we expect each x and y value (where we currently are) to change for each step. We know we'll be moving 1 step each time, so it is just a matter of moving right / down (positive +) or left / up (negative -).
I decided to store these values in an array, but you can probably do some modulo math to switch between them. Looping over a constant is just a little easier to understand. So moving up and to the right would have an x_delta value of 1 and y_delta value of -1, etc.
Finally, you need a "in bounds" check as you are completing your walk. The algo will still try and "visit" these cells, but won't try to write to the array if it doesn't exist. This is one area of the algo you can probably improve.
Put it all together, and you have this:
const data = Array(15)
.fill()
.map(v => Array(15).fill(0));
// Assumes the graph won't contain `undefined` values. Otherwise, do a `length` check on the arrays
function inBounds(data, [y, x]) {
return data?.[y]?.[x] !== undefined;
}
const deltas = [
[ 1, -1], // Up right
[ 1, 1], // Down right
[-1, 1], // Down left
[-1, -1], // Up left
];
function fillFrom({origin: [oy, ox], data, length, value}) {
// Walk in diamond "rings" around our origin
for (let size = 1; size <= length; size++) {
// Start from the left side of our ring
let x = ox - size;
let y = oy;
// Move along 4 sides of the diamond
for (let [xd, yd] of deltas) {
// Move each step along the side
for (let step = 0; step < size; step++) {
if (inBounds(data, [y, x])) {
data[y][x] = value;
}
x += xd;
y += yd;
}
}
}
return data;
}
// Updates data "in place." Would need to deep clone if you wanted to keep things immutable
fillFrom({origin: [9, 4], data, length: 3, value: 1});
data[9][4] = 'A';
console.log(data.map(r => r.join('')).join('\n'));

How I may break from this recursivity in JavaScript for a maze path finder?

I have been practicing some exercises, and among them I am now trying to create a code for finding a path inside a maze matrix created in js.
Now, this code works, it finds the correct path, and I even p[rint it to be sure its the correct one, but I am having one issue. I am not sure what to do in case my path cannot arrive to the destination.
For example, these are 2 of my samples, the correct path is marked with 1 and the "walls" with a 0:
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 1, 2],
[0, 1, 1, 1, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
But, if I cut one path, preventing my fidner to arrive to the destination, I am unable to find a way to break the recursivity.
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 2],
[0, 1, 1, 1, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
In short, I can return the correct path, but I am not sure , in case It cannot find a way to the "exit", to return "Invalid path", or "There is no path to the destination"
Bellow is the complete code:
class mazeSolver {
constructor() {
this.myMaze = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 1, 2],
[0, 1, 1, 1, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
];
this.traverse = function (column, row) {
if (this.myMaze[column][row] === 2) {
console.log("You found the exit at: " + column + "-" + row);
console.log("Path: ")
for (let i = 0; i < this.myMaze.length; i++) {
console.log(this.myMaze[i])
}
}
else if (this.myMaze[column][row] === 1) {
this.myMaze[column][row] = 8;
console.log("You passed by " + row + "-" + column);
if (column < this.myMaze.length - 1) {
this.traverse(column + 1, row);
}
if (row < this.myMaze[column].length - 1) {
this.traverse(column, row + 1);
}
if (column > 0) {
this.traverse(column - 1, row);
}
if (row > 0) {
this.traverse(column, row - 1);
}
}
};
}
}
I appreciate any input.
Thanks!
Some comments on your code:
Use console.log inside the traverse method for debugging only, not for something important as reporting the path that was found. That should actually be left to the caller to do.
If the recursive call finds the target, no other recursive call should be made. Instead that success should immediately be returned to the caller, who should do the same...
The path could be collected during backtracking. This path could be the return value in case of success (and undefined otherwise).
Do not initialise a hardcoded matrix in the constructor. Instead pass the matrix as argument to the constructor.
Make traverse a prototype method, instead of defining it on the instance.
In a matrix, we usually consider the first dimension as rows, and the second dimension as columns. You did it the other way round.
It is easier to protect your traversal against out-of-range access by the use of the ?. operator.
Here is the updated code:
class MazeSolver {
constructor(matrix) {
this.myMaze = matrix;
}
traverse(column, row) {
if (this.myMaze[row]?.[column] === 2) {
return [[column, row]]; // Return path. Caller can extend it
} else if (this.myMaze[row]?.[column] === 1) {
this.myMaze[row][column] = 8;
console.log("You passed by " + column + "," + row);
const path = this.traverse(column + 1, row)
?? this.traverse(column, row + 1)
?? this.traverse(column - 1, row)
?? this.traverse(column, row - 1);
if (path) path.unshift([column, row]); // Extend the path found
return path;
}
}
}
// Maze without solution:
const solver = new MazeSolver([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 1, 2],
[0, 1, 1, 1, 0, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]);
const path = solver.traverse(0, 3);
if (path) {
console.log("found a path (column, row):")
console.log(JSON.stringify(path));
} else {
console.log("No path found");
}
your solution doesn't work for some cases, take this example
this.myMaze = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 1, 2],
[0, 1, 1, 1, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
];
result:
You passed by 3-0
You passed by 3-1
You passed by 4-1
You passed by 5-1
You passed by 5-2
You passed by 5-3
You passed by 6-3
You passed by 7-3
You passed by 8-3
You passed by 9-3
maze.js:39
if (this.myMaze[row][column] === 2) {
^
TypeError: Cannot read property '3' of undefined
at mazeSolver.traverse (maze.js:39:33)
at mazeSolver.traverse (maze.js:50:26)
at mazeSolver.traverse (maze.js:50:26)
at mazeSolver.traverse (maze.js:50:26)
at mazeSolver.traverse (maze.js:50:26)
at mazeSolver.traverse (maze.js:50:26)
at mazeSolver.traverse (maze.js:53:26)
at mazeSolver.traverse (maze.js:53:26)
at mazeSolver.traverse (maze.js:50:26)
at mazeSolver.traverse (maze.js:50:26)
first thing I can tell about your algorithm is it's an eager algorithm, meaning
that you chose the first available path.
Second thing about recursion is you must have an exit condition that will be true at some point, you don't have it your case, you are not even exiting the function at any point.
third you are switching between column and row, column is the vertical array, row is the horizontal array.
here is a code that is an eager solution, that will at least avoid the error above
class mazeSolver {
constructor() {
this.solution_found=false;
this.myMaze = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 1, 1, 2],
[0, 1, 1, 1, 0, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
];
this.traverse = function (row, column) {
if (this.myMaze[row][column] === 2) {
this.solution_found=true;
console.log("You found the exit at: " + row + "-" + column);
console.log("Path: ")
for (let i = 0; i < this.myMaze.length; i++) {
console.log(this.myMaze[i])
}
}
else if (this.myMaze[row][column] === 1) {
this.myMaze[row][column] = 8;
console.log("You passed by " + row + "-" + column);
if (column < this.myMaze.length - 1) {
if(row +1> this.myMaze.length - 1)
return
this.traverse(row + 1, column);
}
if (row < this.myMaze[row].length - 1) {
if(column+1 > this.myMaze.length - 1)
return
this.traverse(row, column + 1);
}
if (row > 0) {
if(row-1 < 0){
return
}
this.traverse(row - 1, column);
}
if (column > 0) {
if(column-1 < 0){
return
}
this.traverse(row, column - 1);
}
}
};
}
}
maze = new mazeSolver();
maze.traverse(3, 0)
if(!maze.solution_found){
console.log('solution not found')
}
to develop an algorithm that will find the path 100% if the path exists, try doing some research on search algorithms, mainly path finding, e.g., A* heuristic or Dijkstra's Algorithm.

Why is my drawChar function's drawImage not showing?

First things first, I am trying my hand at a very simple tile map engine for 2d games using HTML5 canvas and Javascript and everything seems to be working okay except that my second drawChar function's drawImage() isn't showing on the canvas. I know the urls are good and I have checked for missing chars, etc. but cant figure it out. Code is below. Any help is appreciated.
P.S. I know that much of this code is not "modern" or "best practice", I am still learning and am just trying learn why this error is occurring. Thanks.
<canvas id="canvas" width="1000" height="500" style="border: 2px solid black; margin: 10px auto;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var draw=canvas.getContext('2d');
var tileSize=canvas.height/10;
var mapLength=canvas.width/tileSize;
var tilex=0;
var tiley=0;
var tile1= new Image();
var tile2= new Image();
var charImg= new Image();
tile1.src='https://raw.githubusercontent.com/daveboy87/Jscript-TileEngine/master/tile_sky.jpg';
tile2.src='https://raw.githubusercontent.com/daveboy87/Jscript-TileEngine/master/tile_ground.jpg';
charImg.src='https://raw.githubusercontent.com/daveboy87/Jscript-TileEngine/master/player.jpeg';
var mapArray = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1]
];
function drawMap() {
for (var y=0; y<mapLength; y++){
for (var x=0; x<tileSize; x++){
tilex=x*tileSize;
tiley=y*tileSize;
if (parseInt(mapArray[y][x]) == 0) {
draw.drawImage(tile1, tilex, tiley, tileSize, tileSize); }
if (parseInt(mapArray[y][x]) == 1) {
draw.drawImage(tile2, tilex, tiley, tileSize, tileSize); }
}
}
}
function drawChar(){
draw.drawImage(charImg, 300, 200, tileSize, tileSize); }
function nextFrame(){
draw.clearRect(0, 0, canvas.width, canvas.height);
drawMap();
drawChar();
}
setInterval(nextFrame, 1000);
You're checking mapArray[y][x] - but y and x aren't related with the size of mapArray, so you're checking for an element that doesn't exist, and getting a Javascript error, which blocks the program execution.
You should keep the Chrome developer tools open so you can see Javascript errors, which will show you the problem here.

Grid game board

I would like to quad my board game, I must create coordinates, but i don't know how to do. I need your help !! Thanks
var mapArray = [
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0]
];
function drawMap() {
var col = [];
var table = document.createElement("table");
for (var i = 0; i < mapArray.length; i++) {
for (var j = 0; j < mapArray[i].length; j++) {
if (parseInt(mapArray[i][j]) == 0) {
$('#canvas').append('<div class="grass"></div>');
}
if (parseInt(mapArray[i][j]) == 1) {
$('#canvas').append('<div class="wall"></div>');
}}}}
$('document').ready(function() {
drawMap();
});
It sounds like you need to read up on some canvas manipulation using JavaScript. Example on how to draw lines and what not. But here you go.
I have the below function which draws the grid
function drawGrid(w, h, canvas, ctx, spacing) {
canvas.width = w;
canvas.height = h;
ctx.beginPath();
ctx.strokeStyle = 'rgb(0, 0, 0, 0.35)';
ctx.lineWidth = 1;
for (var x=0; x<=w; x+=spacing) {
ctx.moveTo(x, 0);
ctx.lineTo(x, h);
}
for (var y=0;y<=h;y+=spacing) {
ctx.moveTo(0, y);
ctx.lineTo(w, y);
}
ctx.stroke();
};
Now to explain the above: I pass the width of the canvas, the height of the canvas, the canvas element, the context of the canvas and then the spacing of the grid (example: 16px) I then do a for loop to create the lines and the. I draw them.
The next part of your question is returning the cell the mouse is in. It can be done by the following code - which is two functions for simplicity
function getMousePos(canvas, evt){
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function getGridLocation(posX, posY, gridsize)
{
var cellRow = Math.floor(posY / gridsize);
var cellColumn = Math.floor(posX / gridsize);
return {
row: cellRow,
column: cellColumn
};
}
So above is first to get the mouse co-ordinates and then I use the second function which gets passed the mouse coordinates and then divides them by each cell of the grid and floors the number.
Below is how to get mouse position per cell.
gridCanvas.addEventListener('click', function(evt) {
var mousePos = getMousePos(gridCanvas, evt);
var gridLocation = getGridLocation(mousePos.x, mousePos.y, 64);
//alert("Row: " + gridLocation.row + " Column: " + gridLocation.column);
}, false);
You can do something like this:
const board = [
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
];
const markup = board.map(row => row.map(col => `<span class="field ${col === 0 ? "grass" : "wall"}"></span>` ).join("")).join("<span class='clear'></span>");
document.getElementById("container").innerHTML = markup;
.field {
float: left;
height: 20px;
width: 20px;
border: 1px solid #000;
}
.clear {
clear: both;
float: left;
}
.grass {
background: green;
}
.wall {
background: black;
}
<div id="container">

Javascript Conway's Game of Life Issues

I'm trying to make Conway's Game of Life in javascript. I made a function to count neighbors, and a function that produces the next generation of cells. However, I tried a test input, and the result isn't coming out right, and I can't find where the error is. Please help.
Here's the code:
(code attached)
/* Draws grid */
for (var i = 0; i < 15; i++) {
for (var j = 0; j < 15; j++) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "grey";
ctx.strokeRect(10 * j, 10 * i, 10, 10);
}
}
/* draws live cells */
function drawSquares(a) {
for (var i = 0; i < 15; i++) {
for (var j = 0; j < 15; j++) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#000000";
if (a[i][j] === 1) {
ctx.fillRect(10 * j, 10 * i, 10, 10);
}
}
}
}/* Counts neighbors */
function neighborCount(a, i, j, height, width){
var lifes = 0;
var neighbors = [
[-1, 1],
[0, 1],
[1, 1],
[-1, 0],
[1, 0],
[-1, -1],
[0, -1],
[1, -1]
];
/* loops through a cell's neighbors */
for (var z = 0; z < 8; z++){
/*checks if the neighbor isn't off the grid*/
if ((i + neighbors[z][0]) >=0 && (i + neighbors[z][0]) < height && (j + neighbors[z][1]) >=0 && (j + neighbors[z][1]) < width){
/*checks if it's alive*/
if (a[i + neighbors[z][0]][j + neighbors[z][1]] === 1){
lifes++;
}
}
}
return lifes;
}
/* game of life */
function life(a) {
var n = a; /*new generation of life */
var lifes = 0; /*neighbor counter*/
var height = a.length;
var width = a[0].length;
/*loops through all cells*/
for (var i = 0; i < height; i++){
for (var j = 0; j < width; j++){
lifes = neighborCount(a, i, j, height, width);
/* kills alive cells */
if(a[i][j] === 1 && (lifes < 2 || lifes > 3)){
n[i][j] = 0;
}
/* brings dead cells to life */
else if (a[i][j] === 0 && lifes ===3){
n[i][j] = 1;
}
}
}
drawSquares(n);
return(n);
}
/* test input */
var a = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
];
/* expected result:
var a = [
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]; */
life(a);
<canvas id="myCanvas" width="150" height="150"></canvas>

Categories