Appending a randomly generated number to a string to make an attribute

Is there a way to generate a random number and append it to an attribute, eg

@set description1 = The car was red
@set description2 = The bus was blue

[[next]]

[[next]]:
var randomnumber = function rng(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
set ("rnd", randomnumber(1,2));

...and then append the rnd result to description to make {description1} or {description2}, randomly displaying either 'The car was red' or 'The bus was blue' (without having to do if statements for each possible result of rnd)?

And somewhat related, is there a way to set an attribute with another attribute in it?

@set colour = red
@set description1 = The car was {colour}

...just produces The car was {colour} from {description1}


For the first, I think your javascript should be:

    squiffy.set("result", squiffy.get("description" + randomnumber(1,2));

It's probably easier to do in javascript, because you can combine a string and a random number to get the parameter you need for squiffy.get to get a Squiffy attribute.

If you want it to work with other attributes inside that string, you'd want to call processText. Something like this:

    var rnd = randomnumber(1,2);
    var result = squiffy.get("description" + rnd);
    result = squiffy.ui.processText(result);
    squiffy.set("result", result);

So you can then use {result} in your text.

If you don't need to do anything else with the result before it's displayed, you can compress that down into a single line:

    squiffy.set("result", squiffy.ui.processText(squiffy.get("description" + randomnumber(1,2))));

which is more efficient, but may be harder to read if you're not used to looking at code.


mrangel :)

var randomnumber = function rng(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
squiffy.set("result", squiffy.get("description" + randomnumber(1,2)));
{result}

works beautifully for me, thank you :)

Could you elaborate on the processText alternative? I can't get either to work in my demo, but I'd like to know more - could I use it to stick together (technical term!) different attributes and random results?


Also this is a real rookie question (but I still don't have my head around javascript). In this example from one of the other solutions you've helped me with, how would I append (or prepend) a string of drag to the pageNumber created by the rng so that I'd have an attribute of {dragA} {dragB} etc (dependent on what the rng generated)?

squiffy.set("pagesToVisit", "ABCDEFGHIJKLMNOPQRST")
var pages = get("pagesToVisit");
if (pages) {
var rnd = pages.charAt(Math.floor(Math.random() * pages.length)); // pick a random character from pages
squiffy.set("pageNumber", rnd);
squiffy.set("pagesToVisit", pages.replace(rnd, "")); // remove that page from the list so it won't be picked again
} else {
squiffy.story.go("leftStanding");
}


Could you elaborate on the processText alternative? I can't get either to work in my demo, but I'd like to know more

Here's what I've tried. It seems to work for me:

@title Dumb test game

[[first section]]:

    window.randomnumber = function(min, max) {
      return Math.floor(Math.random() * (1 + max - min) + min);
    };

@set color1 = red
@set color2 = blue
@set color3 = green
@set description1 = The car is {color}
@set description2 = The truck is {color}

The initial attributes are set. Would you like to [[pick a color]] or [[pick a description]]?

[[pick a color]]:

    var rnd = randomnumber(1,3);
    var result = squiffy.get("color" + rnd);
    result = squiffy.ui.processText(result);
    squiffy.set("color", result);

Okay, so far we've picked a color. It was {color}.

Next, would you like to [[pick a color]] or [[pick a description]]?

[[pick a description]]:

    var rnd = randomnumber(1,2);
    var result = squiffy.get("description" + rnd);
    result = squiffy.ui.processText(result);
    squiffy.set("description", result);

You look at the traffic. {description}.

Next, would you like to [[pick a color]] or [[pick a description]]?

To summarise how it works:

  • var rnd = randomnumber(1,2);
    Gets a random number from 1 to 2, and puts that in the javascript variable rnd.

  • var result = squiffy.get("description" + rnd);
    Sticks the string "description" and the value of rnd together to get a name like description2, and uses squiffy.get to get the value of the named attribute, which it puts in the javascript variable result.

  • result = squiffy.ui.processText(result);
    Does the text processor thing to the text in result, the same as is done with a section's description when visiting it. This changes {color} to the current value of the color attribute and similar things. The result is stored back in the javascript variable result.

  • squiffy.set("description", result);
    Sets the squiffy attribute description to the value of the javascript variable result. This means that you can then use {description} in your section text.


Also this is a real rookie question (but I still don't have my head around javascript). In this example from one of the other solutions you've helped me with, how would I append (or prepend) a string of drag to the pageNumber created by the rng so that I'd have an attribute of {dragA} {dragB} etc (dependent on what the rng generated)?

OK, I'm not sure exactly what you mean here.

This line:
squiffy.set("pageNumber", rnd);
sets the attribute pagenumber to the randomly chosen letter. If you want to do something else, you'll want to put a different line either after or instead of that one. Different things you might want include:

  • Set an attribute (let's call it pagename) to a string like "dragA" or "dragB"
    squiffy.set("pagename", "drag" + rnd);

  • Set an attribute (let's call it dragrnd to the contents of the attribute dargA etc, so you can use {dragrnd} instead of {dragA}, {dargB}, etc.
    squiffy.set("dragrnd", squiffy.get("drag" + rnd));

  • Go to the page dragA, dragB, or so on.
    squiffy.story.go("drag" + rnd);

Is one of these what you wanted, or am I missing something?


First thing - brilliant, that's exactly what I needed! I'm trying to construct unique passages using random choices for each part of the sentence, and that does it beautifully, thank you!

On the second one, I think what I'm after is your second example:

squiffy.set("dragrnd", squiffy.get("drag" + rnd));

...so that I can use {dragrnd} instead of having to specify dragA, dragB etc. However for me {dragrnd} is returning null if I use it like this:

var pages = get("pagesToVisit");
if (pages) {
var rnd = pages.charAt(Math.floor(Math.random() * pages.length)); // pick a random character from pages
squiffy.set("dragrnd", squiffy.get("drag" + rnd));
squiffy.set("pagesToVisit", pages.replace(rnd, "")); // remove that page from the list so it won't be picked again
} else {
squiffy.story.go("leftStanding");
}

{dragrnd}

A further thought (once it's not returning null!) - would I be able to stick a string on the beginning and the end of rnd, like

squiffy.set("dragcolour", squiffy.get("drag" + rnd + _colour));

to produce an attribute {dragcolour} that would return the value of dragA_colour, dragB_colour etc?


...so that I can use {dragrnd} instead of having to specify dragA, dragB etc. However for me {dragrnd} is returning null if I use it like this:

That looks like it should work. Are you sure that the attribute pagesToVisit has been set before that point?
I can only see 'null' coming out of that in 3 situations:

  • pagesToVisit hasn't been set yet
  • all the options have already been used
  • one of the dragA, dragB, dragC attributes hasn't been set yet (if the one that gets picked is null, dragrnd will be null as well)

squiffy.set("dragcolour", squiffy.get("drag" + rnd + _colour));

Should be squiffy.set("dragcolour", squiffy.get("drag" + rnd + "_colour"));, because _colour is a string rather than the name of a javascript variable.


Ahh, that was what I hadn't done - defined dragA, dragB etc. Thank you!

That makes sense on the string, too. Honestly, I'm nearly there with this game (she says, after six months...)


Of course I have another question : )

So I have this:

@set dragA = Bob
@set dragB = Fred
@set dragA_hatched=false
@set dragB_hatched=false

squiffy.set("pagesToVisit", "AB")
var pages = get("pagesToVisit");
if (pages) {
var rnd = pages.charAt(Math.floor(Math.random() * pages.length)); // pick a random character from pages
squiffy.set("dragrnd", squiffy.get("drag" + rnd));
squiffy.set("pagesToVisit", pages.replace(rnd, "")); // remove that page from the list so it won't be picked again
} else {
squiffy.story.go("leftStanding");
}

{dragrnd} has hatched

Once a drag eg dragA has been randomly selected, dragA_hatched needs to change to 'true' (as that true/false is used elsewhere) - can that be done?


I think squiffy.set("drag" + rnd + "_hatched", true); may be the line you're looking for.


Also, if you're pasting a whole bunch of code in the forum, rather than putting `s on each line, you can put three of them before and three after, like this:

```
    here is some code
    as many lines as you want {
      and we can see the spaces
      at the start of the lines
        so it's easier to read
    }
```

You thought I'd gone away satisfied, didn't you? Ahahahahaha nope!

So the player randomly selected a dragon (eg dragA, dragB), and whatever drag they select additionally gets eg dragA_current=true set for them to indicate that dragA is the one currently in focus. {dragCurrent} returns a true/false based on dragA_current.

@set dragA = Bob
@set dragB = Fred
@set dragA_hatched=false
@set dragB_hatched=false
@set dragA_current=false
@set dragB_current= false

squiffy.set("pagesToVisit", "AB")
var pages = get("pagesToVisit");
if (pages) {
var rnd = pages.charAt(Math.floor(Math.random() * pages.length)); // pick a random character from pages
squiffy.set("dragname", squiffy.get("drag" + rnd));
squiffy.set("drag" + rnd + "_current", "true");
squiffy.set("dragCurrent", squiffy.get("drag" + rnd + "_current"));
squiffy.set("pagesToVisit", pages.replace(rnd, "")); // remove that page from the list so it won't be picked again
} else {
squiffy.story.go("leftStanding");
}

{dragname} has hatched{if dragCurrent=true:  and is the current dragonet}.  But he doesn't seem interested in you.
[[Leave him alone and wait for another dragon to hatch]](Hatching)
[[Try harder]](Try harder)

However if (after other stuff happens in that section) dragA isn't interested in the player, dragA_current needs to be set back to false so that the next dragon can be set to current. I tried this with:

[[Leave him alone and wait for another dragon to hatch]](Hatching,dragCurrent=false)

but that doesn't affect dragA_current - it remains set to true.

Obviously by this point in the passage I can't set it using another line of javascript because the javascript always has to be the first thing in the section! Any advice?


I'd suggest setting an attribute to the chosen letter, so you can access it on other pages.
For example:

    squiffy.set("chosenLetter", rnd);

Then you can have your link not modifying the variables yet:

[[Leave him alone and wait for another dragon to hatch]](Hatching)

And have the Hatching page set it to false as soon as the player gets there, before doing anything else:

[[Hatching]]:

    if(squiffy.get("dragCurrent")) {
      squiffy.set("dragCurrent", false);
      squiffy.set("drag" + squiffy.get("chosenLetter") + "_current", false);
    }

Does that make sense?


Yes it does - in fact the even more simple way I realised I could do, it based on your solution was

squiffy.set("chosenLetter", rnd);

[[Leave him alone and wait for another dragon to hatch]](Hatching, {chosenLetter}_current=false)

Thank you!


Nice :) I wasn't 100% sure that would work, but good to see it does :)


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums