pitrix/include/effects/snake.h

69 lines
3.5 KiB
C++

#pragma once
#include "Effect.h"
#include "prototypes.h"
#define SNAKE_DIR_NORTH 0
#define SNAKE_DIR_EAST 1
#define SNAKE_DIR_SOUTH 2
#define SNAKE_DIR_WEST 3
#define SNAKE_DEBUG false
class SnakeEffect : public Effect {
private:
Coords _pos;
Coords _apple;
Coords _tail;
int8_t _dir = SNAKE_DIR_NORTH;
uint8_t* _map;
uint16_t _pixels;
uint8_t _length;
unsigned long _last_apple_at;
unsigned long _last_move_at;
uint16_t _round;
// Neural net config
// These are actually float values. But in order to prevent rounding errors and stuff, they are provided
// in form of the raw binary data of the IEE754 floating point numbers.
// In _decide() there's code to memcpy()-convert them to a float.
// Round 340, 223.4 points, length 39, 36% stopped, 64% died
// const uint32_t _weights[36] = {0xbd8e626e, 0xbee2cd2c, 0x3e4d5cab, 0x3eceb8c3, 0xbed0a514, 0x3ec62438, 0x3e947ed4, 0xbe4b8bf2, 0xbf301113, 0xbf3f0a75, 0x3f1868f7, 0xbf0253ca, 0xbedca2f2, 0xbd547c6d, 0x3edd6a8a, 0xbd4b97b6, 0x3f64ec26, 0xbe5323c1, 0x3eccf87d, 0xbf2d4796, 0xbf62b6e8, 0xbf71daf6, 0xbf03f08e, 0xbf222609, 0x3e26c03c, 0xbf497837, 0xbee4d175, 0x3ec601de, 0x3e4e0695, 0x3eef2619, 0xbe849370, 0xbf18fb2b, 0x3f25bbd1, 0xbf3dcd78, 0x3f37a58d, 0x3ef4a25b};
// Round 630, 221.0 points, length 38, 36% stopped, 64% died
const uint32_t _weights[36] = {0xbd25943f, 0xbf279d81, 0x3e25d128, 0x3ec62438, 0x3f0e719c, 0x3eefbea9, 0x3e947ed4, 0xbe5323c1, 0xbf2d4796, 0xbf3f0a75, 0x3f0e45d9, 0xbf0253ca, 0xbedca2f2, 0xbd79073c, 0x3ede80ec, 0xbd4b97b6, 0x3f69a6be, 0xbe4b8bf2, 0x3eccf87d, 0xbf301113, 0xbf62b6e8, 0xbf71daf6, 0xbf204130, 0xbf222609, 0x3e26c03c, 0xbf497837, 0xbee4d175, 0x3ec601de, 0x3e4954eb, 0x3eef2619, 0xbe849370, 0xbf18fb2b, 0x3f25bbd1, 0xbf3b4e44, 0x3f484d59, 0x3edd6a8a};
// Round 193, 164.8 points, length 36, 6% stopped, 94% died
//const uint32_t _weights[36] = {0x3e872ffb, 0xbea57262, 0xbee269bf, 0x3ed790a3, 0xbf54014f, 0x3ecde0a6, 0xbf240a93, 0xbe9e4782, 0x3f205106, 0xbf4465c2, 0xbf79579a, 0xbf07f122, 0x3ed0e1bc, 0xbf7a5a09, 0xbf0fc70b, 0xbf6d1971, 0xbe0f5585, 0xbec94b12, 0x3f51f7a9, 0x3eaac42b, 0xbe6aafa6, 0x3d3e3ce3, 0xbf7c4232, 0xbe634103, 0x3f800000, 0x3eff886c, 0x3deae1e8, 0x3eea6988, 0xbf800000, 0xbf426a20, 0x3e3a0a45, 0xbe848803, 0x3e84e8c9, 0x3ef9fabc, 0xbe7733e6, 0xbecda633};
// Round 13650, 244.8 points, length 42, 34% stopped, 66% died
//const uint32_t _weights[36] = {0xbeb99de3, 0x3e6ca488, 0xbe3e9dad, 0xbed38d4e, 0x3f279fc1, 0xbd367111, 0xbf473843, 0xbf800000, 0x3f614edc, 0xbecc734f, 0xbe59b29d, 0x3d479078, 0x3efa7ca6, 0xbedc6ce6, 0x3f4626a1, 0x3e9d8c2c, 0x3f29e25c, 0x3ebde05d, 0x3e8f3e29, 0xbe8ad92c, 0xbe148f2d, 0x3d4a3ca7, 0xbf800000, 0x3d9cd634, 0x3f29802e, 0xbf2cc57e, 0xbcbfafff, 0x3e280b8a, 0x3f5ff9a3, 0xbf4e29c9, 0x3e8936d2, 0xbf49dda9, 0xbe9bf4c7, 0x3e203ea8, 0xbd4edf4d, 0xbf4e3c05};
const uint8_t _net_layout[3] = {6, 4, 3};
const uint8_t _net_layers = 3;
const uint8_t _net_total_size = 36;
uint8_t _head_rounds = 0;
uint8_t _tail_rounds = 0;
uint16_t _xy2i(uint8_t x, uint8_t y);
uint16_t _xy2i(Coords c);
Coords _i2xy(uint16_t i);
Coords _new_pos(uint8_t dir);
uint8_t _dying = 0;
bool _is_free(uint8_t dir);
uint8_t _free_spaces(uint8_t dir);
uint8_t _to_apple(uint8_t dir);
void _place_apple();
void _init();
void _decide();
uint8_t _coords_to_field_id(Coords);
int8_t _manual_decision();
void _move();
void _draw();
public:
SnakeEffect();
~SnakeEffect();
void loop(uint16_t ms);
boolean can_be_shown_with_clock();
String get_name() override { return "snake"; }
};