About random numbers
What you are trying to achieve is actually not that easy. An Arduino is
basically a computer, and as any computer, it is designed to execute
instructions in a very deterministic fashion. Computers are not good
at randomness and, unless fitted with dedicated hardware, they cannot
generate random numbers. Given this, you are left with two options:
- pseudo-random number generators
- entropy gathering
The first is the easiest:
int first_dice = random(1, 7); // 1 (inclusive) to 7 (exclusive)
int second_dice = random(1, 7);
and voilà! You have two random-looking numbers. They are random-looking
in the sense that you will find no obvious pattern in any sequence of
numbers you draw. However, if you reset your Arduino, either with the
reset button or by power-cycling it, it will give you the exact same
sequence as in the first run. Thus, pseudo-randomness in useless unless
you commit to never unpower your circuit. It is a good starting point,
however, if your main goal is to get started with Arduino programming.
Entropy gathering means getting some randomness from outside the
Arduino: you would connect it to some source of randomness and perform
some measurement that has unpredictable outcome. A human being is a good
source of randomness: if you require the user to press a button before
displaying the dice value, the timing of the button press is a good
random source. The micros() function can be used to get the current
time with 4 µs resolution, which is more than enough for this
purpose. Entropy gathering is usually used in tandem with pseudo-random
number generators, as a way to seed them, like this:
wait_for_the_user_to_press_a_button();
randomSeed(micros());
int first_dice = random(1, 7);
int second_dice = random(1, 7);
If you cannot have human interaction, you could try to get some
electromagnetic noise by performing an analogRead() on a floating pin.
Ideally you would connect that pin to an analog noise source. See the
first comment to this answer for more information on this option.
About arrays and loops
You should definitely try to find a good tutorial about arrays and
loops. Whenever you find yourself writing tons of almost-identical lines
of code, you should wonder whether you can replace that repetition with
a loop. For example, for displaying the digit 1, you may write:
if (number == 1) {
digitalWrite(leda, LOW);
digitalWrite(ledb, HIGH);
digitalWrite(ledc, HIGH);
digitalWrite(ledd, LOW);
digitalWrite(lede, LOW);
digitalWrite(ledf, LOW);
digitalWrite(ledg, LOW);
}
(I am using the "canonical" A–G letter assignments, and yes, you should
also take care of setting to LOW the segments you want to be off).
This code is an obvious candidate for being replaced by a loop:
if (number == 1) {
for (int segment = 0; segment < 7; segment++)
digitalWrite(leds[segment], digit1[segment]);
}
This requires that you first define the following arrays:
// A B C D E F G
int leds[] = { 2, 3, 4, 5, 6, 7, 8 };
int digit1[] = { LOW, HIGH, HIGH, LOW, LOW, LOW, LOW};
This logic can be pushed one level further by using a two-dimensional
array (an array of arrays): instead of defining six arrays digit1,
digit2... digit6, you create an array of arrays like this:
int digits[][7] = {
/* A B C D E F G */
/* 1 */ { LOW, HIGH, HIGH, LOW, LOW, LOW, LOW},
/* 2 */ {HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH},
...
};
and you use digits[number] instead of digit1, etc. This way you get
rid of the whole if () ... else if () chain, replaced by:
for (int segment = 0; segment < 7; segment++)
digitalWrite(leds[segment], digits[number-1][segment]);
Take care though that in C++ arrays are indexed from zero, which is why
you need to use number-1 as the index in digits. If you have more
than one die (which is your case), you can also put their pin
assignments in a two-dimensional array. Then all the dice updating code
would be wrapped inside a loop indexed by the die number. Putting all
this together you end up with something like this:
// Pin assignments.
int leds[][7] = {
/* A B C D E F G */
/* 1st die */ { 2, 3, 4, 5, 6, 7, 8 },
/* 2nd die */ { A0, A1, A2, A3, A4, A5, A6 }
};
// 7-segment "font".
int digits[][7] = {
/* A B C D E F G */
/* 1 */ { LOW, HIGH, HIGH, LOW, LOW, LOW, LOW},
/* 2 */ {HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH},
/* 3 */ {HIGH, HIGH, HIGH, HIGH, LOW, LOW, HIGH},
/* 4 */ { LOW, HIGH, HIGH, LOW, LOW, HIGH, HIGH},
/* 5 */ {HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH},
/* 6 */ {HIGH, LOW, HIGH, HIGH, HIGH, HIGH, HIGH}
};
void setup()
{
for (int die = 0; die < 2; die++) {
for (int segment = 0; segment < 7; segment++) {
pinMode(leds[die][segment], OUTPUT);
}
}
}
void loop() {
for (int die = 0; die < 2; die++) {
int number = random(1, 7);
for (int segment = 0; segment < 7; segment++)
digitalWrite(leds[die][segment], digits[number][segment]);
}
delay(200);
}
This is still lacking the entropy gathering phase discussed above.