diff --git a/src/game/backend.rs b/src/game/backend.rs index a37bf4c..06c4ed1 100644 --- a/src/game/backend.rs +++ b/src/game/backend.rs @@ -1,53 +1,81 @@ extern crate rand; -enum CellType { - Snake, - 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 { +use std::collections::LinkedList; +pub enum Direction { Up, Down, Left, Right, } -struct Snake { - length: i32, +impl Copy for Direction {} +impl Clone for Direction { + fn clone(&self) -> Self { + *self + } } - -struct SnakeCell { +pub enum CellType { + Food, + Snake, + Empty, +} +pub struct Cell { pub line: i32, pub col: i32, + ctype: CellType, } -impl SnakeCell { - fn next(&self, direction: Direction) -> SnakeCell { +impl Cell { + 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, + length: i32, + pub direction: Direction, +} +impl Snake { + pub fn new(head: Cell) -> Snake { + let mut temp_body: LinkedList = 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 { Direction::Up => (-1, 0), Direction::Down => (1, 0), Direction::Left => (0, -1), Direction::Right => (0, 1), }; - - SnakeCell { - line: self.line + dl, - col: self.col + dc, - // ctype: self.ctype, - } + self.direction = direction; + self.head = Cell::new(self.head.line + dl, self.head.col + dc, CellType::Snake); + self.body.push_front(self.head); } } diff --git a/src/game/frontend.rs b/src/game/frontend.rs index 0897fb1..2563209 100644 --- a/src/game/frontend.rs +++ b/src/game/frontend.rs @@ -1,5 +1,8 @@ // 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 { let game_win: WINDOW; 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) { - // wmove(win, 0, 0); - // wclrtobot(win); + wmove(win, 0, 0); + 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 wrefresh(win); // refresh to remove the borders 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"); + } +} diff --git a/src/game/mod.rs b/src/game/mod.rs index 13bccfb..c8746c9 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -2,7 +2,10 @@ mod backend; mod frontend; use crate::menu; // 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; pub fn start() { let (mut mlines, mut mcols): (i32, i32) = (0, 0); @@ -11,14 +14,18 @@ pub fn start() { // let mut choice: i8; getmaxyx(stdscr(), &mut mlines, &mut mcols); 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 { + frontend::draw_snake(&mut snake, game_win); ch = wgetch(game_win); match ch { - KEY_UP => (), - KEY_DOWN => (), - KEY_LEFT => (), - KEY_RIGHT => (), + KEY_UP => snake.smove(backend::Direction::Up), + KEY_DOWN => snake.smove(backend::Direction::Down), + KEY_LEFT => snake.smove(backend::Direction::Left), + KEY_RIGHT => snake.smove(backend::Direction::Right), 112 => { + nodelay(game_win, false); match menu::pause_menu_control() { //112 is keycode for 'p' 0 => (), //resume @@ -27,11 +34,14 @@ pub fn start() { _ => (), //other charachters just in case } wrefresh(game_win); + nodelay(game_win, true); } 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); }