From d32f293c999cd9305bc81fd4d50141f6b2049956 Mon Sep 17 00:00:00 2001 From: Uttarayan Mondal Date: Tue, 19 Jan 2021 02:49:10 +0530 Subject: [PATCH] Fixed food spawning and snake collision Fixed the food spawning in the walls Fixed the snake not colliding with itself Added speed control to the snake Exit if the ncurses window is too small --- src/game/backend.rs | 24 +++++++++++++++++++----- src/game/mod.rs | 11 +++++++++-- src/main.rs | 12 +++++++++++- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/game/backend.rs b/src/game/backend.rs index 8942417..e3addda 100644 --- a/src/game/backend.rs +++ b/src/game/backend.rs @@ -69,8 +69,8 @@ impl Cell { pub fn random(lines: i32, cols: i32) -> Cell { let mut rng = rand::thread_rng(); Cell::new( - rng.gen_range(1..lines), - rng.gen_range(1..cols), + rng.gen_range(1..lines - 1), + rng.gen_range(1..cols - 1), CellType::Food, ) } @@ -97,7 +97,7 @@ impl Clone for Cell { enum FailState { Wall, - // Body, + Snake, } enum GameState { @@ -133,6 +133,14 @@ impl Board { self.gamestate = GameState::Failed(FailState::Wall); return true; } + let mut snake_iter = snake.iter(); + snake_iter.next(); + for snake_cell in snake_iter { + if snake.posyx() == snake_cell.posyx() { + self.gamestate = GameState::Failed(FailState::Snake); + return true; + } + } return false; } pub fn check_food(&self, snake: &Snake) -> bool { @@ -176,6 +184,7 @@ pub struct Snake { body: LinkedList, direction: Direction, grow: bool, + speed: i32, } impl Snake { pub fn new(head: Cell) -> Snake { @@ -187,6 +196,7 @@ impl Snake { // length: 1, direction: Direction::Right, grow: false, + speed: 15, } } pub fn posyx(&self) -> (i32, i32) { @@ -217,8 +227,12 @@ impl Snake { self.body.push_front(self.head); self.grow = false; } - pub fn tick(&mut self, time: Duration) { - sleep(time); + pub fn tick(&mut self) { + // sleep(time); + // let time: std::time::Duration = + // std::time::Duration::from_millis((1000 / self.speed) as u64); + // sleep(time); + sleep(Duration::from_millis((1000 / self.speed) as u64)); self.smove(self.direction); } pub fn grow(&mut self) { diff --git a/src/game/mod.rs b/src/game/mod.rs index 2512119..9fb1595 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -12,8 +12,13 @@ pub fn start() { let mut ch: i32; let (vmargin, hmargin): (i32, i32) = (5, 10); getmaxyx(stdscr(), &mut mlines, &mut mcols); + game_win = frontend::game_window(mlines, mcols, vmargin, hmargin); - let mut snake = Snake::new(Cell::new(mlines / 2, mcols / 2, backend::CellType::Snake)); //Initialise snake in the middle of the screen + let mut snake = Snake::new(Cell::new( + mlines / 2 - vmargin, + mcols / 2 - hmargin, + backend::CellType::Snake, + )); //Initialise snake in the middle of the screen let mut board = Board::new(mlines - vmargin * 2, mcols - hmargin * 2); nodelay(game_win, true); loop { @@ -21,6 +26,8 @@ pub fn start() { frontend::draw_board(&board, game_win); // frontend::_log(&snake, &board); if board.check_collision(&snake) { + // Add stuff here to show the score and + // how You lose screen break; } if board.check_food(&snake) { @@ -50,7 +57,7 @@ pub fn start() { nodelay(game_win, true); } // 27 => break, - _ => snake.tick(std::time::Duration::from_millis(100)), + _ => snake.tick(), } } diff --git a/src/main.rs b/src/main.rs index 6abda5a..9ae1405 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,9 @@ mod highscore; mod menu; // use game::{Cell, Snake}; // use ncurses::*; -use ncurses::{curs_set, endwin, initscr, keypad, noecho, raw, refresh, stdscr, CURSOR_VISIBILITY}; +use ncurses::{ + curs_set, endwin, getmaxyx, initscr, keypad, noecho, raw, refresh, stdscr, CURSOR_VISIBILITY, +}; fn main() { // let (lines, cols): (i32, i32) = (0, 0); @@ -13,6 +15,14 @@ fn main() { keypad(stdscr(), true); curs_set(CURSOR_VISIBILITY::CURSOR_INVISIBLE); noecho(); + let (mut mlines, mut mcols): (i32, i32) = (0, 0); + getmaxyx(stdscr(), &mut mlines, &mut mcols); + if (mlines < 20) || (mcols < 35) { + refresh(); + endwin(); + eprintln!("Sorry window size too small"); + std::process::exit(1); + } loop { match menu::main_menu_control() { 0 => game::start(),