input improvemnts
This commit is contained in:
parent
fffd504a3c
commit
504c882787
91
src/main.rs
91
src/main.rs
|
|
@ -3,7 +3,7 @@ use std::io::stdout;
|
||||||
use std::sync::mpsc::{self, Receiver};
|
use std::sync::mpsc::{self, Receiver};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crossterm::cursor::MoveTo;
|
use crossterm::cursor::{self, MoveTo};
|
||||||
use crossterm::event::{read, Event, KeyCode};
|
use crossterm::event::{read, Event, KeyCode};
|
||||||
use crossterm::execute;
|
use crossterm::execute;
|
||||||
use crossterm::style::{Print, Stylize};
|
use crossterm::style::{Print, Stylize};
|
||||||
|
|
@ -17,23 +17,39 @@ use rand::random;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let g = Game::new();
|
let g = Game::new();
|
||||||
execute!(stdout(), EnterAlternateScreen);
|
execute!(stdout(), EnterAlternateScreen, cursor::Hide);
|
||||||
enable_raw_mode();
|
enable_raw_mode();
|
||||||
|
|
||||||
g.render_board();
|
g.render_board();
|
||||||
let game = game_loop(
|
let game = game_loop(
|
||||||
g,
|
g,
|
||||||
2,
|
4,
|
||||||
2.0,
|
0.16,
|
||||||
|g| {
|
|g| {
|
||||||
|
let mut inputQueue = Vec::<Direction>::new();
|
||||||
while let Ok(input) = g.game.input.try_recv() {
|
while let Ok(input) = g.game.input.try_recv() {
|
||||||
if let Ok(direction) = input.try_into() {
|
if let Ok(direction) = Direction::try_from(input) {
|
||||||
g.game.direction = direction;
|
inputQueue.push(direction.clone());
|
||||||
|
match direction {
|
||||||
|
Direction::Up if !matches!(g.game.direction, Direction::Down) => {
|
||||||
|
g.game.direction = direction
|
||||||
|
}
|
||||||
|
Direction::Down if !matches!(g.game.direction, Direction::Up) => {
|
||||||
|
g.game.direction = direction
|
||||||
|
}
|
||||||
|
Direction::Right if !matches!(g.game.direction, Direction::Left) => {
|
||||||
|
g.game.direction = direction
|
||||||
|
}
|
||||||
|
Direction::Left if !matches!(g.game.direction, Direction::Right) => {
|
||||||
|
g.game.direction = direction
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
g.exit();
|
g.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Err(gg) = g.game.update() {
|
let update_step = g.game.get_step(&mut inputQueue);
|
||||||
|
if let Err(gg) = g.game.update(update_step) {
|
||||||
g.exit();
|
g.exit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -42,7 +58,7 @@ fn main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
disable_raw_mode();
|
disable_raw_mode();
|
||||||
execute!(stdout(), LeaveAlternateScreen);
|
execute!(stdout(), LeaveAlternateScreen, cursor::Show);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -69,6 +85,15 @@ enum Input {
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Step {
|
||||||
|
Turn(Direction),
|
||||||
|
MoveAndTurn {
|
||||||
|
step_direction: Direction,
|
||||||
|
new_direction: Direction,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum GameOverState {
|
enum GameOverState {
|
||||||
SnakeBite,
|
SnakeBite,
|
||||||
|
|
@ -94,6 +119,18 @@ impl TryFrom<Input> for Direction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
fn valid_direction(cur_direction: &Direction, new_direction: &Direction) -> bool {
|
||||||
|
match new_direction {
|
||||||
|
Direction::Up if matches!(cur_direction, Direction::Down) => false,
|
||||||
|
Direction::Down if matches!(cur_direction, Direction::Up) => false,
|
||||||
|
Direction::Right if matches!(cur_direction, Direction::Left) => false,
|
||||||
|
Direction::Left if matches!(cur_direction, Direction::Right) => false,
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Game {
|
struct Game {
|
||||||
apple_pos: (usize, usize),
|
apple_pos: (usize, usize),
|
||||||
|
|
@ -156,7 +193,22 @@ impl Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self) -> Result<(), GameOverState> {
|
fn get_step(&self, input: &Vec<Direction>) -> Step {
|
||||||
|
match input.len() {
|
||||||
|
1 if Direction::valid_direction(&self.direction, &input[0]) => Step::Turn(input[0]),
|
||||||
|
2.. if Direction::valid_direction(&self.direction, &input[input.len() - 2])
|
||||||
|
&& Direction::valid_direction(&input[input.len() - 2], &input[input.len() - 1]) =>
|
||||||
|
{
|
||||||
|
Step::MoveAndTurn {
|
||||||
|
step_direction: input[input.len() - 2],
|
||||||
|
new_direction: input[input.len() - 1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Step::Turn(self.direction),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn advance(&mut self) -> Result<(), GameOverState> {
|
||||||
let next_pos = self.next_pos()?;
|
let next_pos = self.next_pos()?;
|
||||||
|
|
||||||
match self.check_pos(next_pos)? {
|
match self.check_pos(next_pos)? {
|
||||||
|
|
@ -174,6 +226,25 @@ impl Game {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, step: Step) -> Result<(), GameOverState> {
|
||||||
|
match step {
|
||||||
|
Step::Turn(direction) => {
|
||||||
|
self.direction = direction;
|
||||||
|
self.advance()?;
|
||||||
|
}
|
||||||
|
Step::MoveAndTurn {
|
||||||
|
step_direction,
|
||||||
|
new_direction,
|
||||||
|
} => {
|
||||||
|
self.direction = step_direction;
|
||||||
|
self.advance()?;
|
||||||
|
self.direction = new_direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(250));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn gen_apple(max_x: usize, max_y: usize) -> (usize, usize) {
|
fn gen_apple(max_x: usize, max_y: usize) -> (usize, usize) {
|
||||||
let x = random::<usize>() % max_x;
|
let x = random::<usize>() % max_x;
|
||||||
let y = random::<usize>() % max_y;
|
let y = random::<usize>() % max_y;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue