1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//! This module contains the [`Charmander`] type, as well as its method implementations.
//!
//! The [`Charmander`] struct will model the pokemon of the same name.
//! We want to design the struct in such a way that we can easily create a [`Charmander`] and
//! modify its attributes like health, level, and name.
//!
//! [`Charmander`] should have the following attributes:
//!  - `name: String`
//!  - `level: usize`
//!  - `health: usize`
//!  - `attack: usize`
//!  - `defense: usize`
//!
//! All of these fields should be _private_ (not accessible outside of the struct).
//!
//! ---
//!
//! Once you've added the fields to the struct, implement the following methods:
//! - [`new`](Charmander::new): This method will take in a name and create a new [`Charmander`]
//! struct with the following default values:
//!     - `level: 0`
//!     - `health: 100`
//!     - `attack: 42`
//!     - `defense: 33`
//! - [`level_up`](Charmander::level_up): This method will increase the level of the
//! [`Charmander`] struct by the input `levels`.
//! - [`get_health`](Charmander::get_health): This method will return the health value of the
//! [`Charmander`] struct.
//! - [`get_attack`](Charmander::get_attack): This method will return the attack value of the
//! [`Charmander`] struct.
//! - [`get_defense`](Charmander::get_defense): This method will return the defense value of the
//! [`Charmander`] struct.
//!
//! For some of these methods, you may have to do some extra work to determine the value to return.
//! **Make sure to read the specification in either the comments in the code or on this writeup!**
//!
//! ---
//!
//! We also want [`Charmander`]s to battle with each other.
//! We'll implement the following methods
//! [`attack`](Charmander::attack) and [`fight`](Charmander::fight).
//! Click on these hyperlinks or read the doc comments to see the specification for these methods!
//!
//! _Note that this pokemon is **completely** different from the_
//! _[`Eevee`](crate::pokemon::eevee::Eevee)_
//! _pokemon that you will implement in the next part, so make sure not to mix them up!_
pub struct Charmander {
    _placeholder: ()
}

/// Implement the Charmander struct here.
impl Charmander {
    /// Takes in a `name` as a `String` and creates a new [`Charmander`]
    /// struct with the following default values:
    /// - `level: 0`
    /// - `health: 100`
    /// - `attack: 42`
    /// - `defense: 33`
    ///
    /// _Note: We 0-level because we're programmers_ 😎
    pub fn new(name: String) -> Self {
        todo!()
    }

    /// Increases the level of the [`Charmander`] by the input `levels`.
    pub fn level_up(&mut self, levels: usize) {
        todo!()
    }

    /// Return the health value of the [`Charmander`].
    ///
    /// The health value is calculated by the following formula: `(health + (5 * level))`.
    pub fn get_health(&self) -> usize {
        todo!()
    }

    /// Returns the attack value of the [`Charmander`].
    ///
    /// The attack value is calculated by the following formula: `(attack + (3 * level))`.
    pub fn get_attack(&self) -> usize {
        todo!()
    }
    /// Returns the defense value of the [`Charmander`].
    ///
    /// The defense value is calculated by the following formula: `(defense + (4 * level))`.
    pub fn get_defense(&self) -> usize {
        todo!()
    }

    /// Takes `damage` subtracted by [`Charmander`]'s `defense`.
    ///
    /// If the [`Charmander`] takes more damage than it has health,
    /// this function should panic with the message
    /// `"{name} fainted!"`, where `"{name}"` is the name of the [`Charmander`].
    /// In other words, we should panic if the [`Charmander`] hits 0 health.
    ///
    /// ```
    /// # use pokelab::pokemon::charmander::*;
    /// #
    /// let mut charmander = Charmander::new(String::from("Ben"));
    /// assert_eq!(charmander.get_health(), 100);
    /// assert_eq!(charmander.get_defense(), 33);
    ///
    /// charmander.take_damage(30);
    /// assert_eq!(charmander.get_health(), 100); // Not enough damage to overcome defense
    ///
    /// charmander.take_damage(66);
    /// assert_eq!(charmander.get_health(), 67); // 33 actual damage taken
    /// ```
    pub fn take_damage(&mut self, damage: usize) {
        todo!()
    }

    /// Attacks another [`Charmander`] struct and deals damage.
    ///
    /// [`attack`](Charmander::attack) will do damage to the `other` [`Charmander`]
    /// equal to its current attack. Will panic if the other [`Charmander`] faints.
    ///
    /// ```
    /// # use pokelab::pokemon::charmander::*;
    /// #
    /// let mut attacker = Charmander::new(String::from("David"));
    /// let mut defender = Charmander::new(String::from("Connor"));
    /// assert_eq!(attacker.get_attack(), 42);
    /// assert_eq!(defender.get_defense(), 33);
    ///
    /// attacker.attack(&mut defender);
    /// assert_eq!(defender.get_health(), 91); // 9 damage
    ///
    /// attacker.level_up(1);
    /// attacker.attack(&mut defender);
    /// assert_eq!(defender.get_health(), 79); // 12 damage
    /// ```
    pub fn attack(&self, other: &mut Self) {
        todo!()
    }

    /// Pits two [`Charmander`]s against each other!
    ///
    /// Note that this is an associated function, so you cannot write `charmander.fight(other)`.
    ///
    /// The [`Charmander`] with the higher level will go first.
    /// Will panic if a [`Charmander`] faints.
    ///
    /// ```
    /// # use pokelab::pokemon::charmander::*;
    /// #
    /// let mut charmander1 = Charmander::new(String::from("Ben"));
    /// let mut charmander2 = Charmander::new(String::from("Connor"));
    ///
    /// charmander1.level_up(5);
    /// assert_eq!(charmander1.get_health(), 125); // +25
    /// assert_eq!(charmander1.get_attack(), 57);  // +15
    /// assert_eq!(charmander1.get_defense(), 53); // +20
    ///
    /// Charmander::fight(&mut charmander1, &mut charmander2);
    /// assert_eq!(charmander1.get_health(), 125); // no damage taken
    /// assert_eq!(charmander2.get_health(), 76);  // 57 - 33 = 24 damage taken
    /// ```
    pub fn fight(charmander1: &mut Self, charmander2: &mut Self) {
        todo!()
    }
}