Snake doesn't clear the board every run
also changed all i32 to u32
This commit is contained in:
+43
-20
@@ -61,8 +61,8 @@ pub enum CellType {
|
||||
Empty,
|
||||
}
|
||||
pub struct Cell {
|
||||
line: i32,
|
||||
col: i32,
|
||||
line: u32,
|
||||
col: u32,
|
||||
ctype: CellType,
|
||||
}
|
||||
impl PartialEq for Cell {
|
||||
@@ -77,28 +77,37 @@ impl PartialEq for Cell {
|
||||
impl Sub for Cell {
|
||||
type Output = (i32, i32);
|
||||
fn sub(self, rhs: Cell) -> (i32, i32) {
|
||||
return (self.line - rhs.line, self.col - rhs.col);
|
||||
return (
|
||||
self.line as i32 - rhs.line as i32,
|
||||
self.col as i32 - rhs.col as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
impl Cell {
|
||||
pub fn new(l: i32, c: i32, t: CellType) -> Cell {
|
||||
pub fn new(l: u32, c: u32, t: CellType) -> Cell {
|
||||
Cell {
|
||||
line: l,
|
||||
col: c,
|
||||
ctype: t,
|
||||
}
|
||||
}
|
||||
pub fn random(lines: i32, cols: i32) -> Cell {
|
||||
pub fn random(lines: u32, cols: u32) -> Cell {
|
||||
let mut rng = rand::thread_rng();
|
||||
Cell::new(
|
||||
rng.gen_range(1..lines - 1),
|
||||
rng.gen_range(1..cols - 1),
|
||||
rng.gen_range(1..lines - 1) as u32,
|
||||
rng.gen_range(1..cols - 1) as u32,
|
||||
CellType::Food,
|
||||
)
|
||||
}
|
||||
pub fn posyx(&self) -> (i32, i32) {
|
||||
pub fn posyx(&self) -> (u32, u32) {
|
||||
return (self.line, self.col);
|
||||
}
|
||||
pub fn posy(&self) -> u32 {
|
||||
return self.line;
|
||||
}
|
||||
pub fn posx(&self) -> u32 {
|
||||
return self.col;
|
||||
}
|
||||
pub fn chtype(&mut self, ctype: CellType) {
|
||||
self.ctype = ctype;
|
||||
}
|
||||
@@ -138,15 +147,15 @@ enum GameState {
|
||||
}
|
||||
|
||||
pub struct Board {
|
||||
maxlines: i32,
|
||||
maxcols: i32,
|
||||
maxlines: u32,
|
||||
maxcols: u32,
|
||||
gamestate: GameState,
|
||||
food: Cell,
|
||||
}
|
||||
|
||||
// impl Board<'_> {
|
||||
impl Board {
|
||||
pub fn new(maxlines: i32, maxcols: i32) -> Board {
|
||||
pub fn new(maxlines: u32, maxcols: u32) -> Board {
|
||||
Board {
|
||||
maxlines,
|
||||
maxcols,
|
||||
@@ -155,7 +164,7 @@ impl Board {
|
||||
}
|
||||
}
|
||||
pub fn check_collision(&mut self, snake: &Snake) -> bool {
|
||||
let (snake_line, snake_col): (i32, i32) = snake.posyx();
|
||||
let (snake_line, snake_col): (u32, u32) = snake.posyx();
|
||||
if (snake_line >= self.maxlines - 1)
|
||||
|| (snake_col >= self.maxcols - 1)
|
||||
|| (snake_line <= 0)
|
||||
@@ -182,9 +191,12 @@ impl Board {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pub fn food_posyx(&self) -> (i32, i32) {
|
||||
pub fn food_posyx(&self) -> (u32, u32) {
|
||||
return self.food.posyx();
|
||||
}
|
||||
// pub fn food_posy(&self) -> u32 {
|
||||
// return self.food.line;
|
||||
// }
|
||||
pub fn eat_food(&mut self, snake: &mut Snake) {
|
||||
snake.grow();
|
||||
// self.food.chtype(CellType::Empty);
|
||||
@@ -217,7 +229,8 @@ pub struct Snake {
|
||||
body: LinkedList<Cell>,
|
||||
direction: Direction,
|
||||
grow: bool,
|
||||
speed: i32,
|
||||
speed: u32,
|
||||
last_tail: Option<Cell>,
|
||||
}
|
||||
impl Snake {
|
||||
pub fn new(head: Cell) -> Snake {
|
||||
@@ -230,14 +243,14 @@ impl Snake {
|
||||
direction: Direction::Right,
|
||||
grow: false,
|
||||
speed: 15,
|
||||
last_tail: Some(head),
|
||||
}
|
||||
}
|
||||
pub fn posyx(&self) -> (i32, i32) {
|
||||
pub fn posyx(&self) -> (u32, u32) {
|
||||
return (self.head.line, self.head.col);
|
||||
}
|
||||
pub fn smove(&mut self, _direction: Direction) {
|
||||
// smove because move is already a keyword
|
||||
let mut tail: Cell;
|
||||
let direction: Direction;
|
||||
if self.direction == _direction.opposite() {
|
||||
direction = self.direction
|
||||
@@ -245,18 +258,22 @@ impl Snake {
|
||||
direction = _direction
|
||||
}
|
||||
if self.grow == false {
|
||||
tail = self.body.pop_back().unwrap();
|
||||
tail.chtype(CellType::Empty);
|
||||
self.last_tail = Some(self.body.pop_back().unwrap());
|
||||
|
||||
// self.grow = false;
|
||||
}
|
||||
let (dl, dc) = match direction {
|
||||
let (dl, dc): (i32, i32) = match direction {
|
||||
Direction::Up => (-1, 0),
|
||||
Direction::Down => (1, 0),
|
||||
Direction::Left => (0, -1),
|
||||
Direction::Right => (0, 1),
|
||||
};
|
||||
self.direction = direction;
|
||||
self.head = Cell::new(self.head.line + dl, self.head.col + dc, CellType::Snake);
|
||||
self.head = Cell::new(
|
||||
((self.head.line as i32) + dl) as u32,
|
||||
((self.head.col as i32) + dc) as u32,
|
||||
CellType::Snake,
|
||||
);
|
||||
self.body.push_front(self.head);
|
||||
self.grow = false;
|
||||
}
|
||||
@@ -274,4 +291,10 @@ impl Snake {
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Cell> {
|
||||
return self.body.iter();
|
||||
}
|
||||
pub fn remove(&self) -> Option<Cell> {
|
||||
return self.last_tail;
|
||||
}
|
||||
pub fn set_speed(&mut self, speed: u32) {
|
||||
self.speed = speed;
|
||||
}
|
||||
}
|
||||
|
||||
+26
-20
@@ -4,15 +4,15 @@ use ncurses::{
|
||||
box_, delwin, keypad, mvwaddstr, newwin, stdscr, waddstr, wborder, wclrtobot, wmove, wrefresh,
|
||||
WINDOW,
|
||||
};
|
||||
pub fn game_window(mlines: i32, mcols: i32, vmargin: i32, hmargin: i32) -> WINDOW {
|
||||
pub fn game_window(mlines: u32, mcols: u32, vmargin: u32, hmargin: u32) -> WINDOW {
|
||||
let game_win: WINDOW;
|
||||
let (lines, cols): (i32, i32);
|
||||
let (starty, startx): (i32, i32);
|
||||
let (lines, cols): (u32, u32);
|
||||
let (starty, startx): (u32, u32);
|
||||
lines = mlines - vmargin * 2;
|
||||
cols = mcols - hmargin * 2;
|
||||
starty = vmargin;
|
||||
startx = hmargin;
|
||||
game_win = newwin(lines, cols, starty, startx);
|
||||
game_win = newwin(lines as i32, cols as i32, starty as i32, startx as i32);
|
||||
box_(game_win, 0, 0);
|
||||
keypad(game_win, true);
|
||||
wrefresh(game_win);
|
||||
@@ -32,7 +32,7 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
let (mut prev, mut current, _next): (&Cell, &Cell, &Cell);
|
||||
let mut snake_iter = snake.iter();
|
||||
wmove(game_win, 0, 0);
|
||||
wclrtobot(game_win);
|
||||
// wclrtobot(game_win);
|
||||
box_(game_win, 0, 0);
|
||||
|
||||
// I want to draw the snake as ascii box charachters
|
||||
@@ -41,10 +41,16 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
prev = snake_iter.next().unwrap(); // currently this should be head. On initial run this should be the only snake_cell
|
||||
mvwaddstr(
|
||||
game_win,
|
||||
prev.posyx().0,
|
||||
prev.posyx().1,
|
||||
prev.posy() as i32,
|
||||
prev.posx() as i32,
|
||||
&format!("{}", std::char::from_u32(0x0298).unwrap_or('O')),
|
||||
);
|
||||
match snake.remove() {
|
||||
Some(tail) => {
|
||||
mvwaddstr(game_win, tail.posy() as i32, tail.posx() as i32, " ");
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
let _current = snake_iter.next();
|
||||
current = match _current {
|
||||
Some(cell) => cell,
|
||||
@@ -52,7 +58,7 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
};
|
||||
for next in snake_iter {
|
||||
// O(n) the whole snake is redrawn every single tick
|
||||
let (snake_l, snake_c): (i32, i32) = current.posyx();
|
||||
let (snake_l, snake_c): (u32, u32) = current.posyx();
|
||||
// mvwaddstr(game_win, snake_l, snake_c, "o");
|
||||
let snake_char: u32 = match (
|
||||
prev.is_adjacent(current).unwrap(),
|
||||
@@ -68,8 +74,8 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
};
|
||||
mvwaddstr(
|
||||
game_win,
|
||||
snake_l,
|
||||
snake_c,
|
||||
snake_l as i32,
|
||||
snake_c as i32,
|
||||
&format!("{}", std::char::from_u32(snake_char).unwrap_or('o')),
|
||||
);
|
||||
prev = current;
|
||||
@@ -78,8 +84,8 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
|
||||
mvwaddstr(
|
||||
game_win,
|
||||
current.posyx().0,
|
||||
current.posyx().1,
|
||||
current.posy() as i32,
|
||||
current.posx() as i32,
|
||||
&format!(
|
||||
"{}",
|
||||
std::char::from_u32(match current.is_adjacent(prev).unwrap() {
|
||||
@@ -93,22 +99,22 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
}
|
||||
|
||||
pub fn draw_board(board: &Board, game_win: WINDOW) {
|
||||
let (food_l, food_c): (i32, i32) = board.food_posyx();
|
||||
let (food_l, food_c): (u32, u32) = board.food_posyx();
|
||||
mvwaddstr(
|
||||
game_win,
|
||||
food_l,
|
||||
food_c,
|
||||
food_l as i32,
|
||||
food_c as i32,
|
||||
&format!("{}", std::char::from_u32(0x0298).unwrap_or('F')),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn _log(snake: &Snake, board: &Board) {
|
||||
let (shl, shc): (i32, i32) = snake.posyx();
|
||||
let (bfl, bfc): (i32, i32) = board.food_posyx();
|
||||
pub fn _log(_snake: &Snake, _board: &Board) {
|
||||
let (shl, shc): (u32, u32) = _snake.posyx();
|
||||
let (stl, stc): (u32, u32) = _snake.remove().unwrap().posyx();
|
||||
mvwaddstr(stdscr(), 0, 0, &format!("snake:head: {} {} ", shl, shc));
|
||||
mvwaddstr(stdscr(), 1, 0, &format!("board:food: {} {} ", bfl, bfc));
|
||||
mvwaddstr(stdscr(), 1, 0, &format!("snake:tail: {} {} ", stl, stc));
|
||||
wmove(stdscr(), 2, 0);
|
||||
for snake_cell in snake.iter() {
|
||||
for snake_cell in _snake.iter() {
|
||||
waddstr(
|
||||
stdscr(),
|
||||
&format!(
|
||||
|
||||
+12
-9
@@ -10,21 +10,21 @@ pub fn start() {
|
||||
let (mut mlines, mut mcols): (i32, i32) = (0, 0);
|
||||
let game_win: WINDOW;
|
||||
let mut ch: i32;
|
||||
let (vmargin, hmargin): (i32, i32) = (5, 10);
|
||||
let (vmargin, hmargin): (u32, u32) = (5, 10);
|
||||
getmaxyx(stdscr(), &mut mlines, &mut mcols);
|
||||
|
||||
game_win = frontend::game_window(mlines, mcols, vmargin, hmargin);
|
||||
game_win = frontend::game_window(mlines as u32, mcols as u32, vmargin, hmargin);
|
||||
let mut snake = Snake::new(Cell::new(
|
||||
mlines / 2 - vmargin,
|
||||
mcols / 2 - hmargin,
|
||||
mlines as u32 / 2 - vmargin,
|
||||
mcols as u32 / 2 - hmargin,
|
||||
backend::CellType::Snake,
|
||||
)); //Initialise snake in the middle of the screen
|
||||
let mut board = Board::new(mlines - vmargin * 2, mcols - hmargin * 2);
|
||||
let mut board = Board::new(mlines as u32 - vmargin * 2, mcols as u32 - hmargin * 2);
|
||||
nodelay(game_win, true);
|
||||
loop {
|
||||
frontend::draw_snake(&snake, game_win); // always draw snake before board because the snake will clear the game win
|
||||
frontend::draw_board(&board, game_win);
|
||||
// frontend::_log(&snake, &board);
|
||||
frontend::_log(&snake, &board);
|
||||
if board.check_collision(&snake) {
|
||||
// Add stuff here to show the score and
|
||||
// how You lose screen
|
||||
@@ -46,9 +46,12 @@ pub fn start() {
|
||||
//112 is keycode for 'p'
|
||||
0 => (), //resume
|
||||
1 => {
|
||||
snake =
|
||||
Snake::new(Cell::new(mlines / 2, mcols / 2, backend::CellType::Snake)); //Initialise snake in the middle of the screen
|
||||
board = Board::new(mlines - vmargin * 2, mcols - hmargin * 2);
|
||||
snake = Snake::new(Cell::new(
|
||||
mlines as u32 / 2,
|
||||
mcols as u32 / 2,
|
||||
backend::CellType::Snake,
|
||||
)); //Initialise snake in the middle of the screen
|
||||
board = Board::new(mlines as u32 - vmargin * 2, mcols as u32 - hmargin * 2);
|
||||
} //restart
|
||||
2 => break, //exit
|
||||
_ => (), //other charachters just in case
|
||||
|
||||
Reference in New Issue
Block a user