Ranked choice judging on one passage

Twine Version: sugarcube 2.36.1

I’m attempting to make a gameshow judging game with five competing NPCs, where the player plays a judge. In each round, they’ll assign set points to each NPC, based on their performance (10, 7, 5, 3 and 1), but each NPC can only get one set of points per round.

I’d prefer to do this all on one page, so they can easily see what each NPC did while judging them. I think there’s probably an easier way to do this than the 9 million nested links or vast number of individual pages, I’m coming up with so far, but I can’t figure it out. So by preference it would be the list of options I can get like this:

"Who are you giving 10 points to?"

@@#winner;

<<link "John">><<replace "#winner">><<set $johnscore to $johnscore+ 10>>"John wins 10 points!"<</replace>><</link>>

<<link "Roger">><<replace "#winner">><<set $rogerscore to $rogerscore + 10>>"Roger wins 10 points!"<</replace>><</link>>

[Repeat for all five competitors]

But then I don’t see a straightforward way to continue down the chain to who wins 7 points (etc.) without nesting all of the 4! options under each of the five set ups. Is there a simpler way to do this? Maybe something with checkboxes? I have no objection to them having to select all five scores at once, but they can’t give Roger 10 points and 7 points, or anything like that.

I’m fine writing 25 reactions (1 for each score for each NPC), but layering each reaction in a bunch of times seems fairly painful and like it introduces a lot of possibilities for me to mess things up.

Also, I think I probably need to set a ‘round score’ variable which resets to 0 at the end of each round, so I can distinguish those who’ve already been scored from those who haven’t as there are multiple rounds. Unless there’s a better way to do that? But that’s fairly simple, just a little annoying.

Here is some code and formatting I wrote to simulate this. I created an array of the contestants names and some story variables for their running point totals on first time visiting the page (probably better done earlier like in your storyinit). Radioboxes are a good choice to use for each of the 5 point categories. When the player clicks on a radiobutton, the respective points is assigned to a temp variable.

So if I click John in the 10 point bracket “John” is assigned to _tenpoint. Once all point brackets are assigned a vote, the player clicks on cast vote. At this point I do some error checking using the temp array _winnersarray. I use the pushUnique() method on _winnersarray to add all the point selections into it (_tenpoint, _sevenpoint, etc). First it checks for any undefined, meaning not all radioboxes had a check, and the player is given a message all votes not cast. Second, if _winnersarray length is not 5, it means the player selected duplicate names for different point categories (if for instance they voted for John on the 10 and 3 brackets). If both those checks pass, everything is correct.

Now several things happen, the $round gets incremented. Then it gets a little hacky, I use State.setVar to concatenate some variable names and add the points to the running totals. They have to be story variables to carry over ($Johnpoints, $Rogerpoints, etc). There is probably a better way to handle the running totals but this gets the job done.

The player can then click to move onto the next round. The page refreshes and now the contestants running totals are shown at the top. If the round is greater than five, the contest is over and the story moves onto the winners circle where you could show point totals, a trophy, etc. Before the voting brackets each round, you would ideally use an if statement put something the contestants did whether be text or graphics, based on what the $round it is…

That’s the nuts and bolts of it. Hopefully it’s close to what you want. Passage code below.

It's time to judge and award points to the contestants. Each winner must have a unique score.

<<set _winnersarray = []>>\
<<if visited()< 2>>\
ROUND 1
<<set $contestants = ["John", "Roger", "Bill", "Mack", "Ian"]>>\
<<set $round = 1>>\
<<set $Johnpoints = 0>>\
<<set $Rogerpoints = 0>>\
<<set $Billpoints = 0>>\
<<set $Mackpoints = 0>>\
<<set $Ianpoints = 0>>\
<<else>>\
ROUND $round
Current points
John: $Johnpoints
Roger: $Rogerpoints
Bill: $Billpoints 
Mack: $Mackpoints 
Ian: $Ianpoints
<</if>>\

<div>\
<div style="width:15%; float:left;border:1px solid; padding:4px; margin:4px;border-radius:4px;">\
10 POINTS
<<for _i=0; _i < $contestants.length;_i++>>\
<<capture _i>>\
<<radiobutton "_tenpoint" $contestants[_i]>>$contestants[_i]
<</capture>>\
<</for>>\
</div>\
<div style="width:15%; float:left;border:1px solid; padding:4px; margin:4px;border-radius:4px;">\
7 POINTS
<<for _i=0; _i < $contestants.length;_i++>>\
<<capture _i>>\
<<radiobutton "_sevenpoint" $contestants[_i]>>$contestants[_i]
<</capture>>\
<</for>>\
</div>\
<div style="width:15%; float:left;border:1px solid; padding:4px; margin:4px;border-radius:4px;">\
5 POINTS
<<for _i=0; _i < $contestants.length;_i++>>\
<<capture _i>>\
<<radiobutton "_fivepoint" $contestants[_i]>>$contestants[_i]
<</capture>>\
<</for>>\
</div>\
<div style="width:15%; float:left;border:1px solid; padding:4px; margin:4px;border-radius:4px;">\
3 POINTS
<<for _i=0; _i < $contestants.length;_i++>>\
<<capture _i>>\
<<radiobutton "_threepoint" $contestants[_i]>>$contestants[_i]
<</capture>>\
<</for>>\
</div>\
<div style="width:15%; float:left;border:1px solid; padding:4px; margin:4px;border-radius:4px;">\
1 POINTS
<<for _i=0; _i < $contestants.length;_i++>>\
<<capture _i>>\
<<radiobutton "_onepoint" $contestants[_i]>>$contestants[_i]
<</capture>>\
<</for>>\
</div>\
</div>\
<div id="final" style="position:relative;clear:both;">\

<<button "cast votes">>\
<<set _winnersarray.pushUnique(_tenpoint)>>
<<set _winnersarray.pushUnique(_sevenpoint)>>
<<set _winnersarray.pushUnique(_fivepoint)>>
<<set _winnersarray.pushUnique(_threepoint)>>
<<set _winnersarray.pushUnique(_onepoint)>>
<<if _winnersarray.includes(undefined)>>
<<replace #message>>
Not all votes cast. Try again.
<<set _winnersarray.length = 0>>\
<</replace>>
<<elseif _winnersarray.length != 5>>\
<<replace #message>>
Duplicate point selections. Try again.
<<set _winnersarray.length = 0>>\
<</replace>>
<<else>>\
<<replace #final>>
Votes cast!
<<set $round += 1>>\
<<run State.setVar("_" + _tenpoint + "points", 10)>>\
<<run State.setVar("_" + _sevenpoint + "points", 7)>>\
<<run State.setVar("_" + _fivepoint + "points", 5)>>\
<<run State.setVar("_" + _threepoint + "points", 3)>>\
<<run State.setVar("_" + _onepoint + "points", 1)>>\
<<set $Johnpoints += _Johnpoints>>\
<<set $Rogerpoints += _Rogerpoints>>\
<<set $Billpoints += _Billpoints>>\
<<set $Mackpoints += _Mackpoints>>\
<<set $Ianpoints += _Ianpoints>>\

<<if $round < 6>>\
[[Next round|contest]]
<<else>>\
[[Winners circle]]
<</if>>\
<</replace>>\
<</if>>\

<</button>>
<span id="message"></span>
</div>\

Thanks!