Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Random set of Choices?

Hi all, first post here!  Twine's been a blast to learn about, and the Wiki and these forums have been super helpful in finding out things.  I still can't seem to get my mind around an issue I'm having however.

I'm currently using Sugarcane story format (like the darker style.  Easy on the eyes.)

So the game I'm making essentially consists of a 'Hub' passage that a player will enter at the start of the day.  In this case, it's a bar.

I want to have a random set of three bar patrons out of a list I've generated to be shown as choices.

After fully interacting with one patron, I want to go back to the Hub area, where three more random patrons will appear as choices to interact with.

I know how to set choices..but not so much in how to make it randomly select folks for me and was wondering how this could be coded!

After interacting with three of these random folks, the day will officially end.

_________

I also don't want it to be completely random...in this example.

First Day - I spoke to Ana, Bob, and Carl.

I wanted to talk to Ana again on the 2nd day.

Second Day - I see Ana, Darvin, and Elise

How could I accomplish this also?

Any help would be great!  I know the basic jist of coding but I think combining things together is still a bit confusing ^^

Comments

  • I don't use SugarCane, so can't speak to the exact code, but influencing random events is a case of setting triggers within each random event.

    So:

    1. First Day - I spoke to Ana, Bob, and Carl: Your random choice function choosing from a list of everyone.

    2. On passage where you talk to Ana: <<set $Ana to 1>> <<set $Bob to 0>>

    3. I wanted to talk to Ana again on the 2nd day.

    In this case you use <<if>>  and <<elseif>> functions for every person:

    <<if $Ana is 1>>

    1. Ana
    2. Random choice that's not Ana
    3. Random choice that's not Ana

    <<elseif $Bob is 1>>

    1. Bob
    2. Random Choice that's not Bob
    3. Random Choice that's not Bob

    <</if>>


    And so on.

    To set up the "Random choice that's not Ana/Bob" function you'd use a random list specific to each person. So Ana's random list would not contain Ana.

    Very easy to do this sort of thing in SugarCube, but I'm not familiar with SugarCane so can't type out the exact syntax.


    Where it gets complex though, is you might want to make sure you don't list the same person in the same list, which in that case you need to set gating variables to close off choices based on what random variable just got chosen:


    <<set random to Ana, Bob, Carl>>

    <<if random = Ana>>
    1. Ana <<set $anachosen to 1>>
    <<elseif random = Bob>>
    1. Bob <<set $bobchosen to 1>>
    <<elseif random = Carl>>
    1. Carl <<set $carlchosen to 1>>
    <</if>

    <<if anachosen = 1>>
    <<random Bob, Carl>>
    <<if random = Bob>>
    2. Bob <<set bobchosen to 1>>
    <<elseif random = carl>>
    2. Carl <<set carlchosen to 1>>
    <</if>>

    Insert equivalent code for Bob and Carl for number 2.

    <<if bobchosen = 0>>
    3. Bob
    <<elseif anachosen = 0>>
    3. Ana
    <<elseif carlchosen = 0>>
    3. Carl
    <</if>>

    And so on. Here, $anachosen is the gating variable that tells Twine to chose from a list not containing Ana for when it chooses to populate the second list item. This list is simply a random list of names you create that doesn't contain Ana.

    As you can see it is possible, but requires a Goldberg machine of <<if>> functions where you end up with 20 lines of code for one list. But luckily once you make one working random list set of functions, you can just copy-paste code.

    This is what I do, using Notepad++'s function of "replace all". So I copy my code from Twine to Notepad++, then tell it to replace all instances of Ana with Bob, if I'm creating a Bob function etc. Then copypaste it back to Twine. That's why I use variable names like $ana and $anachosen. Because then you can just completely switch the code to $bob and $bobchosen by telling Notepad++ to replace all instances of Ana with Bob.
  • The functions area of the Twine wiki explains how to use the either() function.

    /% Array for storing list of people, %/
    <<set $list to ["Ann", "John", "Jane"]>>

    <<set $first to either($list)>>
    <<print $first>>

    The following is an example of how to get three different names from an array of names.

    <<nobr>>
    /% The original Array storing the list of possible people. %/
    <<set $originals to ["Ann", "John", "Jane", "Mark", "Betty"]>>

    /% Clone the original list of names because we are going to be deleting names from it as they are randomly chosen. %/
    <<set $list to $originals.slice()>>

    /% Get the first name. %/
    <<set $first to either($list)>>

    /% Remove the first name from the list. %/
    <<set $dummy to $list.splice($list.indexOf($first), 1)>>

    /% Get the second name. %/
    <<set $second to either($list)>>

    /% Remove the second name from the list. %/
    <<set $dummy to $list.splice($list.indexOf($second), 1)>>

    /% Get the third name. %/
    <<set $third to either($list)>>
    <<endnobr>>

    First Name: <<print $first>>
    Second Name: <<print $second>>
    Third Name: <<print $third>>
  • That's probably easier than my approach, but I like mine for its sheer complexity. :P
  • thank you thank you thank you ^^  both of these codes were extremely useful and did exactly as intended ^_^
  • Alright, I tried a bit myself but I'm still getting stuck on how to remove the chosen variable from the array.  I'm using greyelf's code right now.

    I've also switched to Sugarcube.

    Player gets given a list of folks to talk to at the bar. Player chooses "Ann". A few passages later, they are done talking. Player goes back to the bar.  Ann shouldn't be in the list anymore, because we finished speaking to her.

    I've tried multiple things.  No doubt I'm just missing something simple.
    I'm using two lines of code and kinda wishing they'd work.
    <<if $first is "Ann">> <<set $chosen = "Ann">>
    To try and keep track of what was chosen in terms of a name over a variable.


    <<set $dummy to $list.splice($list.indexOf($chosen), 1)>>


    /% Back at the Bar, 2nd time %/
    <<if visitedTag("day1choice1")>> This is my second time at the bar. I see a new set of patrons, oh my.

    <<print $first>> beep beep boop
    <<print $second>> tralalalas more
    <<print $third>> tralalas
    <<print $fourth>> beep beep boop
    The intention is that the person that was chosen - will not appear again at the bar unless I add her specifically to it via another variable. $first, $second, and $third are just a means for choosing randomly and allowing only one to become $chosen, if that makes sense.

    Hasn't worked yet, I'm sure I just have a strange bit of code that's messing me up ^^; 
  • I noticed that your last examples had no <</if>> 's, I am assuming you just left them out of you examples.

    If I understand what you want then the following three example passages may help you.

    (note: the following is using TWEE notation, lines starting with two colons indicate a new passage, the text on the same line as the two colons in the new passage's title)

    :: Start
    <<nobr>>
    /% The list of potential people in bar. %/
    <<set $potential to ["Ann", "John", "Jane", "Mark", "Betty"]>>\
    <</nobr>>
    This is the start of the story

    [[Go to Bar|Bar]]


    :: Bar
    Potential People: <<print $potential>>
    <<nobr>>
    /% Clone the original potential people because we are going to be deleting names from it as they are randomly chosen. %/
    <<set $list to $potential.slice()>>

    /% Get the first name. %/
    <<set $first to either($list)>>

    /% Remove the first name from the list. %/
    <<run $list.splice($list.indexOf($first), 1)>>

    /% Get the second name. %/
    <<set $second to either($list)>>

    /% Remove the second name from the list. %/
    <<run $list.splice($list.indexOf($second), 1)>>

    /% Get the third name. %/
    <<set $third to either($list)>>
    <</nobr>>

    /% Dynamically create a link (with a setter) for each of the random people you want to talk to. %/
    <<print "[[Talk to " + $first + "|Talk To][$person = $first]]">>
    <<print "[[Talk to " + $second + "|Talk To][$person = $second]]">>
    <<print "[[Talk to " + $third + "|Talk To][$person = $third]]">>


    :: Talk To
    Talked to <<print $person>>
    <<nobr>>
    /% remove this person from the list of potential people %/
    <<run $potential.splice($potential.indexOf($person), 1)>>
    <</nobr>>

    [[Return to Bar|Bar]]
    The $potential variable records the possible people in the bar, after you have talked to a particular person you remove them from the list.

    Because you are now using SugarCube I have replaced the <<set $dummy to ....>> macros with <<run>> macros to save the use of a variable.

    Using a setter link allows you to use a generic Talk To passage if you wish, or you could send each of those Talk To links for individual passages.
  • It worked like a charm greyelf!  You are a saint ^_^

    Edit - Okay, I spent most of this morning figuring out my previous questions and I've been able to Print the Variables as well as change my radio button placement so that depending on whether one variable is randomly A, B, or C, the true variable will be either first second or third on the radio button list.

    Here is my code

    ::orderfood
    <<set $order1 to ["Braised Beef", "Creme Brulee", "Ratatouille", "Kalamari", "Cookies and Cream", "Frog Legs"]>>

    <<set $order1 to $order1.slice()>>

    <<set $maindish to either($order1)>>

    /% remove this person from the list of potential people %/

    <<run $order1.splice($order1.indexOf($maindish), 1)>>

    "I think I'll have the <<print $maindish>>

    [[Go to Kitchen|Kitchen]]

    ::Kitchen
    <<set $radio to ["A", "B", "C"]>>
    <<set $radioprob to either($radio)>>

    /% Get the first name. %/
    <<set $order1false to either($order1)>>

    /% Remove the first name from the list. %/
    <<run $order1.splice($order1.indexOf($order1false), 1)>>

    /% Get the second name. %/
    <<set $order1false2 to either($order1)>>

    /% Remove the second name from the list. %/
    <<run $order1.splice($order1.indexOf($order1false2), 1)>>

    What is the maindish?

    <<if $radioprob is "A">>
    I was given A
    <<print "" + $maindish + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false2 + "">><<radiobutton "$maindishchoice" "">>
    <</if>>

    <<if $radioprob is "B">>
    I was given B
    <<print "" + $order1false + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $maindish + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false2 + "">><<radiobutton "$maindishchoice" "">>
    <</if>>

    <<if $radioprob is "C">>
    I was given C
    <<print "" + $order1false + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false2 + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $maindish + "">><<radiobutton "$maindishchoice" "">>
    <</if>>

    <<button "Were you Correct?" "Test">><</button>>
    ::Test
    <<if ($maindishchoice = $maindish)>>Yay, you've got it correct!
    <<else>>
    Nope, not it at all :(
    <</if>>
    It looks like I've gotten everything right (though if there are errors in my codes, let me know.), but the Test passage isn't working correctly, and my mind is boggled as to why.

    It always seems to go with "Yay! You've got it correct!" even when I choose the wrong answer.  :(

    Editeditedit

    Actually, I think I know what's going on.  I need to print my $order1false, $order1false2, and $maindish INSIDE of <<radionbutton>> Otherwise it's not going through.  I don't know how to print it out just yet though.


  • From orderfood:
    NPStudios wrote:

    <<set $order1 to ["Braised Beef", "Creme Brulee", "Ratatouille", "Kalamari", "Cookies and Cream", "Frog Legs"]>>

    <<set $order1 to $order1.slice()>>


    What do you think the above code is actually doing?  Specifically, I mean the second &lt;&lt;set&gt;&gt; there.  You're creating a copy of $order1 and then assigning it over the original, which is pointless.

    If you were keeping a master list of dishes, then it would make sense to make a copy of it, since you're performing destructive operations on $order1.  For example:

    /% Create the master list of dishes %/
    <<set $dishes to ["Braised Beef", "Creme Brulee", "Ratatouille", "Kalamari", "Cookies and Cream", "Frog Legs"]>>

    /% Make a copy of the master list of dishes %/
    <<set $order1 to $dishes.slice()>>
    So, unless you intend to do something like that, you can drop the second &lt;&lt;set&gt;&gt;.


    From Kitchen:
    NPStudios wrote:

    <<set $radio to ["A", "B", "C"]>>
    <<set $radioprob to either($radio)>>


    Are you using $radio anyplace else?  If not, simply doing the following would be better:

    <<set $radioprob to either("A", "B", "C")>>

    More from Kitchen:
    NPStudios wrote:

    <<if $radioprob is "A">>
    I was given A
    <<print "" + $maindish + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false2 + "">><<radiobutton "$maindishchoice" "">>
    <</if>>

    <<if $radioprob is "B">>
    I was given B
    <<print "" + $order1false + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $maindish + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false2 + "">><<radiobutton "$maindishchoice" "">>
    <</if>>

    <<if $radioprob is "C">>
    I was given C
    <<print "" + $order1false + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $order1false2 + "">><<radiobutton "$maindishchoice" "">>
    <<print "" + $maindish + "">><<radiobutton "$maindishchoice" "">>
    <</if>>


    Every single use of &lt;&lt;radiobutton&gt;&gt; in the above is wrong (see: &lt;&lt;radiobutton&gt;&gt; macro), you're setting the checked value to an empty string when it should be the same value as the label.  And why are you pointlessly concatenating empty strings to the labels?  That section should look something like the following:

    <<if $radioprob is "A">>
    I was given A
    <<radiobutton "$maindishchoice" $maindish>> <<print $maindish>>
    <<radiobutton "$maindishchoice" $order1false>> <<print $order1false>>
    <<radiobutton "$maindishchoice" $order1false2>> <<print $order1false2>>
    <</if>>

    <<if $radioprob is "B">>
    I was given B
    <<radiobutton "$maindishchoice" $order1false>> <<print $order1false>>
    <<radiobutton "$maindishchoice" $maindish>> <<print $maindish>>
    <<radiobutton "$maindishchoice" $order1false2>> <<print $order1false2>>
    <</if>>

    <<if $radioprob is "C">>
    I was given C
    <<radiobutton "$maindishchoice" $order1false>> <<print $order1false>>
    <<radiobutton "$maindishchoice" $order1false2>> <<print $order1false2>>
    <<radiobutton "$maindishchoice" $maindish>> <<print $maindish>>
    <</if>>
    Or, even better:

    <<if $radioprob is "A">>
    I was given A
    <<radiobutton "$maindishchoice" $maindish>> <<print $maindish>>
    <<radiobutton "$maindishchoice" $order1false>> <<print $order1false>>
    <<radiobutton "$maindishchoice" $order1false2>> <<print $order1false2>>
    <<elseif $radioprob is "B">>
    I was given B
    <<radiobutton "$maindishchoice" $order1false>> <<print $order1false>>
    <<radiobutton "$maindishchoice" $maindish>> <<print $maindish>>
    <<radiobutton "$maindishchoice" $order1false2>> <<print $order1false2>>
    <<else>>
    I was given C
    <<radiobutton "$maindishchoice" $order1false>> <<print $order1false>>
    <<radiobutton "$maindishchoice" $order1false2>> <<print $order1false2>>
    <<radiobutton "$maindishchoice" $maindish>> <<print $maindish>>
    <</if>>

    Even more from Kitchen:
    NPStudios wrote:

    <<button "Were you Correct?" "Test">><</button>>


    I'm unsure if you think you need a button there or not, so I'm just going to point out that you don't.  If you knew that and simply wanted to use a button, then carry on.


    NPStudios wrote:

    ::Test

    <<if ($maindishchoice = $maindish)>>Yay, you've got it correct!
    <<else>>
    Nope, not it at all :(
    <</if>>


    You're using an assignment operator (=) inside a conditional expression (see: &lt;&lt;if&gt;&gt; macro), which if that's what you needed and wanted to do there would be fine, except that it's not.  You should be doing something like the following:

    <<if $maindish is $maindishchoice>>\
    Yay, you've got it correct!\
    <<else>>\
    Nope, not it at all :(\
    <</if>>
  • Welp, that pretty much answered and fixed all the errors I had.  Thanks!

    I don't know, I've literally been looking at the Wiki, the Sugarcube Wiki, the forums, and I'm still pretty blah when it comes to coding these things.

    For example, the radio buttons. For the life of me I couldn't understand how to place the variables to make them appear after the radio button.

    Same thing for the <<set $order1 to $order1.slice()>>

    Still not certain if I need that yet or not, as I needed it for the aforementioned Name situation in order to take out names from the existing array so that there would be no repeating names when $order1false and $order1false2 were pulled out of the array to be used in the radio.

    Thanks for being patient guys ^^; 
Sign In or Register to comment.