0

I'm using the random() to generate random coordinates for coins in a simple game console. The problem here is that the random() function is not generating random numbers, since the coin is at the same coordinates every single time I upload it. I am using the Adafruit GFX library with the Adafruit 1.44" Color TFT LCD Display. Here is my code (sorry, it's kind of long).

//necessary libraries
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

//colors #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF

//pins #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8

//joystick variables const int VRxPin = A1; const int VRyPin = A0; const int SWPin = 7; bool mov = false;

//data read from joystick pins int x = 0; int y = 0; int SW = 0;

// X and Y coords for entities int playerx = 50; int playery = 50;

long coinx; long coiny;

//game variables int score = 0;

//defining the tft class Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

//useful text function void output(char *text, int x, int y, uint16_t color, bool wrap = 0){ tft.setCursor(x, y); tft.setTextColor(color); tft.setTextWrap(wrap); tft.print(text); }

//there is probably a better way to do this but im too lazy to find it void num_output(int text, int x, int y, uint16_t color, bool wrap = 0){ tft.setCursor(x, y); tft.setTextColor(color); tft.setTextWrap(wrap); tft.print(text); }

//clears screen void clear() { tft.fillScreen(BLACK); }

//setup (lcd init & startup screen) void setup() { Serial.begin(9600); pinMode(SWPin,INPUT_PULLUP); tft.initR(INITR_GREENTAB);

long coinx = random(20, 100); long coiny = random(20, 100);

clear(); output("RAMBUTAN", 40, 60, RED); delay(1000); clear(); tft.fillRect(playerx, playery, 5, 5, WHITE); tft.fillCircle(coinx, coiny, 5, YELLOW); }

void loop() { //reads data from joystick pins every single tick int VRx = analogRead(VRxPin); int VRy = analogRead(VRyPin); int SW = digitalRead(SWPin);

//converts joystick pin data into directions if (VRx > 250 && VRx < 750 && VRy > 250 && VRy < 750) { // middle } else if (VRx > 511.5 && VRy < 750 && VRy > 240) { // right playery -= 5; mov = true; } else if (VRx < 511.5 && VRy < 750 && VRy > 240) { // left playery += 5; mov = true; } else if (VRy > 511.5 && VRx < 750 && VRx > 240) { // up playerx += 5; mov = true; } else if (VRy < 511.5 && VRx < 750 && VRx > 240) { // down playerx -= 5; mov = true; } else { mov = false; }

if (mov == true) { clear(); tft.fillRect(playerx, playery, 5, 5, WHITE); num_output(score, 10, 10, WHITE); tft.fillCircle(coinx, coiny, 5, YELLOW); mov = false; } delay(100); }

jort57
  • 13
  • 4

2 Answers2

1

You are correct, random() isn't random - it's pseudo random. It returns successive results from a mathematical formula which, to all intents and purposes, is random. It's also predictable, as you have seen.

The formula has a starting value, called the seed, which you can choose your self. Changing that seed gives you a different sequence of random-like numbers.

So the trick is to set the seed to something that is truly random. One common source of randomness, or entropy, is an unconnected ADC input:

randomSeed(analogRead(A3));

You can read more about the randomSeed() function here.

Majenko
  • 105,851
  • 5
  • 82
  • 139
0

As an alternative to Majenko's answer, this is how I generate random n-bit-numbers: for each of the n bits I read the chip temperature (which is pretty noisy), take the least significant bit of the reading and assign it to the corresponding bit in the number. The results are sufficiently random for my purpose at least.

Sim Son
  • 1,878
  • 13
  • 21