pub mod stats; use std::io; use io::BufRead; pub use stats::*; use crate::inventory::Inventory; pub const MAX_LEVEL: u8 = 10; fn swap_stats_according_to_string(stats: &mut Stats, string: String) { let string = string.trim(); let parts: Vec<&str> = string.split_whitespace().collect(); if parts.len() == 2 && stats.swap(parts[0], parts[1]) { println!("{} and {} values have been switched.", parts[0], parts[1]); } else { println!("Not switching any stats."); } } pub fn cli_interactively_create_character() -> Character { println!("Starting character creation."); println!("Rolling initial stats..."); let mut stats = Stats::roll_initial(); println!("Initial stats: {}", stats); println!( "Would you like to swap two stats' values? If so, write the names of them seperated by a \ whitespace and press enter, if not just press enter." ); let mut buf = String::new(); { let stdin = io::stdin(); let mut lock = stdin.lock(); lock.read_line(&mut buf) .expect("Unable to read from console"); } swap_stats_according_to_string(&mut stats, buf); unimplemented!() } #[derive(Clone, Debug)] pub struct Character { health: u8, max_health: u8, stats: Stats, /// Free text describing the special trait of the character special_traits: Vec, /// Total value of experience. The level can be calculated through it experience: u32, wealth: u32, inventory: Inventory, goals: Vec, } impl Character { pub fn new( health: u8, max_health: u8, stats: Stats, special_traits: Vec, experience: u32, wealth: u32, inventory: Inventory, goals: Vec, ) -> Self { Self { health, max_health, stats, special_traits, experience, wealth, inventory, goals, } } pub fn stats(&self) -> &Stats { &self.stats } pub fn stats_mut(&mut self) -> &mut Stats { &mut self.stats } pub fn special_traits(&self) -> &Vec { &self.special_traits } pub fn experience(&self) -> u32 { self.experience } pub fn wealth(&self) -> u32 { self.wealth } pub fn level(&self) -> u8 { /* Start iteration at first level */ let mut level_counter = 1; let mut xp_remaining = self.experience; let mut xp_required_for_levelup = 200; while level_counter < MAX_LEVEL && xp_remaining >= xp_required_for_levelup { level_counter += 1; xp_remaining -= xp_required_for_levelup; xp_required_for_levelup += 100; } level_counter } } #[cfg(test)] mod tests { use super::*; const DEFAULT_STATS: Stats = Stats::from_values([10; NUM_STATS]); #[test] fn create_character() { let character = Character::new( 10, 10, DEFAULT_STATS.clone(), Vec::new(), 1, 2, Inventory::new(), Vec::new(), ); assert_eq!(character.stats(), &DEFAULT_STATS); assert_eq!(character.special_traits(), &Vec::::new()); assert_eq!(character.experience(), 1); assert_eq!(character.wealth, 2); } #[test] fn min_level_calculation() { let character = Character::new( 10, 10, DEFAULT_STATS.clone(), Vec::new(), 199, 0, Inventory::new(), Vec::new(), ); assert_eq!(character.level(), 1); } #[test] fn mid_level_calculation() { let character = Character::new( 10, 10, DEFAULT_STATS.clone(), Vec::new(), 900, 0, Inventory::new(), Vec::new(), ); assert_eq!(character.level(), 4); } #[test] fn max_level_calculation() { let character = Character::new( 10, 10, DEFAULT_STATS.clone(), Vec::new(), 5400, 0, Inventory::new(), Vec::new(), ); assert_eq!(character.level(), 10); let character = Character::new( 10, 10, DEFAULT_STATS.clone(), Vec::new(), 6500, 0, Inventory::new(), Vec::new(), ); assert_eq!(character.level(), 10); } }