Help with Emoji based fruitmachine minigame in Harlowe 3.1

I’ve been struggling with an emoji based fruitmachine minigame.
I’ve got the hold reel(s) function working but I don’t want it on all the time. I just want it to pop up every 1 in 6 spins or so. I’ve been going round in circles with this all weekend. Would appreciate a hand. Ta!

{	
<!--INITIALIZE FRUITS-->	

(set: $fruit1_R1 to "🍒")
(set: $fruit2_R1 to "🍐")
(set: $fruit3_R1 to "🍋")
(set: $fruit4_R1 to "🍊")
(set: $fruit5_R1 to "🍉")
(set: $fruit6_R1 to "🔔")

(set: $fruit1_R2 to "🍒")
(set: $fruit2_R2 to "🍐")
(set: $fruit3_R2 to "🍋")
(set: $fruit4_R2 to "🍊")
(set: $fruit5_R2 to "🍉")
(set: $fruit6_R2 to "🔔")

(set: $fruit1_R3 to "🍒")
(set: $fruit2_R3 to "🍐")
(set: $fruit3_R3 to "🍋")
(set: $fruit4_R3 to "🍊")
(set: $fruit5_R3 to "🍉")
(set: $fruit6_R3 to "🔔")

<!--INITIALIZE REELS AND SET TO STOP-->

(if: $fruitInitialize is 0)[
(set: $REEL1 to $fruit1_R1)(set: $REEL2 to $fruit2_R2)(set: $REEL3 to $fruit3_R3)(set: $fruitInitialize to 1)]
(set: $reelstop1 to 1)(set: $reelstop2 to 1)(set: $reelstop3 to 1)

<!--DISPLAY REELS-->
=><=

(live: 0.1s)[(show:?REEL1)(show:?REEL2)(show:?REEL3)(stop:)]
(css: "font-size: 400%")[
|REEL1)[$REEL1]<b>⬛</b>|REEL2)[$REEL2]<b>⬛</b>|REEL3)[$REEL3]
]
<br><br>
<!--RANDOMIZE FRUITS-->
(live: 0.1s)[
(if: $reelstop1 is 0)[
	(set: $reel1 to (random:1,6))
	(if: $reel1 is 1)[(set: $REEL1 to $fruit1_R1)]
	(if: $reel1 is 2)[(set: $REEL1 to $fruit2_R1)]
	(if: $reel1 is 3)[(set: $REEL1 to $fruit3_R1)]
	(if: $reel1 is 4)[(set: $REEL1 to $fruit4_R1)]
	(if: $reel1 is 5)[(set: $REEL1 to $fruit5_R1)]
	(if: $reel1 is 6)[(set: $REEL1 to $fruit6_R1)]
	(replace: ?REEL1)[$REEL1]
	]


(if: $reelstop2 is 0)[
	(set: $reel2 to (random:1,6))
	(if: $reel2 is 1)[(set: $REEL2 to $fruit1_R2)]
	(if: $reel2 is 2)[(set: $REEL2 to $fruit2_R2)]
	(if: $reel2 is 3)[(set: $REEL2 to $fruit3_R2)]
	(if: $reel2 is 4)[(set: $REEL2 to $fruit4_R2)]
	(if: $reel2 is 5)[(set: $REEL2 to $fruit5_R2)]
	(if: $reel2 is 6)[(set: $REEL2 to $fruit6_R2)]
	(replace: ?REEL2)[$REEL2]
	]
	
(if: $reelstop3 is 0)[
	(set: $reel3 to (random:1,6))
	(if: $reel3 is 1)[(set: $REEL3 to $fruit1_R3)]
	(if: $reel3 is 2)[(set: $REEL3 to $fruit2_R3)]
	(if: $reel3 is 3)[(set: $REEL3 to $fruit3_R3)]
	(if: $reel3 is 4)[(set: $REEL3 to $fruit4_R3)]
	(if: $reel3 is 5)[(set: $REEL3 to $fruit5_R3)]
	(if: $reel3 is 6)[(set: $REEL3 to $fruit6_R3)]
	(replace: ?REEL3)[$REEL3]
	]	
	
]


|RESULT)[]

<br><br>

<!--HOLD REELS FEATURE-->

(live:0.1s)[(show: ?HOLD1)(show: ?HOLD2)(show: ?HOLD3)]

|HOLD1)[
(link-repeat: "HOLD1<b>⬛</b>")[
(set: $HOLD1 to 1)(replace: ?HOLD1)[HELD!<b>⬛</b>]
(replace: ?RESULT)[]
		]	
	]

|HOLD2)[
(link-repeat: "HOLD2<b>⬛</b>")[
(set: $HOLD2 to 1)(replace: ?HOLD2)[HELD!<b>⬛</b>]]
	]

|HOLD3)[
(link-repeat: "HOLD3<b>⬛</b>")[
(set: $HOLD3 to 1)(replace: ?HOLD3)[HELD!<b>⬛</b>]
		]
	]

<!--SPIN REELS ON LINK CLICK (DON'T SPIN IF HELD)-->

<br><br>(link-repeat: "START")[
(live: 0.1s)[
(if: $HOLD1 is 0 and $HOLD2 is 0 and $HOLD3 is 0)[
(set: $reelstop1 to 0)(set: $reelstop2 to 0)(set: $reelstop3 to 0)]
(if: $HOLD1 is 0 and $HOLD2 is 0 and $HOLD3 is 1)[
(set: $reelstop1 to 0)(set: $reelstop2 to 0)(set: $reelstop3 to 1)]
(if: $HOLD1 is 0 and $HOLD2 is 1 and $HOLD3 is 0)[
(set: $reelstop1 to 0)(set: $reelstop2 to 1)(set: $reelstop3 to 0)]
(if: $HOLD1 is 1 and $HOLD2 is 0 and $HOLD3 is 0)[
(set: $reelstop1 to 1)(set: $reelstop2 to 0)(set: $reelstop3 to 0)]
(if: $HOLD1 is 1 and $HOLD2 is 1 and $HOLD3 is 0)[
(set: $reelstop1 to 1)(set: $reelstop2 to 1)(set: $reelstop3 to 0)]
(if: $HOLD1 is 0 and $HOLD2 is 1 and $HOLD3 is 1)[
(set: $reelstop1 to 0)(set: $reelstop2 to 1)(set: $reelstop3 to 1)]
(if: $HOLD1 is 1 and $HOLD2 is 0 and $HOLD3 is 1)[
(set: $reelstop1 to 1)(set: $reelstop2 to 0)(set: $reelstop3 to 1)]
(stop:)]

<!STOP REELS AT RANDOM RESULT-->

(live: 1.4s)[
(set: $reelstop1 to 1)(set: $reelstop2 to 1)(set: $reelstop3 to 1)
(set: $HOLD1 to 0)(set: $HOLD2 to 0)(set: $HOLD3 to 0)

<!--RESET HOLD ON REEL 1-->
(replace: ?HOLD1)[(link-repeat: "HOLD1<b>⬛</b>")[
(set: $HOLD1 to 1)(replace: ?HOLD1)[HELD!<b>⬛</b>]
	]
]
<!--RESET HOLD ON REEL 2-->
(replace: ?HOLD2)[
(link-repeat: "HOLD2<b>⬛</b>")[
(set: $HOLD2 to 1)(replace: ?HOLD2)[HELD!<b>⬛</b>]
	]
]
<!--RESET HOLD ON REEL 3-->
(replace: ?HOLD3)[
(link-repeat: "HOLD3<b>⬛</b>")[
(set: $HOLD3 to 1)(replace: ?HOLD3)[HELD!<b>⬛</b>]
	]
]

(if: $REEL1 and $REEL2 is $REEL3)[
(if: $REEL1 is "🍒")[(set: $winamount to 20)(set: $money to $money +20)]
(if: $REEL1 is "🍐")[(set: $winamount to 30)(set: $money to $money +30)]
(if: $REEL1 is "🍋")[(set: $winamount to 40)(set: $money to $money +40)]
(if: $REEL1 is "🍊")[(set: $winamount to 50)(set: $money to $money +50)]
(if: $REEL1 is "🍉")[(set: $winamount to 50)(set: $money to $money +50)]
(if: $REEL1 is "🔔")[(set: $winamount to 100)(set: $money to $money +100)]
(replace: ?RESULT)[YOU'VE WON $winamount!]
]
(stop:)]
]

}
1 Like

The following is a variation of your own example that uses less variable and conditional macros, but it does use some more advance macros like (renew:) and it also uses CSS within your project’s Story Stylesheet area to control the layout of the screen.

1: Initialise the following variables within your project’s startup tagged Passage.
note: you may already be initialising variables like $winamount and $money

(set: $Gap to "<b>⬛</b>")
(set: $Reel to (a: "🍒", "🍐", "🍋", "🍊", "🍉", "🔔"))
(set: $Earn to (a: 20, 30, 40, 50, 50, 100))

(set: $spins to 0)

<!-- Current index of each of the three Reels -->
(set: $R1 to 1, $R2 to 1, $R3 to 1)

(set: $HoldR1 to false, $HoldR2 to false, $HoldR3 to false)

(set: $winamount to 0, $money to 0)

2: Replace your existing Passage code with the following

|Reels>[\
	|reel>[(print: $Reel's ($R1))]\
	(print: $Gap)\
	|reel>[(print: $Reel's ($R2))]\
	(print: $Gap)\
	|reel>[(print: $Reel's ($R3))]\
]

|Holds>[\
	|hold>[{
		(if: $HoldR1)[
			HELD
		]
		(else:)[
			(link: "HOLD")[
				(set: $HoldR1 to true)
				(rerun: ?Holds)
			]
		]
	}]\
	(print: $Gap)\
	|hold>[{
		(if: $HoldR2)[
			HELD
		]
		(else:)[
			(link: "HOLD")[
				(set: $HoldR2 to true)
				(rerun: ?Holds)
			]
		]
	}]\
	(print: $Gap)\
	|hold>[{
		(if: $HoldR3)[
			HELD
		]
		(else:)[
			(link: "HOLD")[
				(set: $HoldR3 to true)
				(rerun: ?Holds)
			]
		]
	}]\
]

|action>[{
	(link-repeat: "SPIN")[{
		(set: $spins to it + 1)
		
		<!-- animate the reels -->
		(set: _iteration to 0)
		(live: 250ms)[
			(set: _iteration to it + 1)
			(unless: $HoldR1)[
				(set: $R1 to (random: 1, 6))
			]
			(unless: $HoldR2)[
				(set: $R2 to (random: 1, 6))
			]
			(unless: $HoldR3)[
				(set: $R3 to (random: 1, 6))
			]
			(rerun: ?Reels)
			(if: _iteration is 6)[
				(stop:)
				
				<!-- Reset the Holds -->
				(set: $HoldR1 to false, $HoldR2 to false, $HoldR3 to false)
				(rerun: ?Holds)
				
				<!-- Determine the result -->
				(rerun: ?Result)
			]
		]
	}]
}]

|Result>[{
	(if: $spins > 0 and $R2 is $R1 and $R3 is $R1)[
		(set: $winamount to $Earn's ($R1))
		(set: $money to it + $winamount)
		YOU'VE WON $winamount!
	]
}]

You may notice the usage of the (rerun:) macro to force specific areas of the page to update their contents as needed, and that each of those specific areas contain the code needed to determine what exactly is shown in that area & when.
note: The above Passage example includes line-break plus indentation based formatting to make the code a little easier to read. Most of that formatting can be safely removed if you want.

3: Add the following CSS to the Story Stylesheet area of your project.

tw-hook[name="reels"]{
	display: grid;
	grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
	max-width: 70%;
	margin-left: auto;
	margin-right: auto;
	text-align: center;
}
tw-hook[name="reels"] tw-hook[name="reel"] {
	font-size: 400%;
}

tw-hook[name="holds"]{
	display: grid;
	grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
	max-width: 70%;
	margin-left: auto;
	margin-right: auto;
	text-align: center;
}

tw-hook[name="action"]{
	display: block;
	text-align: center;
}

It uses an advanced Grid based layout feature to create the 5 columns used to display both the Reels and Holds. An article about using Grid can be found here.

Regarding your question, are you asking how to control the Holds section of the page so that those links only appear after each 6th spin?

1 Like

Amazing, Greyelf. Thank you!
It’s so good to be learning new ways to make things cleaner.

Yes or rather that there should be a 1 in 6 chance of the Holds section appearing.

There are two basic techniques you could use to achieve this effect in my previous example:

1: Use the (hide:) and (show:) macros within the body of the “SPIN” link to control the displaying of the Holds area.

<!-- Reset the Holds -->
(set: $HoldR1 to false, $HoldR2 to false, $HoldR3 to false)
(rerun: ?Holds)
(hide: ?Holds)
(if: (random: 1,6) is 6)[
	(show: ?Holds)
]

You might also want to change the Holds Named hook into a Hidden hook, so that that area doesn’t initially show when the game is first shown to the end-user.

2: Use a Boolean variable within the body of the Holds Named hook to control the displaying of the hook’s content, a little like how the Numerical $spin variable is used to control the initial displaying of the Result Named hook content.

warning: This technique would likely also result in the Grid based CSS used to layout the elements of the Holds Named hook needing to be altered to take into account the new HTML element structure of that hook’s content.

1 Like

Thank you so much!