From 2a86201c3e9d30424b906c9aa089fc4dec62d83f Mon Sep 17 00:00:00 2001 From: Joachim Lusiardi Date: Thu, 21 Dec 2023 23:02:06 +0100 Subject: [PATCH] add 3 distinct outcomes for the game --- src/game.rs | 39 +++++++++++++++++++++++++++++++++++- src/level_generator.rs | 8 ++++---- src/main.rs | 45 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/game.rs b/src/game.rs index 4f7c3a9..79b45b5 100644 --- a/src/game.rs +++ b/src/game.rs @@ -3,7 +3,19 @@ use crate::level_generator::LevelGenerator; use crate::player::Player; use crate::position::Position; -pub const LEVELS: usize = 2; +pub const LEVELS: usize = 10; + +#[derive(PartialEq)] +/// represents a state of a game +pub enum GameState { + /// the game is ongoing (neither won or lost) + RUNNING, + /// the player died + LOST, + /// the player reached the Ω + WON, +} + /// the main structure to hold all information about the ongoing game pub struct Game { @@ -31,6 +43,31 @@ impl Game { g } + /// returns true if the player is dead (life <= 0) + fn player_is_dead(&self) -> bool { self.get_player().get_life() <= 0 } + /// returns true if the player is standing on the End element + fn player_reached_goal(&mut self) -> bool { + match self.next_element(0, 0) { + None => {} + Some(a) => { + match a { + StructureElement::End => { return true; } + _ => {} + } + } + }; + false + } + /// returns the state of the game (depending on player's life and position) + pub fn get_game_state(&mut self) -> GameState { + if self.player_is_dead() { + return GameState::LOST; + } + if self.player_reached_goal() { + return GameState::WON; + } + GameState::RUNNING + } pub fn get_player(&self) -> &Player { &self.player } diff --git a/src/level_generator.rs b/src/level_generator.rs index 97d37af..ddf5454 100644 --- a/src/level_generator.rs +++ b/src/level_generator.rs @@ -276,11 +276,11 @@ impl LevelGenerator { // TODO randomize enemies here match rng.gen_range(1..=100) { 1..=50 => { - println!("Orc! {} {} {}", self.level, t_x, t_y); - enemies.push(Box::new(Orc::new_with_position(Position::new(self.level, t_x, t_y)))); } + enemies.push(Box::new(Orc::new_with_position(Position::new(self.level, t_x, t_y)))); + } _ => { - println!("Rat! {} {} {}", self.level, t_x, t_y); - enemies.push(Box::new(Rat::new_with_position(Position::new(self.level, t_x, t_y))));} + enemies.push(Box::new(Rat::new_with_position(Position::new(self.level, t_x, t_y)))); + } }; } diff --git a/src/main.rs b/src/main.rs index 74b34dd..1c74556 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,10 +11,11 @@ use ratatui::{ widgets::Paragraph, }; use ratatui::prelude::*; -use ratatui::widgets::Block; +use ratatui::widgets::{Block, Borders, BorderType, Wrap}; +use ratatui::widgets::block::{Position, Title}; use whoami::realname; -use crate::game::Game; +use crate::game::{Game, GameState}; use crate::level_widget::LevelWidget; // use crate::level_widget::LevelWidget; use crate::player::Player; @@ -96,6 +97,46 @@ fn main() -> Result<()> { } game.player_collects_artifact(); game.update_level(); + if game.get_game_state() != GameState::RUNNING { + break; + } + } + } + } + } + loop { + let _ = terminal.draw(|frame| { + let mut area = frame.size(); + let w = area.width / 2; + let h = area.height / 2; + area.x += w - 20; + area.y += h - 10; + area.width = 40; + area.height = 20; + let block = Block::default() + .title("Game ended") + .title(Title::from("Press `q` to quit!").position(Position::Bottom)) + .borders(Borders::ALL) + .border_style(Style::default().fg(Color::White)) + .border_type(BorderType::Rounded) + .style(Style::default().bg(Color::Black)); + let paragraph = match game.get_game_state() { + GameState::RUNNING => { + Paragraph::new("Quitting is for cowards! You'll better try again!") + } + GameState::LOST => { + Paragraph::new("Sorry, you died in the dungeon. Better luck next time!") + } + GameState::WON => { + Paragraph::new("Congratulation! You mastered your way through the dungeon and won the game.") + } + }.block(block).wrap(Wrap { trim: true }); + frame.render_widget(paragraph, area); + }); + if event::poll(std::time::Duration::from_millis(16))? { + if let event::Event::Key(key) = event::read()? { + if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { + break; } } }