Files
snake-rs/src/game/backend.rs
T
Uttarayan Mondal 2cf1d355f9 Add food spawning
2021-01-06 21:54:30 +05:30

169 lines
3.7 KiB
Rust

extern crate rand;
use rand::Rng;
use std::collections::LinkedList;
pub enum Direction {
Up,
Down,
Left,
Right,
}
impl Copy for Direction {}
impl Clone for Direction {
fn clone(&self) -> Self {
*self
}
}
pub enum CellType {
Food,
Snake,
Empty,
}
pub struct Cell {
line: i32,
col: i32,
ctype: CellType,
}
impl Cell {
pub fn new(l: i32, c: i32, t: CellType) -> Cell {
Cell {
line: l,
col: c,
ctype: t,
}
}
pub fn random(lines: i32, cols: i32) -> Cell {
let mut rng = rand::thread_rng();
Cell::new(
rng.gen_range(0..lines),
rng.gen_range(0..cols),
CellType::Food,
)
}
pub fn posyx(&self) -> (i32, i32) {
return (self.line, self.col);
}
pub fn chtype(&mut self, ctype: CellType) {
self.ctype = ctype;
}
}
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
}
}
enum FailState {
Wall,
// Body,
}
enum GameState {
Failed(FailState),
Ready,
// Playing,
}
pub struct Board {
maxlines: i32,
maxcols: i32,
gamestate: GameState,
food: Cell,
}
// impl Board<'_> {
impl Board {
pub fn new(maxlines: i32, maxcols: i32) -> Board {
Board {
maxlines,
maxcols,
gamestate: GameState::Ready,
food: Cell::random(maxlines, maxcols),
}
}
pub fn check_collision(&mut self, snake: &Snake) -> bool {
let (snake_line, snake_col): (i32, i32) = snake.posyx();
if (snake_line >= self.maxlines)
|| (snake_col >= self.maxcols)
|| (snake_line <= 0)
|| (snake_col <= 0)
{
self.gamestate = GameState::Failed(FailState::Wall);
return true;
}
return false;
}
pub fn check_food(&self, snake: &Snake) -> bool {
if self.food_posyx() == snake.posyx() {
return true;
} else {
return false;
}
}
pub fn food_posyx(&self) -> (i32, i32) {
return self.food.posyx();
}
pub fn eat_food(&mut self, snake: &mut Snake) {
snake.grow();
self.food.chtype(CellType::Empty);
}
pub fn spawn_food() {}
}
pub struct Snake {
head: Cell,
pub body: LinkedList<Cell>,
// length: i32,
pub direction: Direction,
grow: bool,
}
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,
grow: false,
}
}
pub fn posyx(&self) -> (i32, i32) {
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;
if self.grow {
tail = self.body.back().unwrap().clone();
} else {
tail = 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),
};
self.direction = direction;
self.head = Cell::new(self.head.line + dl, self.head.col + dc, CellType::Snake);
self.body.push_front(self.head);
}
pub fn tick(&mut self) {
self.smove(self.direction);
}
pub fn grow(&mut self) {
self.grow = true;
}
}