minicrossterm/examples/program_examples/snake/src/main.rs

141 lines
3.7 KiB
Rust
Raw Normal View History

2018-08-20 07:13:21 +10:00
extern crate crossterm;
extern crate rand;
mod map;
mod snake;
mod variables;
mod messages;
use self::crossterm::input::input;
use self::crossterm::terminal::{terminal, ClearType};
use self::crossterm::style::Color;
use self::crossterm::{Screen, Crossterm};
use map::Map;
use variables::{Size, Direction, Position};
use snake::Snake;
use std::collections::HashMap;
use std::{thread, time};
use std::iter::Iterator;
use std::io::Read;
use std::io::Write;
fn main() {
let map_size = title_screen();
{
let mut screen = Screen::new(true);
let crossterm = Crossterm::new(&screen);
let cursor = crossterm.cursor();
let mut input = crossterm.input();
cursor.hide();
let mut stdin = input.read_async().bytes();
let mut free_positions: HashMap<String, Position> = HashMap::with_capacity((map_size.width * map_size.height) as usize);
let mut map = Map::new(map_size.clone());
map.render_map(&screen, &mut free_positions);
let mut direction = Direction::Right;
let mut snake = Snake::new(map_size.clone());
for part in snake.get_parts().iter() {
free_positions.remove_entry(format!("{},{}", part.position.x, part.position.y).as_str());
}
map.spawn_food(&free_positions, &screen);
loop {
2018-08-25 02:49:25 +10:00
thread::sleep(time::Duration::from_millis(200));
2018-08-20 07:13:21 +10:00
let pressed_key = stdin.next();
if let Some(Ok(key)) = pressed_key {
match key as char {
'w' => direction = Direction::Up,
'a' => direction = Direction::Left,
's' => direction = Direction::Down,
'd' => direction = Direction::Right,
_ => {}
}
}
snake.move_snake(&direction, &screen, &mut free_positions);
if map.is_out_of_bounds(snake.snake_parts[0].position)
{
break;
}
snake.draw_snake(&screen);
if snake.has_eaten_food(map.foot_pos)
{
map.spawn_food(&free_positions, &screen);
}
}
2018-08-24 02:15:18 +10:00
drop(screen);
2018-08-20 07:13:21 +10:00
}
2018-08-24 02:15:18 +10:00
2018-08-20 07:13:21 +10:00
game_over_screen();
}
fn title_screen() -> Size
{
let crossterm = Crossterm::new(&Screen::default());
let cursor = crossterm.cursor();
let terminal = crossterm.terminal().clear(ClearType::All);
println!("{}",messages::SNAKERS.join("\n\r"));
cursor.goto(0, 15);
println!("Enter map width:");
cursor.goto(17, 15);
let width = crossterm.input().read_line().unwrap();
2018-08-25 02:49:25 +10:00
cursor.goto(0, 16);
2018-08-25 02:32:48 +10:00
println!("Enter map height:");
2018-08-20 07:13:21 +10:00
cursor.goto(17, 16);
let height = crossterm.input().read_line().unwrap();
let parsed_width = width.parse::<usize>().unwrap();
let parsed_height = height.parse::<usize>().unwrap();
let terminal = crossterm.terminal().clear(ClearType::All);
return Size::new(parsed_width, parsed_height);
}
fn print_game_stats(map_size: Size, snake_lenght: usize, food_aten: usize, screen: &mut Screen)
{
let crossterm = Crossterm::new(&Screen::default());
let cursor = crossterm.cursor();
let terminal = crossterm.terminal().clear(ClearType::All);
screen.write(format!("Snake Lenght: {}\n\r", snake_lenght).as_ref());
screen.write(format!("Food aten: {}\n\r", snake_lenght).as_ref());
cursor.goto(0,map_size.height as u16);
cursor.goto(0,map_size.height as u16);
}
fn game_over_screen()
{
let crossterm = Crossterm::new(&Screen::default());
let cursor = crossterm.cursor();
let terminal = crossterm.terminal();
terminal.clear(ClearType::All);
println!("{}",messages::END_MESSAGE.join("\n\r"));
// cursor.goto()
cursor.show();
}