Creating a Yahtzee Game within Nextion Logic

This thread will show how to create the Yahtzee dice game and keep the game scoring all within the Nextion logic without the need for an external microprocessor. As we go through the process of creating this game, I will deal with a few techniques that may be useful in your projects. A special shout out to Steve (indev2) for tripping across the b[.id] component array and to Gerry Kropf for his short and sweet val=1-val boolean toggle.

And from time to time … I maybe toss in another variable component or two.

Step 4

So, it is soon about time to include an HMI file,
I am using the 3.5″ 480×320 Enhanced Nextion model for this project <order it here>
Attached is the yahtzee.HMI file created with the Nextion Editor version 0.40
You can download the HMI and then we can start to get on with the coding.

Step 5

The first thing to take care of with rolling our dice will be to have them roll somewhat random. For this we need to add a random factor to have the dice roll. We also want to initialize the number of dice rolls to three. So in the page0 Page PreInitialize Event we add

randset 0,65535tr.val=3

So, although it may be true that for a dice roll we need only six values, 0 to 5,

we could have use randset 0,5, and then p3.pic=rand

we can actually get a better randomness from a modulo of the larger value

so randset 0,65535 and then p3.pic=rand%6

This also requires that out dice pictures are id 0 for dice 1, id 1 for dice 2 .. id 5 for dice 6
So the ordering of our Pictures is intentional and on purpose,
Changing their order and this will fail, so the obvious would be – do not change their order.

p0.pic=rand%6p1.pic=rand%6p2.pic=rand%6p3.pic=rand%6p4.pic=rand%6

Now we add this code info the m0 hostpot for throw, but we also want to add animation. Here we will encapsulate the rolling in a 11 step roll and have it slow down towards the end. To do this we will ask the help of the sys2 system variable and the command delay

Step 6

Ahh, so we just talked about holding some dice back between throws.
So lets quickly see what code we might need to do this.

First in order to hold we will touch the dice to do so,
– so this will go in the Pressed Event of each die

Second, it can only make sense to hold a die if there is a roll remaining
– and then only once the dice have had an original throw.

This already implies two nested if statements, and within this we need to:

toggle the die hold variable dhX.val

set the hold status picture under each corresponding die.

Since we have a 0 or 1 value for the toggle we set off as pic id 7 and on as pic id 8
– this makes the status equal to the hold value + the pic id offset to our status images

p5.pic=dh1.val+7

Credit goes to Gerry Kropf for his shortened binary toggle routine of value=1-value. so

dh1.val=1-dh1.val

This makes the dice hold (die picture p0 Press Event) events

if(tr.val>0){ if(tr.val<3) { dh1.val=1-dh1.val p5.pic=dh1.val+7 }}

This will keep the nested if statements, but change the inner for the next four dice
Second die: dh2.val=1-dh2.val and p6.pic=dh2.val+7Third die: dh3.val=1-dh3.val and p7.pic=dh3.val+7Fourth die: dh4.val=1-dh4.val and p8.pic=dh4.val+7and the final fifth die: dh5.val=1-dh5.val and p9.pic=dh5.val+7

Now at this time we will also code the hotspot m1 Pressed Event

we need to create a new hotspot m1

set the .w attribute to 5 and the .h attribute to 5

we will set this out of the way, perhaps to the left of the Ones label

in here we will tally the scores.

The Upper Subtotal includes n0 (.id of 1) through n5 (.id of 6)
– this needs to be placed in n6.val

If n6.val totals 63 or above, n7.val (.id of 7) needs to be set to 35, otherwise it is 0
Then n6.val + n7.val gets written in both n8.val and n18.val

The Lower Subtotal includes n10 (.id of 8) through n16 (.id of 14)
– this needs to be placed in n17.val

Finally if the game is over, if plays remaining == 0 then

the values from n17.val and n18.val can be combined

this will be placed in n19.val

But since this Final Score isn’t calculated until the game is over

we need to create a new variable component pr for plays remaining

In the page Preinitialize Event we set this equal to 13 pr.val=13

This will allow our m1 hotspot Pressed Event to contain the code:

sys1=0sys2=0for(sys0=1;sys0<=6;sys0++){ sys1=sys1+b[sys0].val}n6.val=sys1if(sys1>=63){ n7.val=35 sys1=sys1+35}n8.val=sys1n18.val=sys1for(sys0=8;sys0<=14;sys0++){ sys2=sys2+b[sys0].val}n17.val=sys2if(pr.val==0){ n19.val=n17.val+n18.val tr.val=0 // ensure there are no more throws remaining as game ended. n9.val=tr.val n19.pco=2016}

This m1 hotspot Pressed Event will be called with the command

click m1,1

This will be done within each of the 13 scoring opportunities … that will be next.

Step 7

Now if we test our HMI design so far, we can roll up to three roll per play
and we can hold the dice as desired when it is permitted
and we have the code to tally our scores …
But how do we set each of our plays? And ensure it is only used once?
In our page PreInitialization Event we are going to initialize this
By setting the number color .pco attribute to the color 2016

we will now know if that play selection is used or unused.

we will need to set this when the game starts

we will need to set to another color when using the play option

We will also set the color of the Final Score n19 to know the game is still in play

But Yahtzee needs to make sure that all dice are the same
– so here we will test if they are all the same
– if the are all the same, regardless of the value, award 50 points in n15
So this is most easily accomplished in a large nested if

Step 10

Okay and now we will deal with the two straights.
For the large straight, the user needs 1-2-3-4-5 or 2-3-4-5-6 and
For the small straight, the user needs 1-2-3-4 or 2-3-4-5, or 3-4-5-6.
The large straight is a bit easier as all dice need to be used.

For this I will assign a twos complement to die value and then check the sum
We will need to create a new variable component nv for this to work
nv.val can only be one of two possible sums to score the 40 points – 124 or 248

Now likewise the small straight is valid only for three counts 60,120, and 240.
But here we must only use 4 dice to arrive at the sum.
So I will create another variable component dr for the die removed.
Again if one of these three values are arrived at, then this will score 30 points

Step 11

Now we are off to the 3 of a Kind.
Here in order to score the points shown on all five dice, the user needs three to be the same.
So I am going to simply check all five dice against the first, the second and the third.
For this I will initialize my dr variable to 0 as I won’t be using it otherwise
and I if I get a three count, I will tally all five dice and assign it into n10.
We will keep all the other maintenance in mind as well

That worked out short than I expected. So the 4 of a Kind will be the same length.
We merely only check the dice against the first and the second and set it to >=4.
Swap out all n10’s for n11’s and the n11 Press Event will look something like:

Step 12

So one final scoring opportunity left to code. Yes! The Full House at n12.
Can you figure this one out … awesome … and that should wrap up our Yahtzee Game.
… just kidding folks. So let’s get started on this one.

The Full House is going to require 3 of a Kind + a Pair, or 5 of a Kind as 3+2 is 5. It would count. (I would be inclined to use my 5 of a Kind for a Yahtzee at 50 points than for a Full House at 25 points) But within the five dice values, there are either only one (with 5 of a Kind) or two (with 3 and the pair). So lets see how we can accomplish this one.

I will probably count the dice that have the same value as the first die, and at the same time use an if statement to find the die position of the second value, and do a count of that value. Remember there is only one or two dice values in a 3+2 to be awarded the 25 points.

Final Step

Now if we run what we have accomplished so far, we get a working game of Yahtzee.
So the question becomes, how do we start a new game once the game has ended.
If we place the page 0 command in the n19 Press Event, the game will restart.
But to ensure that this doesn’t occur mid-game …
– check to ensure the plays remaining is 0

So n19 Press Event looks like:

if(pr.val==0){ page 0}

And there we have it … a working Yahtzee Game all within the Nextion Logic