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() };