summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-08-04 19:12:54 +0300
committerOxore <oxore@protonmail.com>2023-08-04 19:12:54 +0300
commit7207b50aa469ab3775ed8560e9bc2bf5ad19dc07 (patch)
tree9079f66d414da3c25c2cde9aec4b05e6b0752f74
parent63e5b15ac97b4b41c43a566754c5cf7a1c3cf415 (diff)
Impl simple main menu
-rw-r--r--src/main.rs97
1 files changed, 83 insertions, 14 deletions
diff --git a/src/main.rs b/src/main.rs
index 0ebd6ae..00f4583 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,6 +2,7 @@ extern crate termios;
use nonblock::NonBlockingReader;
use rand::seq::SliceRandom;
+use std::io::Write;
const FIELD_COLS: usize = 10;
const FIELD_ROWS_VISIBLE: usize = 20;
@@ -264,20 +265,13 @@ impl Default for Bag {
}
}
-enum Parameter {
- Bool(bool),
- Int(i32),
-}
-
enum MenuAction {
Run,
Quit,
}
enum MenuContent {
- Menu(Vec<Menu>),
Action(MenuAction),
- Parameter(Parameter),
}
struct Menu {
@@ -293,6 +287,7 @@ enum GameState {
struct Game {
state: GameState,
menu: Vec<Menu>,
+ menu_selected: usize,
field: Field,
figure: Figure,
x: isize,
@@ -329,6 +324,7 @@ impl Default for Game {
Self {
state: GameState::Menu,
menu,
+ menu_selected: 0,
field: Field::default(),
figure,
x: 3,
@@ -343,6 +339,23 @@ impl Default for Game {
}
impl Game {
+ fn start_game(&mut self) {
+ self.bag = Bag::default();
+ self.figure_on_hold = Figure::from_kind(self.bag.next());
+ self.figure = Figure::from_kind(self.bag.next());
+ self.figure_next = [
+ Figure::from_kind(self.bag.next()),
+ Figure::from_kind(self.bag.next()),
+ Figure::from_kind(self.bag.next()),
+ Figure::from_kind(self.bag.next()),
+ ];
+ self.field = Field::default();
+ self.state = GameState::InGame;
+ (self.x, self.y) = (3, 17);
+ self.fall_timeout = Timeout::from_duration(std::time::Duration::from_millis(500));
+ self.place_timeout = None;
+ }
+
fn place_figure(&mut self) {
self.field.render(&self.figure, self.x, self.y);
self.figure = self.figure_next[0].clone();
@@ -387,7 +400,7 @@ impl Game {
}
}
- fn handle_input(&mut self, c: char) -> Option<StepResult> {
+ fn handle_input_ingame(&mut self, c: char) -> Option<StepResult> {
match c {
'q' => return Some(StepResult::Quit),
' ' => {
@@ -427,7 +440,7 @@ impl Game {
self.reset_fall_timeout();
self.stop_place_timeout();
}
- _ => {}
+ _ => return None,
}
self.reset_place_timeout();
Some(StepResult::StateChanged)
@@ -449,7 +462,7 @@ impl Game {
fn step_game(&mut self, c_optional: Option<char>) -> Option<StepResult> {
let handle_input_result = if let Some(c) = c_optional {
- self.handle_input(c)
+ self.handle_input_ingame(c)
} else {
None
};
@@ -473,10 +486,46 @@ impl Game {
}
}
+ fn handle_input_menu(&mut self, c: char) -> Option<StepResult> {
+ match c {
+ 'q' => return Some(StepResult::Quit),
+ 'k' => {
+ if self.menu_selected < self.menu.len() {
+ self.menu_selected += 1;
+ Some(StepResult::StateChanged)
+ } else {
+ None
+ }
+ }
+ 'i' => {
+ if self.menu_selected > 0 {
+ self.menu_selected -= 1;
+ Some(StepResult::StateChanged)
+ } else {
+ None
+ }
+ }
+ 'l' | ' ' => {
+ match &self.menu[self.menu_selected].content {
+ MenuContent::Action(action) => match action {
+ MenuAction::Run => {
+ self.start_game();
+ Some(StepResult::StateChanged)
+ },
+ MenuAction::Quit => Some(StepResult::Quit),
+ },
+ }
+ }
+ _ => None,
+ }
+ }
+
fn step_menu(&mut self, c_optional: Option<char>) -> Option<StepResult> {
- // TODO
- self.state = GameState::InGame;
- None
+ if let Some(c) = c_optional {
+ self.handle_input_menu(c)
+ } else {
+ None
+ }
}
fn step(&mut self, c_optional: Option<char>) -> Option<StepResult> {
@@ -581,7 +630,25 @@ impl Tui {
}
fn display_game_menu(&self, game: &Game) {
- // TODO
+ self.cursor_to_home();
+ for y in 0..FIELD_ROWS_VISIBLE {
+ print!(" |");
+ if y == 10 {
+ if game.menu_selected == 0 {
+ print!("\x1b[7m");
+ }
+ print!("{:^20}\x1b[0m", game.menu[0].name);
+ } else if y == 11 {
+ if game.menu_selected == 1 {
+ print!("\x1b[7m");
+ }
+ print!("{:^20}\x1b[0m", game.menu[1].name);
+ } else {
+ print!(" ");
+ }
+ print!("|");
+ print!("\r\x1b[1B");
+ }
}
fn display_game(&self, game: &Game) {
@@ -589,6 +656,7 @@ impl Tui {
GameState::Menu => self.display_game_menu(game),
GameState::InGame => self.display_game_ingame(game),
}
+ std::io::stdout().flush().unwrap();
}
fn clear_screen(&self) {
@@ -641,6 +709,7 @@ fn main() {
let tui = Tui::default();
let mut game = Game::default();
tui.display_game(&game);
+ std::thread::sleep(std::time::Duration::from_millis(1000));
let mut noblock_stdin = NonBlockingReader::from_fd(std::io::stdin()).unwrap();
'outer: while !noblock_stdin.is_eof() {
let mut buf = String::new();