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 164 165 166 167 168 169 170 171 172 173
use self::super::Leader; /// Game's all possible states. /// /// `Widgets::update()` takes care of proper state transformation. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum GameState { /// Display the main menu. /// /// Main menu contains a Start button, a button to Display Highscores, an Exit button. /// /// Can transform into: /// /// * `ChooseDifficulty` /// * `DisplayHighscores` /// * `Exit` MainMenu, /// Display the screen where the player chooses the difficulty. /// /// The screen contains one button for each difficulty and the Back button. /// /// Can transform into: /// /// * `Playing` /// * `MainMenu` ChooseDifficulty, /// The game is currently in progress. /// /// This also contains the game's difficulty, the player's current score and whether the current fruit is a mango. /// /// Can transform into `GameOver`. Playing { /// The game difficulty, as chosen in the `ChooseDifficulty` stage. difficulty: Difficulty, /// The user's current score. score: u64, /// The current fruit index. /// /// If `None` - it's a mango, else it's an index of fruit from `util::FRUITS`. fruit: Option<usize>, }, /// The game was lost after a valiant battle. /// /// Contains the game's difficulty, the player's final score and the Back button. /// /// In this stage the player enters its name. /// /// Can transform into: /// /// * `GameEnded` /// * `MainMenu` GameOver { /// The game difficulty, as same as in the `Playing` stage. difficulty: Difficulty, /// The user's final score. score: u64, /// The user's name, mostly partial. name: String, }, /// The game cycle has ended. Semi-meta-state /// /// Contains the game's difficulty and the players final score. /// /// In this stage the player enters its name. /// /// Transforms into `MainMenu`. GameEnded { /// The user's name. name: String, /// User's final score, weighted. score: u64, }, /// Meta-state indicating that the leaderboard needs to be loaded. /// /// Needs to be handled in usercode, place the leaderboard into `DisplayLeaderboard` after loading it. /// /// Leaderboards are loaded via `Leader::load()`. /// /// Transforms into `DisplayLeaderboard` LoadLeaderboard, /// Display top 10 high scores. /// /// This screen also contains the Back button. /// /// Can transform into `MainMenu` DisplayLeaderboard(Vec<Leader>), /// Pseudo-state, signifying that the game window should be closed. /// /// Can transform into: nothing. This is the final state all others seek. Exit, } /// The game's difficulty, chosen in the `ChooseDifficulty` step. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum Difficulty { /// Easy difficulty, points are halved when sorting. Easy, /// Normal difficulty, points are untouched when sorting. Normal, /// Hard difficulty, points are doubled when sorting. Hard, } impl GameState { /// Check whether this state currently means that the game has ended. /// /// # Examples /// /// ``` /// # use poke_a_mango::ops::GameState; /// assert!(GameState::Exit.should_exit()); /// ``` pub fn should_exit(&self) -> bool { *self == GameState::Exit } /// Check whether this state requires usercode to load the leaderboard. /// /// # Examples /// /// ``` /// # use poke_a_mango::ops::GameState; /// assert!(GameState::LoadLeaderboard.should_load_leaderboard()); /// ``` pub fn should_load_leaderboard(&self) -> bool { *self == GameState::LoadLeaderboard } } impl Difficulty { /// The difficulty's numeric value, from `1` to `3`. pub fn numeric(&self) -> u32 { match *self { Difficulty::Easy => 1, Difficulty::Normal => 2, Difficulty::Hard => 3, } } /// Get the difficulty from its numeric value. pub fn from_numeric(num: u32) -> Option<Self> { match num { 1 => Some(Difficulty::Easy), 2 => Some(Difficulty::Normal), 3 => Some(Difficulty::Hard), _ => None, } } /// How to much to multiply the player's points for sorting. /// /// Points on Easy are worth half, and on Hard - twice the normal amount. /// /// # Examples /// /// ``` /// # use poke_a_mango::ops::Difficulty; /// // Normally you'd get these by playing /// let points = 20; /// let difficulty = Difficulty::Hard; /// /// let real_points = (points as f64) * difficulty.point_weight(); /// assert_eq!(real_points, 40.0); /// ``` pub fn point_weight(&self) -> f64 { match *self { Difficulty::Easy => 0.5, Difficulty::Normal => 1.0, Difficulty::Hard => 2.0, } } }