SnakeEffect now uses a hand-crafted meandering algorithm. Still not perfect, but it works as good as the old code while looking more "natural".
This commit is contained in:
		@@ -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++;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user