Can Now move a dot across the screen

To add failstate
To add snake food and growth
This commit is contained in:
Uttarayan Mondal
2021-01-05 23:30:43 +05:30
parent e5bbdd7b41
commit 5569f1b345
3 changed files with 94 additions and 43 deletions
+62 -34
View File
@@ -1,53 +1,81 @@
extern crate rand; extern crate rand;
enum CellType { use std::collections::LinkedList;
Snake, pub enum Direction {
Food,
Empty,
}
struct Cell {
line: i32,
col: i32,
ctype: CellType,
}
impl Default for Cell {
fn default() -> Self {
Self {
line: -1,
col: -1,
ctype: CellType::Empty,
}
}
}
enum Direction {
Up, Up,
Down, Down,
Left, Left,
Right, Right,
} }
struct Snake { impl Copy for Direction {}
length: i32, impl Clone for Direction {
fn clone(&self) -> Self {
*self
}
} }
pub enum CellType {
struct SnakeCell { Food,
Snake,
Empty,
}
pub struct Cell {
pub line: i32, pub line: i32,
pub col: i32, pub col: i32,
ctype: CellType,
} }
impl SnakeCell { impl Cell {
fn next(&self, direction: Direction) -> SnakeCell { pub fn new(l: i32, c: i32, t: CellType) -> Cell {
Cell {
line: l,
col: c,
ctype: t,
}
}
}
impl Copy for CellType {}
impl Clone for CellType {
fn clone(&self) -> CellType {
*self
}
}
impl Copy for Cell {}
impl Clone for Cell {
fn clone(&self) -> Cell {
*self
}
}
pub struct Snake {
head: Cell,
pub body: LinkedList<Cell>,
length: i32,
pub direction: Direction,
}
impl Snake {
pub fn new(head: Cell) -> Snake {
let mut temp_body: LinkedList<Cell> = LinkedList::new();
temp_body.push_front(head);
Snake {
head,
body: temp_body,
length: 1,
direction: Direction::Right,
}
}
pub fn smove(&mut self, direction: Direction) {
// smove because move is already a keyword
let mut tail: Cell = self.body.pop_back().unwrap();
tail.ctype = CellType::Empty;
let (dl, dc) = match direction { let (dl, dc) = match direction {
Direction::Up => (-1, 0), Direction::Up => (-1, 0),
Direction::Down => (1, 0), Direction::Down => (1, 0),
Direction::Left => (0, -1), Direction::Left => (0, -1),
Direction::Right => (0, 1), Direction::Right => (0, 1),
}; };
self.direction = direction;
SnakeCell { self.head = Cell::new(self.head.line + dl, self.head.col + dc, CellType::Snake);
line: self.line + dl, self.body.push_front(self.head);
col: self.col + dc,
// ctype: self.ctype,
}
} }
} }
+16 -3
View File
@@ -1,5 +1,8 @@
// use ncurses::*; // use ncurses::*;
use ncurses::{box_, delwin, keypad, newwin, wborder, wrefresh, WINDOW}; use crate::game::backend::Snake;
use ncurses::{
box_, delwin, keypad, mvwaddstr, newwin, wborder, wclrtobot, wmove, wrefresh, WINDOW,
};
pub fn game_window(mlines: i32, mcols: i32, vmargin: i32, hmargin: i32) -> WINDOW { pub fn game_window(mlines: i32, mcols: i32, vmargin: i32, hmargin: i32) -> WINDOW {
let game_win: WINDOW; let game_win: WINDOW;
let (lines, cols): (i32, i32); let (lines, cols): (i32, i32);
@@ -18,9 +21,19 @@ pub fn game_window(mlines: i32, mcols: i32, vmargin: i32, hmargin: i32) -> WINDO
} }
pub fn destroy_window(win: WINDOW) { pub fn destroy_window(win: WINDOW) {
// wmove(win, 0, 0); wmove(win, 0, 0);
// wclrtobot(win); wclrtobot(win);
wborder(win, 32, 32, 32, 32, 32, 32, 32, 32); // 32 is the ascii code for whitespace. this replaces all the window borders with whitespace wborder(win, 32, 32, 32, 32, 32, 32, 32, 32); // 32 is the ascii code for whitespace. this replaces all the window borders with whitespace
wrefresh(win); // refresh to remove the borders wrefresh(win); // refresh to remove the borders
delwin(win); // delete the window delwin(win); // delete the window
} }
pub fn draw_snake(snake: &mut Snake, game_win: WINDOW) {
let mut snake_iter = snake.body.iter();
for snake_cell in snake_iter.next() {
wmove(game_win, 0, 0);
wclrtobot(game_win);
box_(game_win, 0, 0);
mvwaddstr(game_win, snake_cell.line, snake_cell.col, "x");
}
}
+16 -6
View File
@@ -2,7 +2,10 @@ mod backend;
mod frontend; mod frontend;
use crate::menu; use crate::menu;
// use ncurses::*; // use ncurses::*;
use ncurses::{getmaxyx, stdscr, wgetch, wrefresh, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_UP, WINDOW}; use backend::{Cell, Snake};
use ncurses::{
getmaxyx, nodelay, stdscr, wgetch, wrefresh, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_UP, WINDOW,
};
use std::thread::sleep; use std::thread::sleep;
pub fn start() { pub fn start() {
let (mut mlines, mut mcols): (i32, i32) = (0, 0); let (mut mlines, mut mcols): (i32, i32) = (0, 0);
@@ -11,14 +14,18 @@ pub fn start() {
// let mut choice: i8; // let mut choice: i8;
getmaxyx(stdscr(), &mut mlines, &mut mcols); getmaxyx(stdscr(), &mut mlines, &mut mcols);
game_win = frontend::game_window(mlines, mcols, 5, 10); game_win = frontend::game_window(mlines, mcols, 5, 10);
let mut snake = Snake::new(Cell::new(mlines / 2, mcols / 2, backend::CellType::Snake));
nodelay(game_win, true);
loop { loop {
frontend::draw_snake(&mut snake, game_win);
ch = wgetch(game_win); ch = wgetch(game_win);
match ch { match ch {
KEY_UP => (), KEY_UP => snake.smove(backend::Direction::Up),
KEY_DOWN => (), KEY_DOWN => snake.smove(backend::Direction::Down),
KEY_LEFT => (), KEY_LEFT => snake.smove(backend::Direction::Left),
KEY_RIGHT => (), KEY_RIGHT => snake.smove(backend::Direction::Right),
112 => { 112 => {
nodelay(game_win, false);
match menu::pause_menu_control() { match menu::pause_menu_control() {
//112 is keycode for 'p' //112 is keycode for 'p'
0 => (), //resume 0 => (), //resume
@@ -27,11 +34,14 @@ pub fn start() {
_ => (), //other charachters just in case _ => (), //other charachters just in case
} }
wrefresh(game_win); wrefresh(game_win);
nodelay(game_win, true);
} }
27 => break, 27 => break,
_ => (), _ => (),
} }
sleep(std::time::Duration::new(0, 10)); sleep(std::time::Duration::from_millis(300));
snake.smove(snake.direction);
} }
frontend::destroy_window(game_win); frontend::destroy_window(game_win);
} }