From d84906ec92e45ed2cf2611c2f646d72ef5f1bb64 Mon Sep 17 00:00:00 2001
From: Iago Garrido <iago086@gmail.com>
Date: Tue, 12 Nov 2019 14:28:58 +0100
Subject: add state

---
 src/character.rs | 19 +++++++-----
 src/main.rs      | 91 +++++++++++++++-----------------------------------------
 src/state.rs     | 48 ++++++++++++++++++++++++++++++
 src/world.rs     | 48 ++++++++++++++++++++++++++++--
 4 files changed, 130 insertions(+), 76 deletions(-)
 create mode 100644 src/state.rs

(limited to 'src')

diff --git a/src/character.rs b/src/character.rs
index 3e6c4a7..ded4fa4 100644
--- a/src/character.rs
+++ b/src/character.rs
@@ -11,6 +11,7 @@ pub struct Character {
     dodge: i32,
     luck: i32,
     xp: i32,
+    gold: i32,
     location: Point
 }
 
@@ -22,7 +23,6 @@ pub trait Player {
         attack: i32,
         dodge: i32,
         luck: i32,
-        location: Point
     ) -> Character;
 
     fn place(&mut self, location: Point);
@@ -42,6 +42,8 @@ pub trait Player {
     fn stats(&self) -> String;
 
     fn walk(&mut self, dir: Direction);
+
+    fn get_gold(&self) -> i32;
 }
 
 pub enum Direction {
@@ -59,7 +61,6 @@ impl Player for Character {
         attack: i32,
         dodge: i32,
         luck: i32,
-        location: Point
     ) -> Character {
         Character {
             name: name,
@@ -70,7 +71,8 @@ impl Player for Character {
             dodge: dodge,
             luck: luck,
             xp: 0,
-            location: location
+            gold: 0,
+            location: (0, 0),
         }
     }
 
@@ -86,7 +88,6 @@ impl Player for Character {
             self.attack,
             self.dodge,
             self.luck + player_luck,
-            (0,0)
         )
     }
 
@@ -128,10 +129,14 @@ impl Player for Character {
 
     fn stats(&self) -> String {
         format!(
-            "{} - hp: {} attack: {} dodge: {} luck: {} experience: {}",
-            self.class, self.health, self.attack, self.dodge, self.luck, self.xp
+            "{} - hp: {}/{} attack: {} dodge: {} luck: {} experience: {} gold: {}",
+            self.class, self.health, self.max_health, self.attack, self.dodge, self.luck, self.xp, self.gold
         )
     }
+
+    fn get_gold(&self) -> i32 {
+        self.gold
+    }
 }
 
 #[cfg(test)]
@@ -139,7 +144,7 @@ mod tests {
     use super::*;
 
     fn test_attack() {
-        let player = Character::new("".to_string(), "Rogue".to_string(), 1, 4, 1, 4, (0,0));
+        let player = Character::new("".to_string(), "Rogue".to_string(), 1, 4, 1, 4);
 
         assert_eq!(player.attack(), 6);
     }
diff --git a/src/main.rs b/src/main.rs
index 06fcd0f..8662438 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,86 +6,41 @@ extern crate text_io;
 
 mod character;
 mod computer;
+mod state;
 mod world;
 
-use std::env;
 use character::Player;
 use character::Character;
-use computer::Enemy;
-use pancurses::{Window, initscr, endwin, Input, noecho};
-use world::{Dungeon, Level, Generable, TileType};
-
-fn tile_to_str(tile: &TileType) -> &str {
-    match tile {
-        TileType::Floor => ".",
-        TileType::Wall => "#",
-        TileType::Empty => " ",
-        TileType::StairsDown => ">",
-        TileType::StairsUp => "<",
-        TileType::Character => "@",
-        _ => "?"
-    }
-}
-
-fn draw_block(window: &Window, block: &TileType) {
-    window.printw(tile_to_str(block));
-}
-
-fn render_level(window: &Window, level: &Level) {
-    let grid = level.to_tilegrid().unwrap();
-
-    for (linenum, line) in grid.raw_data().iter().enumerate() {
-        for block in line.iter() {
-            draw_block(&window, block);
-        }
-        window.mv(linenum as i32, 0);
-    }
-}
-
-fn debug_level(level: Level) {
-    let grid = level.to_tilegrid().unwrap();
-
-    for line in grid.raw_data().iter() {
-        for block in line.iter() {
-            print!("{}", tile_to_str(block));
-        }
-        print!("\n");
-    }
-}
+use pancurses::{
+    initscr,
+    endwin,
+    Input
+};
+use state::State;
+use world::Dungeon;
 
 
 fn main() {
-    let mut level = 0;
-    let mut dungeon = Dungeon::new(80, 24, 5);
-    dungeon.generate();
-
-    let start_location = dungeon.levels[0].get_start_point();
-
-    let mut character: Character = Character::new(
-        "Kshar".to_string(),
-        "Warror".to_string(),
-        30,
-        10,
-        10,
-        20,
-        start_location
+    let mut state = State::new(
+        Character::new(
+            "Kshar".to_string(),
+            "Warror".to_string(),
+            30,
+            10,
+            10,
+            20,
+        ),
+        Dungeon::new(80, 24, 5),
     );
-    character.place(start_location);
+
+    state.init();
 
     // Dump the whole dungeon structure in terminal for debugging
-    match env::var("DEBUG") {
-        Ok(_) => {
-            for l in dungeon.levels {
-                debug_level(l);
-            }
-            return
-        },
-        Err(_) => ()
-    };
+    state.debug();
 
     let window = initscr();
 
-    render_level(&window, &dungeon.levels[0]);
+    state.render_level(&window);
 
     loop {
         // update actors
@@ -106,4 +61,6 @@ fn main() {
         }
     }
     endwin();
+
+    println!("You quit with {} gold pieces", state.character.get_gold())
 }
diff --git a/src/state.rs b/src/state.rs
new file mode 100644
index 0000000..3e8516b
--- /dev/null
+++ b/src/state.rs
@@ -0,0 +1,48 @@
+use pancurses::Window;
+use std::env;
+
+use crate::character::Character;
+use crate::character::Player;
+use crate::computer::Enemy;
+use crate::world::{Dungeon, Generable, Level};
+
+pub struct State {
+    pub character: Character,
+    pub dungeon: Dungeon,
+    pub level: usize,
+}
+
+impl State {
+    pub fn new(
+        character: Character,
+        dungeon: Dungeon,
+    ) -> State {
+        State {
+            character: character,
+            dungeon: dungeon,
+            level: 0,
+        }
+    }
+
+    pub fn init(&mut self) {
+        self.dungeon.generate();
+        self.character.place(self.current_level().get_start_point());
+    }
+
+    pub fn debug(&self) {
+        match env::var("DEBUG") {
+            Ok(_) => {
+                self.dungeon.debug_levels();
+            },
+            Err(_) => ()
+        };
+    }
+
+    pub fn render_level(&self, window: &Window) {
+        self.current_level().render(window);
+    }
+
+    fn current_level(&self) -> &Level {
+        &self.dungeon.levels[self.level]
+    }
+}
\ No newline at end of file
diff --git a/src/world.rs b/src/world.rs
index 24a4c31..4f2a645 100644
--- a/src/world.rs
+++ b/src/world.rs
@@ -1,9 +1,10 @@
 use rand::Rng;
+use pancurses::{Window};
 
 pub type Point = (usize, usize);
 
 #[derive(Clone)]
-pub enum TileType {
+enum TileType {
     Empty,
     Wall,
     Floor,
@@ -226,6 +227,38 @@ impl Dungeon {
             levels: vec![]
         }
     }
+
+    pub fn debug_levels(&self) {
+        for l in &self.levels {
+            Dungeon::debug_level(l);
+        }
+    }
+
+    fn draw_block(window: &Window, block: &TileType) {
+        window.printw(Dungeon::tile_to_str(block));
+    }
+
+    fn debug_level(level: &Level) {
+        let grid = level.to_tilegrid().unwrap();
+
+        for line in grid.raw_data().iter() {
+            for block in line.iter() {
+                print!("{}", Dungeon::tile_to_str(block));
+            }
+            print!("\n");
+        }
+    }
+
+    fn tile_to_str(tile: &TileType) -> &str {
+        match tile {
+            TileType::Floor => ".",
+            TileType::Wall => "#",
+            TileType::Empty => " ",
+            TileType::StairsDown => ">",
+            TileType::StairsUp => "<",
+            TileType::Character => "@",
+        }
+    }
 }
 
 impl Generable for Dungeon {
@@ -251,7 +284,7 @@ impl Level {
         }
     }
 
-    pub fn to_tilegrid(&self) -> Result<TileGrid, String> {
+    fn to_tilegrid(&self) -> Result<TileGrid, String> {
         let mut grid = TileGrid::new(self.xsize, self.ysize);
 
         for room in &self.rooms {
@@ -272,6 +305,17 @@ impl Level {
         return (0,0)
     }
 
+    pub fn render(&self, window: &Window) {
+        let grid = self.to_tilegrid().unwrap();
+
+        for (linenum, line) in grid.raw_data().iter().enumerate() {
+            for block in line.iter() {
+                Dungeon::draw_block(&window, &block);
+            }
+            window.mv(linenum as i32, 0);
+        }
+    }
+
     fn overlaps(&self, start: Point, width: usize, height: usize, padding: usize) -> bool {
         for room in &self.rooms {
             if room.start.0 < start.0 + width + padding &&
-- 
cgit v1.2.3