A strange thing happened on my way to making Liar's Dice

Or, perhaps it’s a pretty normal thing. But again, the entire experience is being blatantly counter-intuitive.

I’m not sure how to fix this. There are an equal number of times when I think I can make out that DiceOnHand needs it’s math reconfigured, and reset back to 1

OR

For some reason, the blink throws back up one random colored face.

In Liars Dice, everyone rolls five dice in secret. After this is done, there are rounds of bidding, that declares at a minimum, how many dice of a given number, in grand total, are on the table. Each bid must either increase the number of dice, or increase the current rank of the pip count. If a player bids that there are Two Threes on the table, the next bid must be either Three Threes on the table, or Two Fours. This continues until the bid is challenged. If a challenge is successful, and the bider did not have what he bid actually on the table, after all dice are revealed, he looses a die for the rest of the game.

A Common dice game, in the Pirates Of The Caribbean movies, also marketed under the name Perudo. Etc. Etc. Etc. The game isn’t fleshed out quite yet, as I ((Obviously)) took from my Kingmaker code and wanted to play around a bit. Liars dice felt like a natural step up here. And I thought, [[Heh]] I could tackle it.


byte currentColor = 0;
byte GemColorRandomizer1 = 0;
byte GemColorRandomizer2 = 0;
byte GemColorRandomizer3 = 0;
byte GemColorRandomizer4 = 0;
byte GemColorRandomizer5 = 0;
int  DiceOnHand = 1;

//Declaring Variables Fairly certain this can get cleaned up with better code. 


Color GemColorList[6] = {RED, ORANGE, YELLOW, GREEN, BLUE, MAGENTA}; 
//The "numbers" on the dice. Selected these because they were predefined. A better curation here may help.

void setup() {
  randomize();
  GemColorRandomizer1 =  random(5);
  GemColorRandomizer2 =  random(5);
  GemColorRandomizer3 =  random(5);
  GemColorRandomizer4 =  random(5);
  GemColorRandomizer5 =  random(5);
}

void loop() {

  if (buttonSingleClicked()) {
  setColorOnFace(OFF, 1);
  setColorOnFace(OFF, 2);
  setColorOnFace(OFF, 3);
  setColorOnFace(OFF, 4);
  setColorOnFace(OFF, 5);
  }

  // A Single Click to "hide" the dice under your cup, in case real life calls you away from the game.

 if (buttonLongPressed()) {
  
  if (DiceOnHand == 1) {
  setColorOnFace(GemColorRandomizer1[GemColorList], 1);
  setColorOnFace(GemColorRandomizer2[GemColorList], 2);
  setColorOnFace(GemColorRandomizer3[GemColorList], 3);
  setColorOnFace(GemColorRandomizer4[GemColorList], 4);
  setColorOnFace(GemColorRandomizer5[GemColorList], 5);
  }

  if (DiceOnHand == 2) {
  setColorOnFace(GemColorRandomizer1[GemColorList], 1);
  setColorOnFace(GemColorRandomizer2[GemColorList], 2);
  setColorOnFace(GemColorRandomizer3[GemColorList], 3);
  setColorOnFace(GemColorRandomizer4[GemColorList], 4);
  }

if (DiceOnHand == 3) {
  setColorOnFace(GemColorRandomizer1[GemColorList], 1);
  setColorOnFace(GemColorRandomizer2[GemColorList], 2);
  setColorOnFace(GemColorRandomizer3[GemColorList], 3);
  }

  if (DiceOnHand == 4) {
  setColorOnFace(GemColorRandomizer1[GemColorList], 1);
  setColorOnFace(GemColorRandomizer2[GemColorList], 2);
  }

  if (DiceOnHand == 5) {
  setColorOnFace(GemColorRandomizer1[GemColorList], 1);
  }

  if (DiceOnHand == 6) {
    DiceOnHand = 1;
  }

  //Lengthy Math to roll only the number of dice that you currently still have in play. Another instance where I am certain that this can be expedited with better code. 
  
 }

if (buttonDoubleClicked())
{
  DiceOnHand = (DiceOnHand + 1) % 6;
}

if (buttonMultiClicked())
{
  setColor(OFF);
  GemColorRandomizer1 =  random(5);
  GemColorRandomizer2 =  random(5);
  GemColorRandomizer3 =  random(5);
  GemColorRandomizer4 =  random(5);
  GemColorRandomizer5 =  random(5);
}
// code to re-roll the dice
}

It is not clear what the actual issue is from your description. Can you describe what you did, what you expected to happen and what actually happened?

You current have a blink showing only one face lit up.

Double click from here should set DiceOnHand back up to having 5 faces light after tbe next triple click.

But instead Im not sure what its doing. I feel like it has to increment or decrement an extra time, that doesn’t show anything on the blink, and is also not needed.

Alternately at times it decides it wants to just change dice on hand back to what it was a step previously. Not sure what that is about.

Also, long press restores your current hand if you single click.

Based on this, it will not:

if (buttonDoubleClicked()) {
    DiceOnHand = (DiceOnHand + 1) % 6;
}

DiceOnHand goes from 0 to 5 inclusive (it will never be 6).

According to your game logic, having 1 face lit means DiceOnHand is 5.

After 5 it wraps around to 0 when you double click (due to the code copied above).

You do not handle the case where DiceOnhand is 0 so nothing will happen and it will show the same single lit face as before.

Your other issues might all stem form this.

1 Like

Ok. I made a few changes, edits, and revisions here. I think I got it.

Using an array here could make this code shorter and cleaner. An array is like a table and is great for when you want to store a set of values. You can read about arrays here…

https://www.google.com/search?q=arduino+array

Thanks. I’ll look into this. … There is so much here, that, on one level or another, I know can be done easier. While I do have some programing experience, I don’t think those languages are relevant today, nor were they when I learned them in the late 90s.

I don’t follow how an array provides random dice rolls. My code above creates 5 separate six sided dice, and then rolls them separately. Each die is a fair* six sided die.

*Obligatory “Can a computer truly be random” boilerplate disclaimer.

What is the interaction of an array with my SingleClicked and LongPressed ?

Looking into your cup (LongPressed), and then discovering the contents of the cup, and then covering your cup again (SingleClicked) in order to make a bid / bet, while having the dice remain consistent throughout that experience, – repeatedly, throughout the entire round of play, is what makes Liars Dice, Liars Dice.

If we have to make variables after an Array to get back to what each individual die roll was, I’m not sure that, that’s any better than what I have here. The criticism then becomes that the entire build out of an array is longer and messier.

I’m not saying Array doesn’t have merit, elsewhere, and I am sure it does. I don’t at present understand it’s benefit, in the immediate case, when SingleClicked and LongPressed need to work as coded.

An array is like a table and can be handy when you want to store a set of values like your dice rolls.

So, for example, instead using five different variables for the dice rolls, you could use one array like this…

byte diceValue[5];     // Make an array with 5 elements to hold the values of each of the five dice

for( byte i=0; i<5; i++ ) {
    diceValue[i]=  random(6);  // Each die gets a value between 0 and 5
}

…and then later access the values like this…

if (DiceOnHand == 1) {
  for( byte i=0; i<5; i++) {
      setColorOnFace(GemColorList[diceValue[i]], i);
  }
} 

There are even more compact ways to write those loops, but this should get you started!

Yes they can! The blinks’ randomize() function uses physical entropy from the environment to seed the pseudorandom number generator with true randomness.

1 Like