summaryrefslogtreecommitdiff
path: root/src/move_snake.rs
blob: 453e79550fd27e34948f6998a2c7d0004fe00698 (plain)
use core::time::Duration;

use alloc::vec::Vec;
use rand::RngExt;
use tortuise_script::{random::TortuiseRng, time::Instant, ScriptContext, TortuiseScript};

use crate::{Position, APPLE_LOCATION, DIRECTION, GRID_SIZE, NEXT_MOVE_TIME, SNAKE_CELLS};

pub const MOVE_SNAKE: TortuiseScript = TortuiseScript {
    update: |context: ScriptContext| {
        let mut apple_location = APPLE_LOCATION.get_mut(&context);
        let mut snake_cells = SNAKE_CELLS.get_mut(&context);
        let mut next_move = NEXT_MOVE_TIME.get_mut(&context);
        let direction = DIRECTION.get(&context);

        let mut available_squares =
            Vec::with_capacity((GRID_SIZE * GRID_SIZE) as usize - snake_cells.len());
        for i in 0..GRID_SIZE {
            for j in 0..GRID_SIZE {
                let position = Position {
                    x: i as i16,
                    y: j as i16,
                };
                if !snake_cells.contains(&position) {
                    available_squares.push(position);
                }
            }
        }

        let mut rng = TortuiseRng::new();
        let time = Instant::now(&context);
        if time > *next_move {
            if snake_cells[0] == *apple_location {
                *apple_location = available_squares[rng.random_range(0..available_squares.len())];
                let new_head = Position {
                    x: snake_cells[0].x + direction.x,
                    y: snake_cells[0].y + direction.y,
                };
                snake_cells.insert(0, new_head);
            }
            *next_move += Duration::from_millis(200);
            for i in (1..snake_cells.len()).rev() {
                snake_cells[i] = snake_cells[i - 1];
            }
            snake_cells[0].x += direction.x;
            snake_cells[0].y += direction.y;
        }
    },
    ..TortuiseScript::empty()
};