bryanwillis7 bryanwillis7 - 4 months ago 9
CoffeeScript Question

How can I avoid calling a function within a function?

#branchID pool
branch0 = "This is a wall of text. This is another wall of text! This is a third wall of text. This is a fourth wall of text. This is a fifth wall of text. This is a sixth wall of text. #branch1%"
branch1 = "This is a second wall of text."
branch2 = "This is a third wall of text."
loopcounter = 0

#classes section
#pulls text from pools above.

branch = (name, branchid)->
alert('begin loop')
stringID = String(branchid)
document.write("<h1 id=\'#{stringID}\'>#{name}</h1>")

document.getElementById(stringID).onclick = ->
for i in [loopcounter...stringID.length]
if branchid[i]!= "." and branchid[i]!="!" and branchid[i]!="?" and branchid[i]!="#"
document.write(branchid[i])

else if branchid[i]=="#"
j = i+1
for k in [j...stringID.length]
if branchid[k] == "%"
j = k+1
alert("switchblock")
switch fcode
when "branch1" then branch('stuff', branch1)
when "branch2" then branch('stuff2', branch2)
else break
break

else
alert("gathering...")
fcode = ""
fcode += branchid[k]

else
alert('end sentence')
document.write(branchid[i])
loopcounter = i+1
break

#This is where the code is executed.
window.onload = ->
branch("Start", branch0)


My code above is the beginning of a Choose your own adventure gamebook.

My code works by executing a function that pulls text from a long string one sentence at a time and writes it to the HTML document.

The issue I'm having is that when the string has no text left, I need to call the very same function again, but this time with different parameters so that a different string can be displayed on the screen. Given my current situation, I've had to call it within it's own function, but I have a feeling that's causing some issues. When I try running my code, It acts up in a way that I really don't understand and writes to the document instead of executing the new function

Any general advice, or specific diagnoses are welcome. I'm just a little stumped at this point and am not sure where to go from here. Maybe I'm not thinking about this correctly? And by the way, I've gotten a lot of help from stack overflow lately. Thank you so much. You guys have been amazing.

**I threw in a bunch of alert boxes so I could try figuring out what the loop was doing.

Codepen posting: http://codepen.io/bryanwillis7/pen/WwMPaw

Answer

Wow, this is a doozy, but I think I've got it working:

#branchID pool
branch0 = "This is a wall of text. This is another wall of text! This is a third wall of text. This is a fourth wall of text. This is a fifth wall of text. This is a sixth wall of text. #branch1%"  
branch1 = "This is a second wall of text."
branch2 = "This is a third wall of text."


#classes section
  #pulls text from pools above.
branch = (name, branchid)->
  loopcounter = 0
  alert('begin loop')
  stringID = String(branchid)
  document.write("<h1 id=\'#{stringID}\'>#{name}</h1>")
  document.getElementById(stringID).onclick = ->
    for i in [loopcounter...stringID.length]
      if branchid[i]!= "." and branchid[i]!="!" and branchid[i]!="?" and branchid[i]!="#"
        document.write(branchid[i])
      else if branchid[i]=="#"
          j = i+1
          fcode = ""
          for k in [j...stringID.length]
            if branchid[k] == "%"
              j = k+1
              alert("switchblock")
              switch fcode
                when "branch1" then return branch('stuff', branch1)
                when "branch2" then return branch('stuff2', branch2)
                else break
              break
            else
              alert("gathering...")
              fcode += branchid[k]

      else
        alert('end sentence')
        document.write(branchid[i])
        loopcounter = i+1
        break

#This is where the code is executed.
window.onload = ->  
  branch("Start", branch0)

Okay, so I had to change only a couple things. I moved fcode out of the switch block and put it right before the k loop. Also, I defined loopcounter in the branch function scope, otherwise it won't reset, and you'll get an index out of bounds issue, which will result in it printing undefined about a million times. Lastly, I added return right before the recursive calls. This makes the parent function stop executing.

Honestly, though, I think you should seriously consider refactoring this into smaller bits. All this nested looping makes it really hard to follow what's going on. Try making one function for just checking if this is the end of the sentence, another for checking if you're starting a new branch, and another for gathering up the string.

Making your code in smaller chunks will also make it easier to test and change later.

Hope that helps.

Comments