Random isnt random?

soooooooo is random not random at all?

``carddraw = random(1 ,52);``

returns 40 every time

Bets $20 you’re doing it wrong. How about the entire sketch?

nope i cant scott will yell at me again

but you can see it here https://github.com/curlyc/deckocards/blob/master/deckocards.ino

you can close this, i was doing something wrong and regardless the code i wrote takes up a ton of memory, sooooooooo unless i can make it tiny (wich i think i can) it wont be anygood for arduboy anyway

Firstly you should use an array (bit array eventually) to keep track of which cards are dealt… and then have a single function to convert a int into a card that returns the string you can use to print. something like / 13 to get the suite and then % 13 to get the card, etc.

1 Like

i was thinking atleast part way on the same path, get the suit first, THEN get the card

beacause clearly my first thought is usless :smiley:

but… this is a good idea, if i can make it work, opens alot of possibilities

The random number generator will always return the same sequence of pseudo-random numbers unless you “seed” it first. Arduino has a randomSeed() function to do this but it needs to be given a random value for the seed (kind of a catch-22 situation).

The library provides the initRandomSeed() function, which attempts to call randomSeed() with a random value. Call it once after calling the begin() function:

void setup() {
  ab.begin();
  ab.setFrameRate(60);
  ab.initRandomSeed(); // <-- seed the random number generator
  ab.clear();
}
1 Like

Your bug is using ‘=’ instead of ‘==’ in the if statements. That means you’re doing an assignment instead of a comparison, so each if that’s not guarded by an else sets the value of carddraw, and you get the value of the last one (40) in each iteration of the loop.

You can guard against that by writing “40 == carddaw” instead, as that’s an error. I’m not sure which C++ compiler the Arduino IDE includes, but the newer GCC & CLANG variants a warning for this construct as well.

And yes, for goddess’es sake use an array! Or two, depending on what you need.

1 Like

thaaaaaaaaaaaaaaaaaaaaaank you… i make that mistake alot, but jesus i did it 52 times in here… i was confused

i need to research arrays in this language, but this thing just might end up being useable :smiley:

can i still get a random value BETWEEN 1-9 with randomseed ?

The arduboy.initRandomSeed() seeds the random number generator using some voodoo magic, I think to make sure you can get good random numbers with the rand(). You can then do some manipulation to that large number to figure out a number between A and B.

int number = rand() % 15 + 10;

I use the above code to find a number between 10 and 25. The way it works is simple.

I find a random number using rand() and then I divide it by 15 and keep the remainder. (That is what the % symbol does.) The remainder will always be a number between 0 and 15 (not including 15). I then add 10 to that to increase the range of possible numbers from 10 to 25 (not including 25).

In your case, you can use the following to get 1~10 (not including 10).

int number = rand() % 8 + 1;
1 Like

FYI, not sure if it is fixed but using initRandomSeed in the past for me was not working (this is old arduboy library).

I have more recently used srand with a combination of the value returned by millis() and the number of frames elapsed since the game started to the first user input.

Fun fact: technically using % ruins the statistical properties of the random function. Never been in a situation where not having modulo bias was important, but aparently a load of mathematicians and crypanalysts get upset about it, so it’s good to know it’s a thing.

Basically the random number generator isn’t actually random.
It’s what’s called a “pseudo random number generator” which means it looks random, but it’s actually a fixed sequence of wildly varying numbers.

To use a different sequence, you have to provide a different ‘seed’ value. (It’s called a seed because it’s put into the generator at the start and is used to effectively ‘grow’ the number sequence.)

Feeding a specific number in as the seed will always generate the same sequence. For example, if you seeded the generator with 5 (by calling srand(5);) you might end up with a sequence like: 42, 234, 123, 87, .... If you left your program running for a while using the random numbers and then re-seeded with 5 it would be like resetting back to the beginning and you’d start getting 42, 234, 123, ... all over again.

This is why the arduboy.initRandomSeed() function exists, it uses a special technique to make sure that the seed is random so you get a different sequence each time.

As for clamping it to a range, follow @crait’s suggestion. To make things easier, make a function like this:

int rangedRand(const int & min, const int & max)
{
    return (rand() % ((max - min) + 1)) + min;
}

So that rangedRand(1, 9) will give you a number between 1 and 9 including 1 and 9 themselves. (Note that this won’t work with negative numbers.)

No need for this. Arduino provides the random() function, which allows you to specify the range.

2 Likes

initRandomSeed() does attempt to provide a different seed by obtaining inputs that hopefully are different each time it’s called, even upon initial boot. However, it will work better if it’s called at a different time after each boot.

You can accomplish this by not calling initRandomSeed() until after the user pushes a button. Since the user likely won’t push the button at exactly the same time after each boot, this helps with randomising the seed.

One good way to do this is by having an intro screen at the start of the game, which can only be exited by a button press, then call initRandomSeed() once, after this screen is exited.

4 Likes

Even better!
So much knowledge floating around the forums.

1 Like

To anyone looking at my earlier code, I’d like to say that this:

Is horribly, horribly wrong - please don’t copy it.
Because of the rules of the % operator in C++ (taking the sign from the left hand side instead of the right) this doesn’t work as intended for any value of rand() less than min.

A correct version (with both bounds inclusive) would look like this:

int rangedRand(const int & min, const int & max)
{
    auto x = ((rand() - min) % ((max - min) + 1));
    return  ((x < 0) ? x + max + 1 : x + min);
}

If I get round to working out one with an exclusive upper bound I’ll post it here again.

As @MLXXXp points out though, this is completely unnecessary for the Arduboy, I’m only providing this because I don’t want to be giving out incorrect code to people and because this is portable (in case anyone needs this for another project).

that could explain why the enemy cant possibly set a piece at the bottom right corner :stuck_out_tongue: more things to fix when i make the next update of tic tac curly (i also will be adding difficulty lvls to the next version, an enemy that just moves randomly is a bit boring id say and i should know ive played that game for hours looking for ways to improve it

1 Like

it can take a reeeeeealy loooooong time for all possible outcomes to become selected 1-24 :stuck_out_tongue: