diff options
-rw-r--r-- | kbd.h | 1 | ||||
-rw-r--r-- | snake.c | 41 |
2 files changed, 30 insertions, 12 deletions
@@ -9,6 +9,7 @@ #define KBD_FLAG_BREAK (_BV(1)) #define KBD_FLAG_EXT (_BV(2)) +#define KBD_CODE_SPACE 0x29 #define KBD_CODE_UP 0xe075 #define KBD_CODE_LEFT 0xe06b #define KBD_CODE_DOWN 0xe072 @@ -4,6 +4,7 @@ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> +#include <stdbool.h> typedef struct _point_t { @@ -20,6 +21,8 @@ typedef enum _dir_t { static volatile uint8_t dir; +static volatile bool start = false; +static volatile uint16_t lfsr = 0xace1; static point_t tail = {7, 4}; @@ -32,7 +35,6 @@ static uint8_t history_pos = 0; static point_t q; static uint16_t rand(void) { - static uint16_t lfsr = 0xace1; unsigned bit; /* taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1 */ @@ -42,6 +44,10 @@ static uint16_t rand(void) { return lfsr; } +static void rand_mix(uint16_t mix) { + lfsr ^= mix; +} + static void rand_q(void) { q.x = rand() % 14; q.y = rand() % 9; @@ -78,6 +84,8 @@ static uint8_t get_dir(uint8_t i) { } static void reset(void) { + LedSignClear(0); + rand_q(); dir = EAST; @@ -95,6 +103,10 @@ void kbd_handle(uint16_t code, bool make) { return; switch(code) { + case KBD_CODE_SPACE: + start = true; + break; + case KBD_CODE_UP: dir = NORTH; break; @@ -142,9 +154,11 @@ static bool point_used(const point_t *p, bool head) { return false; } -static void step(void) { +static bool step(void) { uint8_t d = dir; + rand_mix(d); + LedSignSet(tail.x, tail.y, 0); int i; @@ -160,9 +174,8 @@ static void step(void) { go(&pt, d); LedSignSet(pt.x, pt.y, 3); - if (point_used(&pt, true)) { - while(true) {} - } + if (point_used(&pt, true)) + return false; if (points_equal(&pt, &q)) { rand_q(); @@ -173,26 +186,30 @@ static void step(void) { move(d, false); } - if (point_used(&pt, false)) { - while(true) {} - } + if (point_used(&pt, false)) + return false; LedSignSet(q.x, q.y, 7); + + return true; } int main() { LedSignInit(GRAYSCALE); kbd_init(); - reset(); - sei(); kbd_send(KBD_CMD_RESET); while(true) { - step(); - _delay_ms(100); + while (!start) {} + start = false; + + reset(); + + while (step()) + _delay_ms(100); } return 0; |