snake can now move, eat food and grow

This commit is contained in:
2026-03-10 16:39:40 -05:00
parent 33db0eaaef
commit f75ab1ac47
14 changed files with 191 additions and 21 deletions
+7
View File
@@ -27,4 +27,11 @@ impl Field {
pub fn set_tile(&mut self, x: usize, y: usize, tile: Tile) {
self.tiles[y * self.width + x] = tile;
}
pub fn clear_food(&mut self, x: usize, y: usize) {
let current_tile = self.tiles[y * self.width + x];
if current_tile == Tile::Food {
self.tiles[y * self.width + x] = Tile::Empty;
}
}
}
@@ -16,7 +16,9 @@ impl FieldLoader for PlainTextFieldLoader {
let mut tiles = vec![Tile::Empty; width * height];
for (y, line) in lines.iter().enumerate() {
println!("y: {}", y);
for (x, ch) in line.chars().enumerate() {
println!("x: {}", x);
let tile = match ch {
'x' => Tile::Wall,
_ => Tile::Empty,
+15 -3
View File
@@ -1,6 +1,8 @@
use crate::{field::field::{Field, Tile}, game_handler::states::GameManagerState, snake::snake::SnakeHandler};
use std::time::Duration;
use crate::{field::field::{Field, Tile}, game_handler::states::GameManagerState, inputs::Inputs, snake::snake::{Snake, SnakeHandler}};
pub struct GameData {
pub field: Field,
@@ -22,6 +24,16 @@ impl GameData {
}
pub struct GameManager {
game_data: GameData,
game_manager_state: Box<dyn GameManagerState>,
pub game_data: GameData,
pub state: Box<dyn GameManagerState>,
}
impl GameManager {
pub fn update(&mut self, delta: Duration, inputs: &Inputs) {
let new_state = self.state.update(delta, inputs, &mut self.game_data);
if let Some(new_state) = new_state {
self.state = new_state;
}
}
}
+6 -2
View File
@@ -19,7 +19,7 @@ impl PlayingState {
Self { dt_accumulator: Duration::ZERO }
}
fn spawn_food(&mut self, game_data: &mut GameData) {
pub fn spawn_food(&mut self, game_data: &mut GameData) {
let mut empty_positions = Vec::new();
// Get all empty tiles from the field
@@ -51,10 +51,14 @@ impl GameManagerState for PlayingState {
fn update(&mut self, delta: Duration, inputs: &Inputs, game_data: &mut GameData) -> Option<Box<dyn GameManagerState>> {
let mut should_spawn_food = false;
let mut is_food_available = game_data.get_food_count() >= 1;
let all_snakes: Vec<Snake> = game_data.snakes.iter().map(|sh| sh.snake.clone()).collect();
for (current_snake_index, snake_handler) in game_data.snakes.iter_mut().enumerate() {
if snake_handler.snake.is_eating(&game_data.field) {
snake_handler.snake.grow();
should_spawn_food = true;
game_data.field.clear_food(snake_handler.snake.body.position.x as usize, snake_handler.snake.body.position.y as usize);
is_food_available = false;
}
let other_snakes = all_snakes
.iter()
@@ -68,7 +72,7 @@ impl GameManagerState for PlayingState {
.collect();
snake_handler.update(delta, inputs, &other_snakes, &game_data.field);
}
if should_spawn_food {
if should_spawn_food && !is_food_available {
self.spawn_food(game_data);
}
None
+4
View File
@@ -29,4 +29,8 @@ impl Inputs {
pub fn set_pressed(&mut self, input: InputKey, value: bool) {
self.inputs_state.insert(input, value);
}
pub fn clear(&mut self) {
self.inputs_state.clear();
}
}
+4 -2
View File
@@ -96,12 +96,14 @@ impl Snake {
}
pub fn do_move(&mut self) {
println!("moving?");
// probably a more optimal way of approaching this is just
// moving the tail node to head.next, but Rust's borrow checking
// system doesn't allow for that in an easy way
let mut last_position = self.body.position;
println!("prev pos: {:?}", self.body.position);
self.body.position += self.moving_direction; // the first node in body is always the head
println!("next pos: {:?}", self.body.position);
let mut current_node = self.body.next.as_deref_mut();
while let Some(node) = current_node {
let temp = node.position;
@@ -126,7 +128,7 @@ impl Snake {
pub struct SnakeHandler {
pub snake: Snake,
state: Box<dyn SnakeState>,
pub state: Box<dyn SnakeState>,
}
+2
View File
@@ -61,12 +61,14 @@ impl SnakeState for MovingState {
impl SnakeState for StoppedState {
fn update(&mut self, _delta: Duration, _inputs: &Inputs, _snake: &mut Snake, _other_snakes: &Vec<Snake>, _field: &Field) -> Option<Box<dyn SnakeState>> {
println!("stopped?");
None
}
}
impl SnakeState for DeadState {
fn update(&mut self, _delta: Duration, _inputs: &Inputs, _snake: &mut Snake, _other_snakes: &Vec<Snake>, _field: &Field) -> Option<Box<dyn SnakeState>> {
println!("dead?");
None
}
}