simon says with pro mini, display, ws2812 and touch keys
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
atmega-simon/rng.c

74 lines
1.3 KiB

//
// Created by MightyPork on 2017/09/16.
//
#include "rng.h"
#include <stdint.h>
#include <stdlib.h>
/** Sequence of colors to show. Seed is constant thorough a game.
* rng_state is used by rand_r() for building the sequence. */
static uint32_t game_seed;
static unsigned long game_rng_state;
static uint8_t last_item;
static uint8_t repeat_count;
#define NUM_CNT 4
static uint16_t weights[NUM_CNT];
void rng_set_seed(uint32_t seed)
{
game_seed = seed;
}
void rng_restart(void)
{
game_rng_state = game_seed;
repeat_count = 0;
last_item = 99;
for (uint8_t i = 0; i < 4; i++) {
weights[i] = 1;
}
}
static uint8_t pick_do(void)
{
uint16_t total = 0;
for (uint8_t i = 0; i < 4; i++) {
total += weights[i];
}
uint16_t rn = rand_r(&game_rng_state) % total;
for (uint8_t i = 0; i < 4; i++) {
if (rn < weights[i]) {
// got our number
for (uint8_t j = 0; j < 4; j++) {
if (i == j) {
weights[j]/=2;
}
else weights[j]+=4;
}
return i;
}
rn -= weights[i];
}
return 0; // this never happens but keeps the compiler happy
}
uint8_t rng_next_item(void)
{
uint8_t item;
while (1) {
item = pick_do();
if (item == last_item) {
repeat_count++;
if (repeat_count < 2) return item;
} else {
last_item = item;
repeat_count = 0;
return item;
}
}
}