Jump to content
  • Advertisement
Sign in to follow this  
Durakken

Help. Javascript Code Is Breaking Sometimes When Ran...

This topic is 857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So i'm having a problem here. The code will go into an infinite loop or seems to break and the population seems to stop growing at a low number.

But this only happens sometimes.

At the end of every 12 months it's supposed to show the year and population and it's working, but only some of the time.

I suppose the inconsistency of the population numbers could just be coincidence, but it doesn't seem like it to me and the infiniteloop or whatever is happening that makes it take a longer time to process than i'm willing to wait points to there being a problem, but I can't see it.

//y = year
//py = previous year
// Age is based on months, not years
py = 0;

var Women = new Array();
var Men = new Array();
var Woman = {ID: 0, Age: 240, SinceLastBirth: 0, Pregnant: "no", MonthsPregnant: 0, Dead: "no"};
var Man = {ID: 0, Age: 240, Soldier: "no", Dead: "no"};
Women.push(Woman);
Men.push(Man);
	
for(i = 0; i < 18001; i++) {

	for(x = 0; x < Women.length; x++) {
		Women[x].Age++;
	}
	
	for(x = 0; x < Women.length; x++) {
		if(Women[x].Age <= 168 && Women[x].Dead == "no") {
			DeathCheck = Math.random();
			if(DeathCheck <= 0.00166) {
				Women[x].Dead = "yes";
			}
		}
	}
	
	for(x = 0; x < Women.length; x++) {
		if(Women[x].Pregnant == "yes" && Women[x].Dead == "no") {
			MiscarryCheck = Math.random()
			if(MiscarryCheck <= 0.036){
				Women[x].Pregnant = "no"
				Women[x].MonthsPregnant = 0;
			} else {
				Women[x].MonthsPregnant++;
			}
		}
		if(Women[x].MonthsPregnant >= 9 && Women[x].Dead == "no") {
			Sex = Math.floor((Math.random() *2) +1);
			if(Sex == 2) {
				Man = {ID: 0, Age: 0, Soldier: "no", Dead: "no"};
				Men.push(Man);
			} else {
				Woman = {ID: 0, Age: 0, SinceLastBirth: 0, Pregnant: "no", MonthsPregnant: 0, Dead: "no"};
				Women.push(Woman);
			}
			BirthDeathCheck = Math.random();
			if(BirthDeathCheck < 0.01) {
				Women[x].Dead = "yes";
			} else {
				Women[x].MonthsPregnant = 0;
				Women[x].SinceLastBirth = 48;
			}
		}
	}

	for(x = 0; x < Women.length; x++) {
		if(Women[x].Age >= 168 && Women[x].Age <= 1860 && Women[x].SinceLastBirth <= 0 && Women[x].Dead == "no") {
			PregnantCheck = Math.random();
			if(PregnantCheck <= 0.05 && Women[x].Pregnant == "no") {
				Women[x].Pregnant = "yes";
			}
		}
		if(Women.SinceLastBirth > 0  && Women[x].Dead == "no") {
			Women.SinceLastBirth--;
		}
	}
	
	m = 0;
	y = 0;
	for(x = 0; x <= i; x++) {
		if(m == 12) {
			y++;
			m = 0;
		}
		m++
	}
	
	if(y > py) {
		Population = 0;
		for(x = 0; x < Men.length; x++) {
			if(Men[x].Dead == "no") {
				Population++
			}
		}
		for(x = 0; x < Women.length; x++) {
			if(Women[x].Dead == "no") {
				Population++
			} 
		}
		document.write(y + " : " + Population + "<br />");
		py = y;
	}
}
Edited by Durakken

Share this post


Link to post
Share on other sites
Advertisement

Figured it out... still some annoyances I haven't worked out but this particular problem was fixed. Thanks anyways

Share this post


Link to post
Share on other sites

Figured it out... still some annoyances I haven't worked out but this particular problem was fixed. Thanks anyways

 

It's generally very good form to explain what you have figured out/fixed so that other people finding this question via Google with a similar problem get the benefit of your experience.

 

I can't put into words how frustrating it is to have a problem and being able to find evidence that someone else had that same problem and that they fixed it but didn't bother to share what the fix was. :)

Share this post


Link to post
Share on other sites

I can't put into words how frustrating it is to have a problem and being able to find evidence that someone else had that same problem and that they fixed it but didn't bother to share what the fix was.

As always, xkcd has a relevant comic:

https://xkcd.com/979/ 

Share this post


Link to post
Share on other sites

As always, xkcd has a relevant comic:
 

 

I personally am so much happier seeing no answer than I am when I see "nevermind, fixed." In the first case, maybe I'm the first one who will ever actually figure this out; in the second case, I'm just a chump trying to keep up with those who've gone before.

 

I like being a trail blazer way more than I like being a chump. :p

Share this post


Link to post
Share on other sites

Well the vast amount of prints/alerts made it hard to pin down till figured out how to handle that. Once I did it was just stupid minor errors probably because I was up late where I missed the array reference and some stupid stuff like that...

 

I still need to add in soldiering deaths to what I have but other than that it's finished more or less for the base level of what I want. If anyone can help make it run faster I'd apreciate it, because it struggles on my PC to run through it with fairly low numbers. I would like to be able to get the numbers to higher population numbers, but meh. And i might add in a family tree output, but not till later most likely ^.^.The biggest problem is getting the population statistics right. If I set them just a little higher (and more accurately) the population quickly dies off and then there is the fact that I can't find how exactly to model the death rate per month of a persons life... Oh well... Here's the updated code...

 

Oh also can't figure out how to make the do while loop to end on a year rather than a month which makes the last "year" lower than the 1000 members in a population number and why I just put a population write after that final loop. There should be a away to fix it but meh.

 

Also ID is currently useless right now, but if I ever wanted to print out the list of relations it would be used to ID mother/father.

// Age is based on months, not years
py = 0;
Population = 0;
PregPop = 0;

var Women = new Array();
var Men = new Array();
var Woman = {ID: 0, Age: 240, SinceLastBirth: 0, Pregnant: "no", MonthsPregnant: 0, Dead: "no"};
var Man = {ID: 0, Age: 240, Soldier: "no", Dead: "no"};
Women.push(Woman);
Men.push(Man);
Population = Population + 2;
	
	i = 0;
do {
//for(i = 0; i < 3601; i++) {
	
	for(x = 0; x < Women.length; x++) {
		
		if(Women[x].Dead == "no") {
			Women[x].Age++;
		
			if(Women[x].Age <= 168) {
				DeathCheck = Math.random();
				if(DeathCheck <= 0.00083) {
					Women[x].Dead = "yes";
					Population--;
					//document.write("Dead before 14 <br />");
				}
			}
	
			DeathProb = 0;
			if(Women[x].Age > 168) {
				DeathCheck = Math.random();
				if(Women[x].Age >= 3024) {
					DeathProb = 0.02;
				} else {
					y = 0;
					while(y < Women[x].Age) {
						DeathProb = DeathProb + 0.000000661;
						y++;
					}
				}
				if(DeathCheck <= DeathProb) {
					Women[x].Dead = "yes";
					Population--;
					//document.write("Woman Dead <br />");
				}
			}
	
			if(Women[x].Pregnant == "yes") {
				MiscarryCheck = Math.random()
				if(MiscarryCheck <= 0.036){
					Women[x].Pregnant = "no";
					Women[x].MonthsPregnant = 0;
					PregPop--;
					//document.write("Miscarry <br />");
				} else {
					Women[x].MonthsPregnant++;
					//document.write("Pregnancy month added <br />");
				}
			}
			if(Women[x].MonthsPregnant >= 9) {
				Sex = Math.floor((Math.random() *2) +1);
				if(Sex == 2) {
					Man = {ID: Men.Length + 1, Age: 0, Soldier: "no", Dead: "no"};
					Men.push(Man);
					//document.write("Baby Boy Born<br />");
				} else {
					Woman = {ID: Women.length + 1, Age: 0, SinceLastBirth: 0, Pregnant: "no", MonthsPregnant: 0, Dead: "no"};
					Women.push(Woman);
					//document.write("Baby Girl Born<br />");
				}
				Population++;
				BirthDeathCheck = Math.random();
				if(BirthDeathCheck < 0.01) {
					Women[x].Dead = "yes";
					Population--;
					//document.write("Mother died in birth<br />");
				} else {
					//document.write("Mother didn't die in birth <br />");
					Women[x].MonthsPregnant = 0;
					Women[x].SinceLastBirth = 48;
				}
				Women[x].Pregnant = "no";
				PregPop--;
			}

			if(Women[x].Age >= 168 && Women[x].Age <= 1860 && Women[x].SinceLastBirth <= 0) {
				PregnantCheck = Math.random();
				if(PregnantCheck <= 0.013 && Women[x].Pregnant == "no") {
					Women[x].Pregnant = "yes";
					PregPop++;
					//document.write("Woman got pregnant <br />");
				}
			}
			if(Women[x].SinceLastBirth > 0 ) {
				Women[x].SinceLastBirth--;
				//document.write("Since Last Birth working<br />");
			}

		}
	}
		
	for(x = 0; x < Men.length; x++) {
		
		if(Men[x].Dead == "no") {
			Men[x].Age++;
		
			if(Men[x].Age <= 168) {
				DeathCheck = Math.random();
				if(DeathCheck <= 0.00083) {
					Men[x].Dead = "yes";
					Population--;
					//document.write("Dead before 14 <br />");
				}
			}
	
			DeathProb = 0;
			if(Men[x].Age > 168) {
				DeathCheck = Math.random();
				if(Men[x].Age >= 3024) {
					DeathProb = 0.02;
				} else {
					y = 0;
					while(y < Men[x].Age) {
						DeathProb = DeathProb + 0.000000661;
						y++;
					}
				}
				if(DeathCheck <= DeathProb) {
					Men[x].Dead = "yes";
					Population--;
					//document.write("Man Dead <br />");
				}
			}
		}
	}
	
	m = 0;
	y = 0;
	for(x = 0; x <= i; x++) {
		if(m == 12) {
			y++;
			m = 0;
		}
		m++
	}
	
	if(y > py) {
		WPop = 0;
		for(x = 0; x < Women.length; x++) {
			if(Women[x].Dead == "no") {
				WPop++;
			} 
		}
		PercWomenPreg = ((PregPop / WPop) * 100).toFixed(2);

		document.write(y + " : " + Population + " | " +PercWomenPreg+ "%<br />");
		py = y;
	}
	i++
} while(Population < 1001 || Population <= 0);
		Dead = 0;
		for(x = 0; x < Women.length; x++) {
			if(Women[x].Dead == "yes") {
				Dead++;
			}
		}
		for(x = 0; x < Men.length; x++) {
			if(Men[x].Dead == "yes") {
				Dead++;
			}
		}
		document.write("Dead: " +Dead + " | Pop: " +Population);
Edited by Durakken

Share this post


Link to post
Share on other sites

At least your year and month calculations can be simplified.

Instead of a loop, you can just do integer division and modulo.

y = months / 12

m = months % 12

 

Apart from that, maybe delete (or move, if you need to keep history of them) the people marked as dead?

By not having them in your lists, you might be able to skip some iteration time.

Alternatively, at the beginning of your loops, continue (I think that's also a valid javascript keyword?) if == dead.

 

Related, might it be better to have a boolean instead of a string for the "yes"/"no" checks?

I would imagine a string comparison being a lot more expensive than a boolean check.

Share this post


Link to post
Share on other sites

At least your year and month calculations can be simplified.

Instead of a loop, you can just do integer division and modulo.

y = months / 12

m = months % 12

 

Apart from that, maybe delete (or move, if you need to keep history of them) the people marked as dead?

By not having them in your lists, you might be able to skip some iteration time.

Alternatively, at the beginning of your loops, continue (I think that's also a valid javascript keyword?) if == dead.

 

Related, might it be better to have a boolean instead of a string for the "yes"/"no" checks?

I would imagine a string comparison being a lot more expensive than a boolean check.

 

I'll look at the year month thing in a bit, but I tried using 

 

} while((Population < 1001 && i % 12 == 0 )|| Population <= 0);

 

which didn't work, can that not be done?

 

The moving people from the population arrays to a dead population array thing... I don't know how to do that. But it doesn't seem like it would save time as the average number when aiming for 1000 pop is around 300.

 

I don't think continue is a valid js keyword, but I've already got the equive as the second if.

 

boolean is quicker I think... I guess i'll change that soon.

 

also... The speed of the script right now seems to be about the same speed as executing this...

var scalingExp = .75;

for (pop = 0; pop <300001; pop++) {
HomeRange = Math.pow(pop, scalingExp).toFixed(1);
document.write("Pop: " +pop+ " | Home range size: " +HomeRange+ " square km <br />");
}

So 1500-ish running is running about the same speed as 300,000 of these power equations.

Share this post


Link to post
Share on other sites

Made several changes and so far it looks like it completes almost instantly when set to 1000 pop 

EDITED because I changed the DeathProb thing from a loop to a straight calculation and that pretty much eliminated the delay.

// Age is based on months, not years
Population = 0;
PregPop = 0;
Months = 0;
Years = 0;

var Women = new Array();
var Men = new Array();
var DeadWomen = new Array();
var DeadMen = new Array();
var Woman = {ID: 0, Age: 240, SinceLastBirth: 0, Pregnant: false, MonthsPregnant: 0, Dead: false};
var Man = {ID: 0, Age: 240, Soldier: false, Dead: false};
Women.push(Woman);
Men.push(Man);

do {

for(x = 0; x < Women.length; x++) {

Women[x].Age++;

if(Women[x].Age <= 168) {
DeathCheck = Math.random();
if(DeathCheck <= 0.00083) {
Women[x].Dead = true;
//document.write("Dead before 14 <br />");
}
}

DeathProb = 0;
if(Women[x].Age > 168) {
DeathCheck = Math.random();
if(Women[x].Age >= 3024) {
DeathProb = 0.02;
} else {
DeathProb = Women[x].Age * 0.000000661;
}
if(DeathCheck <= DeathProb) {
Women[x].Dead = true;
//document.write("Woman Dead <br />");
}
}

if(!Women[x].Dead) {
if(Women[x].Pregnant) {
MiscarryCheck = Math.random()
if(MiscarryCheck <= 0.036){
Women[x].Pregnant = false;
Women[x].MonthsPregnant = 0;
PregPop--;
//document.write("Miscarry <br />");
} else {
Women[x].MonthsPregnant++;
//document.write("Pregnancy month added <br />");
}
}
if(Women[x].MonthsPregnant >= 9) {
Sex = Math.floor((Math.random() *2) +1);
if(Sex == 2) {
Man = {ID: Men.Length + 1, Age: 0, Soldier: false, Dead: false};
Men.push(Man);
//document.write("Baby Boy Born<br />");
} else {
Woman = {ID: Women.length + 1, Age: 0, SinceLastBirth: 0, Pregnant: false, MonthsPregnant: 0, Dead: false};
Women.push(Woman);
//document.write("Baby Girl Born<br />");
}
BirthDeathCheck = Math.random();
if(BirthDeathCheck < 0.01) {
Women[x].Dead = true;
//document.write("Mother died in birth<br />");
} else {
//document.write("Mother didn't die in birth <br />");
Women[x].MonthsPregnant = 0;
Women[x].SinceLastBirth = 48;
}
Women[x].Pregnant = false;
PregPop--;
}

if(Women[x].Age >= 168 && Women[x].Age <= 1860 && Women[x].SinceLastBirth <= 0) {
PregnantCheck = Math.random();
if(PregnantCheck <= 0.013 && Women[x].Pregnant == false) {
Women[x].Pregnant = true;
PregPop++;
//document.write("Woman got pregnant <br />");
}
}
if(Women[x].SinceLastBirth > 0 ) {
Women[x].SinceLastBirth--;
//document.write("Since Last Birth working<br />");
}

} else {
DeadWomen.push(Women[x]);
Women.splice(x,1);
}
}

for(x = 0; x < Men.length; x++) {

Men[x].Age++;

if(Men[x].Age <= 168) {
DeathCheck = Math.random();
if(DeathCheck <= 0.00083) {
Men[x].Dead = true;
//document.write("Dead before 14 <br />");
}
}

DeathProb = 0;
if(Men[x].Age > 168) {
DeathCheck = Math.random();
if(Men[x].Age >= 3024) {
DeathProb = 0.02;
} else {
DeathProb = Men[x].Age * 0.000000661;
}
if(DeathCheck <= DeathProb) {
Men[x].Dead = true;
//document.write("Man Dead <br />");
}
}
if(!Men[x].Dead) {

} else {
DeadMen.push(Women[x]);
Men.splice(x,1);
}
}

m = Months % 12
if(m == 0 && Months != 0) {
Years++;
Population = Women.length + Men.length;
PercWomenPreg = ((PregPop / Women.length) * 100).toFixed(2);
document.write(Years + " : " + Population + " | " +PercWomenPreg+ "%<br />");
}

Months++;

} while(Population < 1001 || Population <= 0);
Dead = DeadWomen.length + DeadMen.length;
document.write("Dead: " +Dead + " | Pop: " +Population);
Edited by Durakken

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!