el_diablo/src/player.rs

177 lines
4.1 KiB
Rust
Raw Normal View History

2024-10-20 22:12:28 +02:00
use rand::Rng;
2023-11-08 06:52:20 +01:00
use std::cmp::{max, min};
2023-12-18 16:11:19 +01:00
use crate::artifacts::Potion;
2023-12-25 13:47:15 +01:00
use crate::position::{HasPosition, Position};
2023-11-08 06:52:20 +01:00
pub struct Player {
name: String,
position: Position,
life: i16,
max_life: i16,
2023-12-03 21:20:16 +01:00
gold: usize,
2023-12-22 20:10:30 +01:00
experience: usize,
inventory: Vec<Potion>,
2023-11-08 06:52:20 +01:00
}
impl Player {
pub fn new(name: &str, max_life: i16) -> Player {
Player {
name: name.to_string(),
2023-11-27 19:21:10 +01:00
position: Position::new(0, 0, 0),
2023-11-08 06:52:20 +01:00
life: max_life,
max_life,
2023-12-03 21:20:16 +01:00
gold: 0,
2023-12-22 20:10:30 +01:00
experience: 0,
inventory: vec![],
2023-11-08 06:52:20 +01:00
}
}
pub fn get_name(&self) -> String {
2024-10-20 14:59:20 +02:00
self.name.clone()
2023-11-08 06:52:20 +01:00
}
pub fn change_life(&mut self, by: i16) {
self.life = max(0, min(self.max_life, self.life + by));
}
2023-11-26 20:14:33 +01:00
pub fn get_life(&self) -> i16 {
self.life
}
/// returns true if the player is dead (life <= 0)
2024-10-20 14:59:20 +02:00
pub fn is_dead(&self) -> bool {
self.life <= 0
}
/// returns true if the player's life is at maximum
2024-10-20 14:59:20 +02:00
pub fn is_healthy(&self) -> bool {
self.life == self.max_life
}
2023-12-05 19:33:19 +01:00
pub fn get_max_life(&self) -> i16 {
self.max_life
}
2023-12-03 21:20:16 +01:00
/// add the given amount to the players gold stash
2024-10-20 14:59:20 +02:00
pub fn retrieve_gold(&mut self, amount: usize) {
self.gold += amount
}
2023-12-03 21:20:16 +01:00
/// return the size of the players gold stash
2024-10-20 14:59:20 +02:00
pub fn get_gold(&self) -> usize {
self.gold
}
2023-12-22 20:10:30 +01:00
2024-10-20 14:59:20 +02:00
pub fn gain_experience(&mut self, amount: usize) {
self.experience += amount
}
2023-12-22 20:10:30 +01:00
2024-10-20 14:59:20 +02:00
pub fn get_experience(&self) -> usize {
self.experience
}
2024-10-20 22:12:28 +02:00
pub fn damage(&self) -> usize {
rand::thread_rng().gen_range(1..4)
}
2024-10-21 21:59:55 +02:00
pub fn add_to_inventory(&mut self, potion: &Potion) -> bool {
if self.inventory.len() < 10 {
self.inventory.push(*potion);
true
} else {
false
}
}
pub fn inventory_size(&self) -> usize {
self.inventory.len()
}
pub fn consume_inventory(&mut self) -> usize {
if self.is_healthy() {
return 0;
}
if let Some(potion) = self.inventory.pop() {
self.change_life(potion.get_health() as i16);
return potion.get_health();
}
0
}
2023-11-08 06:52:20 +01:00
}
2023-12-25 13:47:15 +01:00
impl HasPosition for Player {
fn get_position(&mut self) -> &mut Position {
&mut self.position
}
fn get_immutable_position(&self) -> &Position {
&self.position
}
}
2023-11-08 06:52:20 +01:00
#[test]
fn test_get_name() {
let p = Player {
name: "Teddy Tester".to_string(),
position: Position::new(0, 1, 1),
life: 5,
max_life: 10,
2023-12-03 21:20:16 +01:00
gold: 0,
2023-12-22 20:10:30 +01:00
experience: 0,
inventory: vec![],
2023-11-08 06:52:20 +01:00
};
assert_eq!(p.get_name(), "Teddy Tester");
}
2023-12-03 21:20:16 +01:00
#[test]
fn test_can_receive_gold() {
let mut p = Player::new("Teddy Tester", 10);
assert_eq!(p.get_gold(), 0);
p.retrieve_gold(13);
p.retrieve_gold(10);
assert_eq!(p.get_gold(), 23);
}
2023-11-08 06:52:20 +01:00
#[test]
fn test_change_life() {
let mut p = Player {
name: "Teddy Tester".to_string(),
position: Position::new(0, 1, 1),
life: 5,
max_life: 10,
2023-12-03 21:20:16 +01:00
gold: 0,
2023-12-22 20:10:30 +01:00
experience: 0,
inventory: vec![],
2023-11-08 06:52:20 +01:00
};
2023-12-07 10:12:44 +01:00
assert_eq!(p.get_life(), 5);
2023-11-08 06:52:20 +01:00
p.change_life(-2);
2023-12-07 10:12:44 +01:00
assert_eq!(p.get_life(), 3);
2023-11-08 06:52:20 +01:00
p.change_life(10);
2023-12-07 10:12:44 +01:00
assert_eq!(p.get_life(), 10);
2023-11-08 06:52:20 +01:00
p.change_life(-12);
2023-12-07 10:12:44 +01:00
assert_eq!(p.get_life(), 0);
2023-11-27 19:21:10 +01:00
}
#[test]
fn player_can_move() {
let mut p = Player::new("Teddy Tester", 10);
assert_eq!(p.get_position(), &Position::new(0, 0, 0));
p.get_position().change(1, 2);
assert_eq!(p.get_position(), &Position::new(0, 1, 2));
p.get_position().change(2, 1);
assert_eq!(p.get_position(), &Position::new(0, 3, 3));
p.get_position().set(1, 2, 3);
p.get_position().change(2, 1);
assert_eq!(p.get_position(), &Position::new(1, 4, 4));
2023-12-07 10:12:44 +01:00
assert_eq!(p.get_immutable_position(), &Position::new(1, 4, 4));
}
#[test]
fn test_max_life() {
let p = Player {
name: "Teddy Tester".to_string(),
position: Position::new(0, 1, 1),
life: 5,
max_life: 10,
gold: 0,
2023-12-22 20:10:30 +01:00
experience: 0,
inventory: vec![],
2023-12-07 10:12:44 +01:00
};
assert_eq!(p.get_max_life(), 10);
2023-11-27 19:21:10 +01:00
}