JavaScript function crashes every time it's run - javascript

I'm writing this really fantastic game in JavaScript but a part of the function I just wrote crashes every time it's run.
So I'm wondering, is it just to much to run in a for loop or have I made a syntax error somewhere?
Here's the code; it's taken from a function but this is the part that makes it crash.
for (zloop=min_houses_per_block; zloop<(house_number+1); zloop++)
{
if (zloop>0)
{
city_block_array[first][second].house_array[zloop].width =
(min_house_width+(((max_house_width-min_house_width)/house_width_slots)*(Math.floor(Math.random()*house_width_slots))));
city_block_array[first][second].house_array[zloop].height =
(min_house_height+(((max_house_height-min_house_height)/house_height_slots)*(Math.floor(Math.random()*house_height_slots))));
if (zloop=1)
{
x_number=(block_width-(house_threshold*2))-city_block_array[first][second].house_array[zloop].width;
min_house_x=house_threshold
city_block_array[first][second].house_array[zloop].x =
(min_house_x+(((x_number)/house_x_slots)*(Math.floor(Math.random()*house_x_slots))));
}
city_block_array[first][second].house_array[zloop].x=6000;
city_block_array[0][0].house_array[1].x=6000;
}
}
Without the if (zloop=1) part it runs fine.

Do you mean to say if (zloop==1)

Your error is most likely this line:
if (zloop = 1) {
This sets zloop to 1. You want to compare zloop to 1, so use zloop == 1.
Also, try to trim down on the line length. You can use some more descriptive variables:
for (var zloop = min_houses_per_block; zloop < (house_number + 1); zloop++) {
var house = city_block_array[first][second].house_array[zloop];
if (zloop > 0) {
house.width = (min_house_width + (((max_house_width - min_house_width) / house_width_slots) * (Math.floor(Math.random() * house_width_slots))));
house.height = (min_house_height + (((max_house_height - min_house_height) / house_height_slots) * (Math.floor(Math.random() * house_height_slots))));
if (zloop == 1) {
x_number = (block_width - (house_threshold * 2)) - house.width;
house.x = (house_threshold + (((x_number) / house_x_slots) * (Math.floor(Math.random() * house_x_slots))));
} else {
city_block_array[0][0].house_array[1].x = 6000;
house.x = 6000;
}
}
}

if (zloop=1)
Did you mean
if (zloop == 1)
= is an assignment
== is a comparison

Related

Random Fibonacci Generator

I'm trying to create a simple program in javascript where the Fibonacci square can be created by a random number sequence but I can't seem to connect both parts of my code. The first side being: the call for a random number and the second part: calculating the Fibonacci square.
var n = function getRandomNum() {
return Math.floor(Math.random()*100) +1;
}
function fib(x) {
if (x < 2) {
return x;
} else {
return fib(x - 1) + fib(x - 2);
}
}
console.log(fib(n));
Tell me where I'm going wrong. These are the errors I get when I run it.
RangeError: Maximum call stack size exceeded
at fib:7:13
at fib:11:12
at fib:11:12
at fib:11:12
at fib:11:12
at fib:11:12
Aside from not invoking the random number generator, you're using a very poorly optimized algorithm. If you think through all the redundant calls that need to take place, you'll see why the stack limit is reached.
var n = function getRandomNum() {
return Math.floor(Math.random() * 100) + 1;
}(); // <-- quick inline invocation... not normally how you'd use this.
console.log(n);
function fib(x) {
function _fib(x, a, b) {
if (x < 2) {
return a;
}
return _fib(x - 1, b, a + b);
}
return _fib(x, 0, 1);
}
console.log(fib(n));
Since you don't call n function, you should call it like the following.
var n = function getRandomNum() {
return Math.floor(Math.random()*100) +1;
}
function fib(x) {
if (x < 2) {
return x;
} else {
return fib(x - 1) + fib(x - 2);
}
}
console.log(fib(n));
But, there's a huge problem in your code, as #rock star mentioned, there's no any optimizing process in your code. That is why your code has caused the problem on memory leak
To avoid this, you can simply use memoization, click this link you don't have any clue on it.
Javascript Memoization Explanation?
So, your code can be improved like the folloiwng, by adapting memoization algorithm.
var n = function getRandomNum() {
return Math.floor(Math.random()*100) +1;
}
var result = [];
result[0] = 1;
result[1] = 1;
function fib(x) {
var ix, ixLen;
for(ix = 0, ixLen = x; ix < ixLen; ix++){
if(!result[ix]){
result[ix] = result[ix-2] + result[ix-1];
}
}
console.log('n:', x, ' result: ', result[ix-1]);
return result[ix-1];
}
console.log(fib(n()));
Compare the result with this site.
http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html

can i reduce my code using loop for varaible or array

now the repeating code problem has been solved but when executed the if condition function of moveHorse is being executed repeteadly. please help.
function moveHorse(horseId)
);
interval=setInterval(function(){moveHorse('horseID');},20);
}
now the repeating code problem has been solved but when executed the if condition function of moveHorse is being executed repeteadly. please help.
Pass in the element ID as the function parameter, then you can refactor the code to -
// TODO: rename your local variable name because now it doesn't need to be horse4, right?
function horseUp(horseElementId) {
var horse = document.getElementById(horseElementId);
// do the rest
}
function horseDown(horseElementId) {
var horse = document.getElementById(horseElementId);
// do the rest
}
function horseleft(horseElementId) {
var horse = document.getElementById(horseElementId);
// do the rest
}
To use the function, pass in the element Id
horseUp('horse4');
horseLeft('horse2');
and so on
Since the only part that appears to be different is the horse being changed, just pass that in. For example:
var horse4 = document.getElementById('horse4');
function horseUp(horse, moving) {
var horseTop = horse.offsetTop;
var random = Math.random() * 2.7 + 2;
horse.style.top = horseTop - 0.5 * random + 'px';
if (horseTop <= window.innerHeight * 0.05) {
clearInterval(interval4);
interval4 = setInterval(moving, 10);
}
}
There's a few other variables like interval4 that you'll need to figure out, but this should give you the general idea.
May use OOP:
function Horse(id) {
this.el = document.getElementById(id);
}
Horse.prototype={
move(x,y){
this.el.offsetTop+=(this.y=typeof y !=="undefined"?y:this.y);
this.el.offsetLeft+=(this.x=typeof x !== "undefined"?x:this.x);
},
up(){
this.move(0,0.5*Math.random() * 2.7 + 2* + 'px';
},
down(){ this.move(0,- 0.5* Math.random() * 2.4 + 2);},
left(){ this.move(0.5* Math.random() * 2.4 + 2,0);},
right(){ this.move(- 0.5* Math.random() * 2.4 + 2,0);},
setInterval(){
this.interval=setInterval(_=>this.move(),10);
}
}
use like this:
var horse4=new Horse("horse4");
horse4.setInterval();
horse4.left();

Javascript - few intervals in right order

In my code I have three intervals which should be executed random times one after the another.
var times = Math.floor((Math.random() * 3) + 2);
var turn = 0;
var schemaInterval1 = setInterval(function(){
console.log('first');
turn++;
if(turn == times)
{
times = Math.floor((Math.random() * 3) + 2);
turn = 0;
clearInterval(schemaInterval1);
}
},1000);
var schemaInterval2 = setInterval(function(){
console.log('second');
turn++;
if(turn == times)
{
times = Math.floor((Math.random() * 3) + 2);
turn = 0;
clearInterval(schemaInterval2);
}
},1000);
var schemaInterval3 = setInterval(function(){
console.log('third');
turn++;
if(turn == times)
{
times = Math.floor((Math.random() * 3) + 2);
turn = 0;
clearInterval(schemaInterval3);
}
},1000);
After each execution of the code within interval, I add 1 to the turn value. When turn and times values are equal I reset both of them. Leave currently working interval and skip to another one. But unfortunately they don't work in correct order and in my console I get that message:
first
second
third
first
second
first
(4)second
How can I rewrite my code to put those intervals in proper order and don't allow others work until first finish it's task?
You start your intervals all at the same time. If you want to run them in series, you have to start one when you clear the previous one.
This code should do what you are looking for:
var times = Math.floor((Math.random() * 3) + 2);
var turn = 0;
var intervalNumber = 1;
var intervalTime = 1000;
var numberOfIntervals = 3;
function instantiateInterval() {
if (intervalNumber <= numberOfIntervals) {
console.log('Timer number: ' + intervalNumber);
var interval = setInterval(function() {
turn++;
if(turn === times) {
times = Math.floor((Math.random() * 3) + 2);
turn = 0;
clearInterval(interval);
instantiateInterval();
}
}, intervalTime);
intervalNumber++;
}
}
instantiateInterval();

Generating Two Numbers With a Specific Sum

I'm trying to generate two numbers with a specific sum. Here is my proposed method:
Edited: http://jsfiddle.net/KDmwn/274/
$(document).ready(function () {
function GenerateRandomNumber() {
var min = -13, max = 13;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
var x = GenerateRandomNumber();
function GenerateRandomNumber2() {
var min2 = -13, max2 = 13;
var random2 = Math.floor(Math.random() * (max2 - min2 + 1)) + min2;
if ((random2 + x) == 0){
return random2};
}
var xx = GenerateRandomNumber2();
There's something wrong with the if ((random2 + x) = 0) line, as the code runs perfectly fine when it's removed. How can I modify this line so that the sum of the two numbers is 0? It would be most helpful if someone could modify the Jsfiddle that I've included. Thanks!
This is invalid:
if ((random2 + x) = 0){
You cannot assign something to an expression.
You probably meant to use the comparison operator (==), like this:
if ((random2 + x) == 0){
Are you trying to make it only output a second number that, when added to the first, equals 0? Because it actually already does that - but only if it gets it on the first try (try hitting refresh at least 30 times.) You need to tell it to keep re-choosing (looping) the second random number while the sum isn't 0:
function GenerateRandomNumber2() {
var min2 = -13,
max2 = 13;
var random2;
while ((random2 + x) !== 0) {
random2 = Math.floor(Math.random() * (max2 - min2 + 1)) + min2;
}
return random2;
}
http://jsfiddle.net/vL77hjp0/
To take this one step further, if I'm reading this right (if not ignore this) it looks like you might want to eventually choose a random sum and have it determine the required second number to be added. To do this, we would replace the 0 in our "while" loop with 'sum'. And 'sum' would have to be defined as a random number with a "max=x+13" and "min=x-13" (otherwise the random number may be too high/low for random2 to ever reach, causing the browser to crash.) [Or just remove the limits from random2.]
http://jsfiddle.net/fkuo54hc/
First, your GenerateRandomNumbers2 function returns undefined value other than in your if statement. So you need to return a value. I updated your fiddle and refactor some of your code.

Check if randomized number is in an array, if true then randomize again?

I'm creating a battleship game, and I'm trying to randomize the computer's ships. However, it sometimes randomizes the same location more than once, thus creating less than 8 ships in some rounds. I tried to fix this using indexOf but I can't seem to get it to work no matter how I change the code. If the randomized number is in the array shipLocations then I want to reroll the number again until it's a number that doesn't match any number in the array. Any ideas?
var shipLocations = [];
function randShips() {
for (i = 0; i < 8; i++) {
var randomize = Math.floor(Math.random() * 64 + 1);
if (shipLocations.indexOf(randomize) == true) {
var randomize = Math.floor(Math.random() * 64 + 1);
}
else {
shipLocations.push(randomize);
}
} //end of i loop
} //end of randShips()
randShips();
console.log(shipLocations);
EDIT: So after trying out a few of the answers, this seems to be working the way it should be after testing about 100 times.
var shipLocations = [];
function randShips() {
while (shipLocations.length < 8) {
var randomize = Math.floor(Math.random() * 64 + 1);
while (shipLocations.indexOf(randomize) > -1) {
randomize = Math.floor(Math.random() * 64 + 1);
}
shipLocations.push(randomize);
}
}
randShips();
var shipLocations = [];
function randShips() {
while ( shipLocations.length < 8 ) {
var randomize = Math.floor(Math.random() * 64 + 1);
while ( shipLocations.indexOf(randomize) >= 0 ) {
randomize = Math.floor(Math.random() * 64 + 1);
}
shipLocations.push(randomize);
}
} //end of randShips()
randShips();
console.log(shipLocations);
Since you want 8 unique values, it's quite possible that 2 numbers created in a row are both in the array already. So I think you'll want to do a while:
while (shipLocations.indexOf(randomize) != -1) {
randomize = Math.floor(Math.random() * 64 + 1);
}
The var part shouldn't be there, that is only necessary for the first instance of the variable.
In javascript false conditions are returned with a value of -1.
Hence, change the if-else condition to :
if (shipLocations.indexOf(randomize) != -1) { //true condition equivalent
var randomize = Math.floor(Math.random() * 64 + 1);
}
else {
shipLocations.push(randomize);
}
indexOf doesn't return boolean value, it returns the index (int) of the matched element.
So the code should be
if (~shipLocations.indexOf(randomize)) {
var randomize = Math.floor(Math.random() * 64 + 1);
}
You could use this function to get a true unique number that for the array.
function uniqueRandom( arr) {
var num = Math.floor(Math.random() * 64 + 1);
if (~arr.indexOf(num)) {
uniqueRandom(arr);
} else {
return num;
}
}
Btw, the logic you had written has a problem. If you found a duplicate number, you just randomize it again, without pushing it into the array. so using a while or a recursive function should do the job quite well.

Categories

Resources