Resetting the iterator in a for...in loop - javascript

This is part of the code I am using to draw some random circles:
if(circles.length != 0) { //1+ circles have already been drawn
x = genX(radius);
y = genY(radius);
var i = 0;
iCantThinkOfAGoodLabelName:
for(i in circles) {
var thisCircle = circles[i];
if(Math.abs(x-thisCircle["x"])+Math.abs(y-thisCircle["y"])>radius*2) {
//overlaps
} else {
//overlaps
x = genX(radius);
y = genY(radius);
continue iCantThinkOfAGoodLabelName;
}
if(i == circles.length - 1) { //Last iteration
//Draw circle, add to array
}
}
}
The problem is that when there is an overlap, the circle with the newly generated coordinates is not checked for overlap with the circles that the overlapping circle had already been checked with. I have tried setting i to 0 before using the continue statement but that did not work. Please help, I am really confused.

You should not use for ... in on arrays.
Use for(var i = 0; i < circles.length; ++i) instead. Then you can reset by setting i = 0.

Why not use a standard for loop
for (var i=0,l = circles.length;i < l; i++) {
....
if (i === l) {
// draw
}
}

I'm not fully understanding the question, but I do not believe you can reset the iterations of a for..in. You'll need to go to a for(var i=0;...;i++).

Related

Simulation of mouses moving, don't work

I'm trying to create a simulation of 150 mouses moving inside a 20x20 grid in p5.js (A processing like libary). First I'm spawning 150 mouses random places and everything goes fine. But after I have spawned the mouses I am trying to make them move to one of their neighbors. Instead of moving to one of the neighbors and make the current square empty it stays on the one that it already was one + it moves to the next one so instead of having 150 mouses i suddenly have 300... I have tried changing the code for hours but I can't find the proplem... Here is my code:
var w = 40;
var grid = [];
var mouses = 10;
var mouseAmount = [];
var Mouse;
var current;
function setup() {
createCanvas(800, 800);
cols = floor(width/w)
rows = floor(height/w)
// frameRate(60);
for (var j = 0; j < rows; j++) {
for ( var i = 0; i < cols; i++) {
var cell = new Cells(i,j);
grid.push(cell);
}
}
amount = new Amount;
}
function draw() {
background(51);
for ( var i = 0; i < grid.length; i++) {
grid[i].show();
}
amount.run();
}
function index(i, j) {
if (i < 0 || j < 0 || i > cols-1 || j > rows-1 ) {
return -1;
}
return i + j * cols;
}
function Cells(i, j) {
this.i = i;
this.j = j;
this.active = false;
this.moveCell = function() {
var neighbors = [];
var top = grid[index(i, j -1)];
var right = grid[index(i+1, j)];
var bottom = grid[index(i, j+1)];
var left = grid[index(i-1, j)];
if (top) {
neighbors.push(top)
}
if (right) {
neighbors.push(right)
}
if (bottom) {
neighbors.push(bottom)
}
if (left) {
neighbors.push(left)
}
if(neighbors.length > 0) {
var r = floor(random(0, neighbors.length));
return neighbors[r];
} else {
return undefined;
}
}
this.show = function() {
var x = this.i*w;
var y = this.j*w;
stroke(255);
noFill();
rect(x,y,w,w);
if(this.active == true) {
fill(155, 0, 255, 100)
rect(x, y, w, w)
}
}
}
function Amount() {
this.run = function() {
var r = floor(random(grid.length))
for (var i = 0; i < mouses; i++) {
var mouse = grid[r];
mouseAmount.push(mouse)
}
if (mouseAmount.length < 1499) {
for (var i = 0; i < mouseAmount.length; i++) {
mouseAmount[i].active = true;
}
}
if (mouseAmount.length > 1499) {
Next();
}
}
}
function Next(i,j) {
for (var i = 0; i < mouseAmount.length; i++) {
current = mouseAmount[i];
var nextCell = current.moveCell();
if (nextCell) {
nextCell.active = true;
current.active = false;
current = nextCell;
}
}
}
Thank you in advance :)
I don't really understand exactly what your code is supposed to do, but a few things stand out to me about your code:
Problem One: I don't understand how you're iterating through your grid array. You seem to be iterating over mouseAmount, which seems to hold random cells from the grid for some reason? That doesn't make a lot of sense to me. Why don't you just iterate over the grid array directly?
Problem Two: You then move the cells randomly to a neighbor, but you don't take into account whether the neighbor is already active or not. I'm not sure what you want to happen, but this seems a bit strange.
Problem Three: Usually with simulations like this, you have to copy the next generation into a new data structure instead of modifying the data structure as you step through it.
The biggest problem is that you haven't really explained what you want your code to do, or what this code does instead, or how those two things are different. But if I were you, I'd make the following changes:
Step One: Iterate over your grid array in a more reasonable way. Just iterate over every index and take the appropriate action for every cell. If I were you I would just use a 2D array and use a nested for loop to iterate over it.
Step Two: Make sure your logic for moving to a neighbor is correct. Do you want cells to move to already active cells?
Step Three: Make a copy of the grid before you modify it. Think about it this way: as you iterate over the grid, let's say you move a cell down one row. Then you continue iterating, you'll reach the newly active cell again. In other words, you'll touch the same active cell twice in one generation, which is definitely going to mess you up.
A word of advice: get this working for a single active cell first. It's really hard to tell what's going on since you have so many things going on at one time. Take a step back and make sure it works for one active cell before moving up to having a whole grid.

matrix rotation in javascript via a html button

( i'm not english but i'll try my best to explain )
i have some issues to rotate a matrix after a click on a button
i tried this
How to rotate a matrix in an array in javascript
but i failed to adapt it to my code .
so here is my html button :
<script type="text/javascript" src="genmap.js"></script>
<button onclick="rotate()">Tourner -></button>
<div style="display:auto;">
<canvas id="main" height="2000" width="5000"></canvas>
</div>
and my matrix ( square ) is randomly generated and look like this :
var map = [];
for(var i=0; i < size; i++) {
map[i] = new Array(size);
}
for(var j = 0; j < size; j++){
for ( var i = 0; i < size ; i++){
map[j][i] = Math.floor ( Math.random() * 2 );
}
}
i use a tuto for canvas , and my script begin with
(function main(isometric) {
and end with
})(this);
i don't know if i should put my function rotate in or out ...
neither how to trigger it with a click on " tourner -> "
i think i need to duplicate ( and rename ) my script but with map2 instead of map and change the random generation with the rotation from map , but i don't even know if it's possible :/
i tried this
for(var j = 0; j < size; j++){
for ( var i = 0; i < size ; i++){
maproteun[i][j] = map[size-i][j];
}
}
after the map generation but for some reason , it stop the creation of the first matrix and don't even draw the map
can you please help me ?
EDIT : things are moving
i'm able to clear the canvas , but i'm unable to reload the function ( or it doesn't work ) to redraw one
i use clearRect to clear it , but if i write
main();
it don't redo the function
Without access to your source it's kind of hard to guess where it could be tripping up within the code. From your description it sounds like you have the clear working when you click rotate button however there is no further drawing.
Did you check for syntax errors in the console? Chrome Menu > More Tools > JavaScript Console.
I've written up a simple sample here using the original source of the tutorial (minus the enclosure) and added a Rotate button: http://jsfiddle.net/goet30ww/2/
Apart from the clearRect which you added, before the drawing loops, I also added a rotate function:
function allowRotate() {
// Display the rotate button once images have loaded and map is drawn
var rot = document.getElementById("rotate")
rot.style.visibility = "visible"
// On click rotate map and redraw
rot.addEventListener("click", function(e) {
var maproteun = [];
var size = map[0].length;
for (var j = 0; j < size; j++) {
maproteun[j] = [];
for ( var i = 0; i < size ; i++) {
maproteun[j][i] = map[size - i - 1][j];
}
}
map = maproteun;
drawMap();
});
}
Thanks.
const matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
];
const rotateMatrix = (arr, col) => arr.map( row => row[col]);
/* matrix[0] - is to check on the column length for any N * N rotation */
const clockWise = matrix[0].map((row,i) => {
return rotateMatrix(matrix, i).reverse();
});
console.log('CLOCK WISE');
console.log(clockWise);
console.log('**********************************');
const antiClockWise = matrix.map((row,i) => {
return rotateMatrix(matrix, matrix.length -1 -i).reverse();
});
console.log('ANTI CLOCK WISE');
console.log(antiClockWise);

Filling up a 2D array with random numbers in javascript

I'm really sorry if anything like this has been posted here before but I couldn't find anything, I'm kinda new to the site still!
So for a while now I've been learning a bit about game development through html5 and javascript and I stumbled upon making tileset maps, I now have a tileset and an 2D array that I want to put certain tiles in (the number varies between 6 and 10 in this case).
I figured it could be a cool function to make the map choose between a small set of similar tiles so I don't have to specifically number every tile in the array(just define the type)
The method I have currently is probably the best for being able to define types but I want something that looks a bit cleaner and/or information to why my "cleaner" version dosen't work.
var ground = [
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()],
[tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile(),tile()]];
function tile() {
var y = (Math.random() * 5 | 0) + 6;
return y;
}
This is the code I've been using so far, I have to edit every element of the code with the tile() function to get a random number in each one, what I wanted to have was something like this:
for (var i = 0 ; i < 15; i++) {
for (var j = 0; j < 9; j++) {
ground[[i],[j]] = (Math.random() * 5 | 0) + 6;
}
}
to fill the array without having to add the function to each spot.
I have a feeling that I'm missing a return function or something along those lines but honestly I have no idea.
You were thinking in the right direction but there are some errors in your code ;)
You have to initialize the array first before you can push elements into it.
And you were counting i++ twice
Javascript
var ground = []; // Initialize array
for (var i = 0 ; i < 15; i++) {
ground[i] = []; // Initialize inner array
for (var j = 0; j < 9; j++) { // i++ needs to be j++
ground[i][j] = (Math.random() * 5 | 0) + 6;
}
}
Maybe even better (reusable)
function createGround(width, height){
var result = [];
for (var i = 0 ; i < width; i++) {
result[i] = [];
for (var j = 0; j < height; j++) {
result[i][j] = (Math.random() * 5 | 0) + 6;
}
}
return result;
}
// Create a new ground with width = 15 & height = 9
var ground = createGround(15, 9);
Here's a quick example. I've created a function that will take in a width and height parameter and generate the size requested. Also I placed your tile function inside generate ground to keep it private, preventing other script from invoking it.
var ground = generateGround(10, 10); //Simple usage
function generateGround(height, width)
{
var ground = [];
for (var y = 0 ; y < height; y++)
{
ground[y] = [];
for (var x = 0; x < width; x++)
{
ground[y][x] = tile();
}
}
return ground;
function tile()
{
return (Math.random() * 5 | 0) + 6;
}
}
http://jsbin.com/sukoyute/1/edit
Try removing the comma from...
ground[[i],[j]] = (Math.random() * 5 | 0) + 6;
...in your 'clean' version. Also, your incrementing 'i' in both for loops:
for (var i = 0 ; i < 15; i++) {
for (var j = 0; j < 9; i++) {
Hopefully these changes make it work for you :)

Determining array's coordinates with a string

The title is already saying. I need to determinate array's coordinates with a string.
As for example: if I want to move the value 1 to the right twice, I'm going to write in my seed variable: "rr". The r means that the value will be moved one index to the right.
In this link: http://jsfiddle.net/Kike/hVczZ/ I'm explaining better.
This works if the movement is possible :
for(var t = array.length; t >= 0; t--){
if(array[t]==1){
move(t,seed);
break;
}
}
function move(index,movements){
var size=5;
var x=index % size;
var y= Math.floor(index / size);
for(var i=0;i<movements.length;i++){
var pos=movements[i];
if(pos=='r'){
if(x+1 == size){
x=0;
y+=1;
}else{x+=1;}
}else if(pos=='l'){
if(x==0){
y-=1;
x=size-1;
}else{x-=1;}
}else if(pos=='u'){
y-=1;
}else if(pos=='d'){
y+=1;
}
}
array[index]=0;
array[size*y+x]=1;
}
console.log(array) // 1 is in fourth position

Trying to read this Javascript loop

I'm trying to read this code. As far as I can tell, it's checking if the child element is "at position" (but it's equal to a string? That makes no sense to me). If it isn't, then it adds 2 to the offset, if it is, it does nothing.
var p = document.getElementById(parent);
var c = document.getElementById(child );
var top = (c["at_position"] == "y") ? p.offsetHeight+2 : 0;
var left = (c["at_position"] == "x") ? p.offsetWidth +2 : 0;
And then here, this for loop does not make sense to me - why does it start with a semicolon?
for (; p; p = p.offsetParent)
{
top += p.offsetTop;
left += p.offsetLeft;
}
Can anyone clarify how to read this a little bit better? I'm trying to reduce the distance between the parent and the child to a limited extent (Only for "left")
It loops while p is truethy that is, p is not null because offsetParent will likely be null once your reach the top.
It's equivalent to:
var p = document.getElementById(parent);
while (p !== null) {
top += p.offsetTop;
left += p.offsetLeft;
p = p.offsetParent;
}
Normally a for loop looks like this:
for (var i = 0; i < array.length; i += 1) {
the first bit var i = 0 is the initialization part. You can leave it empty like:
var i = 0;
for (; i < array.length; i += 1) {
You can also do this:
for (var i = 0, j = 10 - i; i < array.length; i += 1, j -= 1) {
Although there are perhaps better ways to do it. Just showing you the syntax :)
The second part is the part that must be truethy, if it's false the for loop will stop. This can't be empty of course.
The last part is the incrementer part, which can also be empty. So you could have:
var p = document.getElementById(parent);
for (; p ;) {
p = p.offsetParent;
}
It looks weird, but works. I wouldn't recommend this though because it looks weird, and by that I mean that it looks like a bug.

Categories

Resources