0

I'm a total beginner trying to write code to roll on a series of branching d100 tables (the results of the first table determine which table is rolled on next, and so on).

I've gotten it to work by writing it all as one function, but because I'd like to loop a particular table several times while still referencing the results of the previous table, I'd like to do it as a series of nested functions.

The issue I'm running into is that if I nest the same code that worked as one function into a function within the parent function, EDIT: yearResults is now being written to the HTML but monthResults is coming back as undefined

Is there a way I can make this work? Is this a stupid way to go about trying to achieve this? Thank you for your help.

function fullRoll() {
var yearRoll
var yearResults
var monthRoll
var monthResults
// Rolls 1d100 on Yearly Events Table
function annualTable() {
 var yearRoll = Math.floor(Math.random()*(100-1+1)+1);
 // Interprets the results of the roll
 if (yearRoll >= 1 && yearRoll <= 10) { 
 yearResults = "Ambassador";
 } else if (yearRoll >= 11 && yearRoll <= 15) {
 yearResults = "Assassination";
 } else if (yearRoll >=16 && yearRoll <= 30) {
 yearResults = "Birth";
 } else if (yearRoll == 31) {
 yearResults = "Comet";
 } else if (yearRoll >=32 && yearRoll <=40) {
 yearResults = "Death";
 } else if (yearRoll >=41 && yearRoll <= 43) {
 yearResults = "Earthquake";
 } else if (yearRoll >=44 && yearRoll <= 47) {
 yearResults = "Famine";
 } else if (yearRoll >=48 && yearRoll <= 52) {
 yearResults = "Fire";
 } else if (yearRoll >=53 && yearRoll <= 57) {
 yearResults = "Flood";
 } else if (yearRoll == 58) {
 yearResults = "Incursion";
 } else if (yearRoll >= 59 && yearRoll <= 68) {
 yearResults = "Marriage";
 } else if (yearRoll == 69) {
 yearResults = "Religion";
 } else if (yearRoll >= 70 && yearRoll <= 74) {
 yearResults = "Plague";
 } else if (yearRoll >= 75 && yearRoll <= 78) {
 yearResults = "Plot";
 } else if (yearRoll >= 79 && yearRoll <= 87) {
 yearResults = "Rebellion";
 } else if (yearRoll == 88) {
 yearResults = "Visitation";
 } else if (yearRoll >= 89 && yearRoll <= 100) {
 yearResults ="War";
 } 
}
// Determines the Results of a Roll on the Monthly Event Table
function monthlyTable() {
 //Rolls on Monthly Table for Manmade Disasterss
 if (yearResults == "Assassination" || yearResults == "Incursion" || yearResults == "Plot" || yearResults == "Rebellion" || yearResults == "War") {
 monthRoll = Math.floor(Math.random()*(100-1+1)+1);
 if (monthRoll >= 1 && monthRoll <= 5) { 
 var monthResults = "Accident1";
 } else if (monthRoll >= 6 && monthRoll <= 10) {
 monthResults = "Bandits1";
 } else if (monthRoll >=11 && monthRoll <= 15) {
 monthResults = "Birth1";
 } else if (monthRoll >= 16 && monthRoll <=20) {
 monthResults = "Death1";
 } else if (monthRoll >= 21 && monthRoll <=25) {
 monthResults = "Taxes1";
 } else if (monthRoll >=26 && monthRoll <=27) {
 monthResults = "Fame1";
 } else if (monthRoll == 28) {
 monthResults = "Fire, Minor1";
 } else if (monthRoll >= 29 && monthRoll <= 30) {
 monthResults = "Haunting1";
 } else if (monthRoll >=31 && monthRoll <=33) {
 monthResults = "Monster1";
 } else if (monthRoll >= 34 && monthRoll <=41) {
 monthResults = "Incursion, Major1";
 } else if (monthRoll >= 42 && monthRoll <= 51) {
 monthResults = "Incursion, Minor1";
 } else if (monthRoll >=52 && monthRoll <= 54) {
 monthResults = "Injustice1";
 } else if (monthRoll >= 55 && monthRoll <= 60) {
 monthResults = "Battle, Major1";
 } else if (monthRoll == 61) {
 monthResults = "Criminal1";
 } else if (monthRoll >=62 && monthRoll <= 66) {
 monthResults = "Recruiting1";
 } else if (monthRoll >=67 && monthRoll <=71) {
 monthResults = "Troop Movements1";
 } else if (monthRoll >=72 && monthRoll <= 78) {
 monthResults = "Uprising1";
 } else if (monthRoll >=79 && monthRoll <= 80) {
 monthResults = "Vengeful Stranger1";
 } else if (monthRoll >=83 && monthRoll <=100) {
 monthResults = "Nothing1";
 }
//Rolls on Table for Natural Disasters 
} else if (yearResults == "Comet" || yearResults == "Earthquake" || yearResults == "Famine" || yearResults == "Fire" || yearResults == "Flood" || yearResults == "Plague") {
 monthRoll = Math.floor(Math.random()*(100-1+1)+1);
 // Interprets the results of the roll
 if (monthRoll >= 1 && monthRoll <= 5) { 
 monthResults = "Accident2";
 } else if (monthRoll >= 6 && monthRoll <= 15) {
 monthResults = "Bad Harvest2";
 } else if (monthRoll >= 16 && monthRoll <= 22) {
 monthResults = "Bad Weather2";
 } else if (monthRoll >= 23 && monthRoll <= 32) {
 monthResults = "Bandit Activity2";
 } else if (monthRoll >= 33 && monthRoll <= 37) {
 monthResults = "Birth2";
 } else if (monthRoll >= 38 && monthRoll <= 44) {
 monthResults = "Death2";
 } else if (monthRoll >= 45 && monthRoll <= 49 ) {
 monthResults = "Earthquake, Minor2";
 } else if (monthRoll >= 50 && monthRoll <= 54) {
 monthResults = "Taxes2";
 } else if (monthRoll >= 55 && monthRoll <= 60) {
 monthResults = "Fire, Minor2";
 } else if (monthRoll >= 61 && monthRoll <= 66) {
 monthResults = "Flooding2";
 } else if (monthRoll >= 67 && monthRoll <= 69) {
 monthResults = "Haunting2";
 } else if (monthRoll >= 70 && monthRoll <= 73) {
 monthResults = "Monster2";
 } else if (monthRoll >= 74 && monthRoll <= 78) {
 monthResults = "Injustice2";
 } else if (monthRoll >= 79 && monthRoll <= 82) {
 monthResults = "Landslide2";
 } else if (monthRoll >= 83 && monthRoll <= 87) {
 monthResults = "Maneater2";
 } else if (monthRoll >= 88 && monthRoll <= 92) {
 monthResults = "Plague2";
 } else if (monthRoll == 93) {
 monthResults = "Uprising2";
 } else if (monthRoll == 94) {
 monthResults = "VIP2";
 } else if (monthRoll >= 95 && monthRoll <=100) {
 monthResults = "Nothing2";
 }
//Rolls on Table for Other Disasters 
} else if (yearResults == "Ambassador" || yearResults == "Birth" | yearResults == "Death" || yearResults == "Marriage" || yearResults == "Visitation") { 
 monthRoll = Math.floor(Math.random()*(100-1+1)+1);
 // Interprets the results of the roll
 if (monthRoll >= 1 && monthRoll <= 5) { 
 var monthResults = "Accident3";
 } else if (monthRoll >= 6 && monthRoll <= 7) {
 monthResults = "Bad Harvest3";
 } else if (monthRoll >= 8 && monthRoll <= 10) {
 monthResults = "Bad Weather3";
 } else if (monthRoll >= 11 && monthRoll <= 15) {
 monthResults = "Bandit Activity3";
 } else if (monthRoll >= 16 && monthRoll <= 25) {
 monthResults = "Birth3";
 } else if (monthRoll >= 26 && monthRoll <= 30) {
 monthResults = "Death3";
 } else if (monthRoll >= 31 && monthRoll <= 35) {
 monthResults = "Famous Person3";
 } else if (monthRoll >= 36 && monthRoll <= 40) {
 monthResults = "Fire, Minor3";
 } else if (monthRoll >= 41 && monthRoll <= 43) {
 monthResults = "Haunting3";
 } else if (monthRoll >= 44 && monthRoll <= 50) {
 monthResults = "Injustice3";
 } else if (monthRoll >= 51 && monthRoll <= 55) {
 monthResults = "Work of Art3";
 } else if (monthRoll >= 56 && monthRoll <= 60) {
 monthResults = "Maneater3";
 } else if (monthRoll >= 61 && monthRoll <= 68) {
 monthResults = "Marriage3";
 } else if (monthRoll >= 69 && monthRoll <= 78) {
 monthResults = "Criminal3";
 } else if (monthRoll >= 79 && monthRoll <= 83) {
 monthResults = "Vengeful Stranger3";
 } else if (monthRoll >= 84 && monthRoll <= 92) {
 monthResults = "VIP Visit3";
 } else if (monthRoll >= 93 && monthRoll <= 100) {
 monthResults = "Nothing3";
 }
 }
 }
 annualTable();
 monthlyTable();
 document.getElementById('annual').innerHTML = yearResults;
 document.getElementById('month1').innerHTML = monthResults;
} 
asked Dec 31, 2018 at 21:19
4
  • 1
    You haven't shared quite enough code to get a useful answer. Are you calling annualTable() and monthlyTable() inside your fullRoll function? A more complete example would be very helpful. Commented Dec 31, 2018 at 21:31
  • Thank you, I'll update it further! Commented Dec 31, 2018 at 21:37
  • it's innerHTML, not InnerHTML. Commented Dec 31, 2018 at 21:45
  • Thanks, I had the case correct in the actual code, just not what I posted here. Commented Dec 31, 2018 at 21:48

2 Answers 2

2

Your conditions are wrong:

if (yearRoll >= 1 && <= 50) {

Should be:

if (yearRoll >= 1 && yearRoll <= 50) {

Remember to do that for all range checks in your code.


Moreover, considering the comment in your code is true (random number between 1 and 100), you could just go ahead and drop the >=1 and <=100 checks altogether.

answered Dec 31, 2018 at 21:49

6 Comments

Thanks, Lucio, unfortunately (or fortunately) I do have the conditions correct for the range check in the actual document. It looks like the primary thing I was missing was calling annualTable and monthlyTable. Whoops. They're writing to the HTML now, but monthlyTable is coming through as undefined. As for the >=1 and <=100 checks, I just simplified them here to avoid posting several hundred lines of code. the actual ranges are more like >= 5 and <= 11
I see. Well, I recommend you post the actual code right from the start next time. It will help other people guide you to the answer more quickly.
Thank you for your help, I will be sure to do that.
If monthResults is coming through as undefined, though, I believe there's something else in your code here that's different from the original one. If the random function is really returning something between 1 and 100, I don't see how monthResults would be undefined.
Go ahead and remove the if (monthRoll >=1 && <=100) { part, since it will always evaluate to true (your random function always returns something in that range)... and then see if removing it makes the code work.
|
0

Yes, nested functions will have access to variables declared in the parent function.

However, this is probably not what you want as it is very easy to overwrite one of these values accidentally.

Instead, consider breaking your other functions out as separate functions in their own scope. See the below example (with minor modifications to remove syntax errors):

function fullRoll() {
 var yearResults = annualTable();
 var monthResults = monthlyTable(yearResults);
 document.getElementById('annual').innerHTML = yearResults;
 document.getElementById('month1').innerHTML = monthResults;
}
function annualTable() { 
 var yearRoll = 23; //*random number between 1 and 100//*
 if (yearRoll >= 1 && yearRoll <= 50) {
 return "x";
 } else if (yearRoll >= 51 && yearRoll <= 100) {
 return "y";
 }
}
function monthlyTable(yearResults) { 
 if (yearResults == "x") {
 var monthRoll = 72; //*random number between 1 and 100//*
 if (monthRoll >= 1 && monthRoll <= 100) {
 return "a";
 }
 } else if (yearResults == "y") {
 var monthRoll = 23; //*random number between 1 and 100//*
 if (monthRoll >=1 && monthRoll <=100) {
 return "b";
 }
 }
}
answered Dec 31, 2018 at 22:10

2 Comments

Hey Sam, I love this idea, and updated my code to use it. The problem I'm now encountering is that yearResults is being read as undefined when it gets to monthlyTable. If I restate that yearResults = annualTable(), it fixes the issue, BUT the monthResults is no longer tied to the value rolled by annualTable(). Any ideas as to why this may be?
Sure, I updated code example to show passing the return value of yearResults into the monthlyTable() function. Let me know if any further clarification is needed on that.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.