From ffc274808d245f989e12b169e16200cc660ef32e Mon Sep 17 00:00:00 2001 From: FantasyPvP <80643031+FantasyPvP@users.noreply.github.com> Date: Thu, 5 Oct 2023 18:07:21 +0100 Subject: [PATCH] update snake.rs rewriting the snake game code --- src/user/bin/snake.rs | 76 ++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/src/user/bin/snake.rs b/src/user/bin/snake.rs index 135ad47..3784e39 100644 --- a/src/user/bin/snake.rs +++ b/src/user/bin/snake.rs @@ -1,11 +1,13 @@ use alloc::string::String; use alloc::{format, vec, vec::Vec, boxed::Box}; use core::arch::x86_64::_mm_test_all_ones; +use core::cell::RefCell; use async_trait::async_trait; use crate::std::io::{Color, Screen, Stdin}; use crate::std::time; use crate::kernel::tasks::keyboard::KEYBOARD; use crossbeam_queue::SegQueue; +use lazy_static::lazy_static; use crate::kernel::render::{ColorCode, ScreenChar}; use crate::std::application::{Application, Error}; use crate::std::random::Random; @@ -48,6 +50,7 @@ pub struct Game { } + #[async_trait] impl Application for Game { fn new() -> Self { @@ -66,8 +69,12 @@ impl Application for Game { self.render().map_err(|_| Error::ApplicationError(String::from("failed to render game screen")))?; // make the first poi + + self.snakes.borrow_mut().push(Snake::player(0)); + for i in 0..5 { self.new_poi(); + self.snakes.borrow_mut().push(Snake::ai(i + 1)); } // run the game @@ -88,10 +95,31 @@ impl Game { time::wait(0.1); - let res = self.snakes.iter_mut().map(|s| s.next(&self.pois, &self.snakes)).collect::>(); + let mut points: Vec; + let length = self.snakes.len(); + let mut status = Vec::new(); + + for i in 0..length { + let points: Vec = self.snakes.clone().into_iter().map(|s| s.tail).flatten().collect(); + let res = self.snakes[i].next(&self.pois, &points); + status.push(res); + + + + } + + + let res = self.snakes.iter_mut().map(|s| { + + let points: Vec = self.snakes.clone().into_iter().map(|s| s.tail).flatten().collect(); + s.next(&self.pois, &points) + }).collect::>(); + + if res.contains(&Status::Lost) { self.render_end_screen().map_err(|_| Error::ApplicationError(String::from("failed to render end screen")))?; + // loop triggers when game is lost loop { match Stdin::keystroke().await { 'x' => break 'gameloop, @@ -104,14 +132,7 @@ impl Game { self.score += 1; } - - - - - - - - + self.render().map_err(|_| Error::ApplicationError(String::from("failed to render game screen")))?; }; Ok(()) } @@ -126,18 +147,21 @@ impl Game { } fn render(&mut self) -> Result<(), ()> { - // let mut frame = vec![vec![ScreenChar::null(); 80]; 25]; - // snake.into_iter().for_each(|p| { - // frame[p.y as usize][p.x as usize] = ScreenChar::new('@' as u8, ColorCode::new(Color::Cyan, Color::Black)); - // }); - // - // frame[self.poi.y as usize][self.poi.x as usize] = ScreenChar::new('o' as u8, ColorCode::new(Color::Red, Color::Black)); - // let literal = format!("snake go brr score: {}", self.score); - // let msg = Game::centre_text(80, literal); - // frame[1] = msg.chars().map(|c| ScreenChar::new(c as u8, ColorCode::new(Color::LightGreen, Color::Black))).collect(); - // - // let mut elem = ColouredElement::generate(frame, (80, 25)); - // elem.render((0,0)) + let mut frame = vec![vec![ScreenChar::null(); 80]; 25]; + self.snakes.borrow().clone().into_iter().map(|s| s.tail).flatten().for_each(|p| { + frame[p.y as usize][p.x as usize] = ScreenChar::new('@' as u8, ColorCode::new(Color::Cyan, Color::Black)); + }); + + self.pois.iter().for_each(|poi| { + frame[poi.y as usize][poi.x as usize] = ScreenChar::new('o' as u8, ColorCode::new(Color::Red, Color::Black)); + }); + + let literal = format!("snake go brr score: {}", self.score); + let msg = Game::centre_text(80, literal); + frame[1] = msg.chars().map(|c| ScreenChar::new(c as u8, ColorCode::new(Color::LightGreen, Color::Black))).collect(); + + let mut elem = ColouredElement::generate(frame, (80, 25)); + elem.render((0,0)); Ok(()) } @@ -176,7 +200,7 @@ impl Game { - +#[derive(Debug, Clone)] struct Snake { ai_controlled: bool, head: Point, @@ -202,7 +226,7 @@ impl Snake { } } - fn next(&mut self, points_of_interest: &Vec, tails: &Vec) -> Status { // returns (lose_condition, scored) + fn next(&mut self, points_of_interest: &Vec, tails: &Vec) -> Status { // returns (lose_condition, scored) // uses pathing algorithm if ai else keyboard input if human if self.ai_controlled { @@ -237,7 +261,7 @@ impl Snake { if points_of_interest.contains(&self.head) { if !self.ai_controlled { - Status::Scored + return Status::Scored; } } else { self.tail.remove(0); @@ -250,11 +274,9 @@ impl Snake { unimplemented!() // implement a basic pathfinding or random movement algorithm } - fn lose_condition(&mut self, tails: &Vec) -> bool { // where tails includes the tail of every other snake + fn lose_condition(&mut self, tails: &Vec) -> bool { // where tails includes the tail of every other snake let p = self.head.clone(); - let tails: Vec = tails.iter().map(|t| t.tail.flatten()).collect(); - let snake_overlaps = tails.contains(&self.head); // checks if any part of the snake overlaps itself let out_of_bounds = p.x < 0 || p.y < 0 || p.x > 79 || p.y > 24; // checks if the snake goes out of bounds