Friday, January 25, 2019

Using Twine to Keep Score with Three Teams

The problem One of the problems with trying to learn programming outside of a formal computer science class is the amount of time I spend re-inventing wheels. 

This issue, which I spent two days struggling with, has probably been solved by other people. I bet they published solutions in academic journals, but they ended up with abstract names like graph traversal or Byzantine fault tolerance

I'm just trying to keep score when there are three different teams. The player can assign points to any team, in any order they choose. 

Let's call the teams Red, Yellow, and Blue. The world state should always indicate which team has the most points. 

A color wheel is going to be helpful here: 



The world state can change whenever a new point is awarded to one of the three teams. If the Red team is winning, then the world is red. If the Blue team is in the lead, then the world is blue. This helps because I can use green, purple, and orange to show when two teams are tied for points.

It seems like a network containing 7 nodes (six colors + neutral for a three-way tie), with each node connected to 3 other nodes. I need to write Twine code that 1) identifies which node was the previous world state, and 2) which node should be the new world state.

Stumbling towards an answer on my own, it looks like this:

When a RED point is added
If state is red, do nothing.
If state is orange or purple or neutral, move to red
If state is yellow, and $redPoints = $yellowPoints, move to orange
If state is blue, and $redPoints = $bluePoints, move to purple
If state is green, and $redPoints = $bluePoints, move to neutral
When a YELLOW point is added
If state is yellow, do nothing.
If state is orange or green or neutral, move to yellow
If state is blue, and $yellowPoints = $bluePoints, move to green
If state is red, and $yellowPoints = $redPoints, move to orange
If state is purple, and $yellowPoints = $redPoints, move to neutral
When a BLUE point is added
If state is blue, do nothing.
If state is purple or green or neutral, move to blue
If state is red, and $bluePoints = $redPoints, move to purple
if state is yellow, and $bluePoints = $yellowPoints, move to green
if state is orange, and $bluePoints = $yellowPoints, move to neutral

Writing out code in SugarCube, this part goes in the StoryCaption passage:
Ascore: <<print $aScore>>
Bscore: <<print $bScore>>
Cscore: <<print $cScore>>

<<if $worldState == "A">>Red
<<elseif $worldState == "B">>Blue
<<elseif $worldState == "C">>Yellow
<<elseif $worldState == "AB">>Purple
<<elseif $worldState == "CA">>Orange
<<elseif $worldState == "BC">>Green
<<else>>neutral<</if>>
It lets you see how many points have been assigned to each faction, and it shows the current world state. (I simplified the teams to be A, B, and C in the code.)

This part goes in the passage where Red gains a point:

<<set $aScore += 1>>
<<if $worldState == "AB" or $worldState == "CA" or $worldState == "N" >><<set $worldState = "A">>
<<elseif $worldState == "B" and $aScore == $bScore>><<set $worldState = "AB">>
<<elseif $worldState == "C" and $aScore == $cScore>><<set $worldState = "CA">>
<<elseif $worldState == "BC" and $aScore == $bScore>><<set $worldState = "N">>
<</if>>
This part goes in the passage where Blue gains a point:

<<set $bScore += 1>>
<<if $worldState == "AB" or $worldState == "BC" or $worldState == "N" >><<set $worldState = "B">>
<<elseif $worldState == "C" and $bScore == $cScore>><<set $worldState = "BC">>
<<elseif $worldState == "A" and $bScore == $aScore>><<set $worldState = "AB">>
<<elseif $worldState == "CA" and $bScore == $aScore>><<set $worldState = "N">>
<</if>>
And this part goes in the passage where Yellow gains a point:

<<set $cScore += 1>>
<<if $worldState == "CA" or $worldState == "BC" or $worldState == "N" >><<set $worldState = "C">>
<<elseif $worldState == "A" and $cScore == $aScore>><<set $worldState = "CA">>
<<elseif $worldState == "B" and $cScore == $bScore>><<set $worldState = "BC">>
<<elseif $worldState == "AB" and $cScore == $aScore>><<set $worldState = "N">>
<</if>>
I should probably leave this to the professionals, but I got this code to work after a lot of trial and error.

Image credit: By Jackelynelc - Own work, CC BY-SA 4.0, Link