From 9de77349e830800827d10cc92a6707ec0701bfcb Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Thu, 30 Apr 2020 06:40:05 +0200 Subject: [PATCH] SnakeEffect now uses a hand-crafted meandering algorithm. Still not perfect, but it works as good as the old code while looking more "natural". --- src/effect_snake.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/effect_snake.cpp b/src/effect_snake.cpp index 64c0840..08c999d 100644 --- a/src/effect_snake.cpp +++ b/src/effect_snake.cpp @@ -30,10 +30,6 @@ SnakeEffect::~SnakeEffect() { } void SnakeEffect::_place_apple() { - if (SNAKE_DEBUG) { - _apple = {3, 3}; - return; - } if (_length < _pixels) { uint8_t start = random8(_pixels); for (int i=0; i<_pixels; i++) { @@ -60,7 +56,7 @@ void SnakeEffect::_decide() { inputs[3] = a_l; inputs[4] = a_s; inputs[5] = a_r; - if (SNAKE_DEBUG) LOGln("SnakeEffect * Position: %d, %d - Inputs: %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f", _pos.x, _pos.y, inputs[0], inputs[1], inputs[2], inputs[3], inputs[4], inputs[5]); + if (SNAKE_DEBUG) DBG("SnakeEffect * Position: %d, %d - Inputs: %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f", _pos.x, _pos.y, inputs[0], inputs[1], inputs[2], inputs[3], inputs[4], inputs[5]); float* outputs = NULL; uint8_t i=0; for (uint8_t layer=1; layer<_net_layers; layer++) { @@ -92,7 +88,7 @@ void SnakeEffect::_decide() { decision = decision - 1; delete outputs; - if (SNAKE_DEBUG) LOGln("SnakeEffect * Decision: %d", decision); + if (SNAKE_DEBUG) DBG("SnakeEffect * Decision: %d", decision); _dir += decision; if (_dir < 0) _dir += 4; @@ -130,6 +126,36 @@ int8_t SnakeEffect::_manual_decision() { (2) Having a number smaller than the field the apple is on. (Watch out for "overflows".) */ int8_t SnakeEffect::_manual_decision() { + uint8_t head_index = _coords_to_field_id(_pos); + uint8_t apple_index = _coords_to_field_id(_apple); + uint8_t tail_index = _coords_to_field_id(_tail); + if (SNAKE_DEBUG) DBG("SnakeEffect * Decision. head: %d, apple: %d, tail: %d", head_index, apple_index, tail_index); + + uint16_t best_distance = 0xFFFF; + int8_t decision = 0; + + for (int i=-1; i<=1; i++) { // Test all thre possible directions (left, ahead, right) + Coords new_pos = _new_pos(_dir + i); + uint8_t new_index = _coords_to_field_id(new_pos); + + int16_t distance; + if (apple_index >= new_index) { + distance = apple_index - new_index; + } else { + distance = (window->width * window->height) - apple_index + new_index; + } + if (SNAKE_DEBUG) DBG("SnakeEffect * Decision: %d would have distance %d", i, distance); + if (distance < best_distance && _is_free(_dir + i)) { + best_distance = distance; + decision = i; + } + } + + if (SNAKE_DEBUG) DBG("SnakeEffect * Decision taken: %d with distance %d", decision, best_distance); + + /* apple_index > new_index && head_index > apple_index + apple_index > new_index && head_index < apple_index && new_index > head_index + uint16_t head_index = (_head_rounds<<8) | _coords_to_field_id(_pos); uint16_t apple_index = (_head_rounds<<8) | _coords_to_field_id(_apple); uint16_t tail_index = (_tail_rounds<<8) | _coords_to_field_id(_tail); @@ -148,7 +174,7 @@ int8_t SnakeEffect::_manual_decision() { decision = i; best_dist = dist; } - } + }*/ _dir = (_dir + decision) % 4; return decision; } @@ -242,7 +268,7 @@ void SnakeEffect::_move() { } unsigned long now = millis(); - if (_last_move_at < now && now - _last_move_at < 0) { + if (_last_move_at < now && now - _last_move_at < 50) { return; } _round++;