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
This commit is contained in:
Uttarayan Mondal
2021-01-19 02:49:10 +05:30
parent 477ffdb036
commit d32f293c99
3 changed files with 39 additions and 8 deletions
+19 -5
View File
@@ -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<Cell>,
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) {
+9 -2
View File
@@ -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(),
}
}
+11 -1
View File
@@ -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(),