konnektoren_core/game/
game.rs1use super::GamePath;
2use crate::Xp;
3use crate::challenges::{
4 Challenge, ChallengeConfig, ChallengeFactory, ChallengeHistory, Performance,
5};
6use crate::game::error::{GameError, Result};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub struct Game {
11 pub game_paths: Vec<GamePath>,
12 pub challenge_factory: ChallengeFactory,
13 pub challenge_history: ChallengeHistory,
14 pub xp: Xp,
15}
16
17impl Default for Game {
18 fn default() -> Self {
19 let game_path = GamePath::default();
20 Game {
21 game_paths: vec![game_path],
22 challenge_factory: ChallengeFactory::default(),
23 challenge_history: Default::default(),
24 xp: Default::default(),
25 }
26 }
27}
28
29impl Game {
30 pub fn find_game_path_index(&self, challenge_id: &str) -> Option<usize> {
31 self.game_paths.iter().position(|game_path| {
32 game_path
33 .challenge_ids()
34 .contains(&challenge_id.to_string())
35 })
36 }
37
38 pub fn create_challenge(&self, challenge_config_id: &str) -> Result<Challenge> {
39 let challenge_config = self
40 .get_challenge_config(challenge_config_id)
41 .ok_or_else(|| GameError::ChallengeNotFound(challenge_config_id.to_string()))?;
42
43 self.challenge_factory
44 .create_challenge(&challenge_config)
45 .map_err(GameError::ChallengeError)
46 }
47
48 pub fn get_challenge_config(&self, challenge_config_id: &str) -> Option<ChallengeConfig> {
49 self.game_paths
50 .iter()
51 .map(|game_path| game_path.get_challenge_config(challenge_config_id))
52 .find(|challenge_config| challenge_config.is_some())
53 .flatten()
54 .cloned()
55 }
56
57 pub fn calculate_xp_reward(&self, challenge: &Challenge) -> Xp {
58 challenge.performance(&challenge.challenge_result)
59 * challenge.stars(&challenge.challenge_result)
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn create_challenge() {
69 let game = Game::default();
70 let challenge = game.create_challenge("unknown");
71 assert!(challenge.is_err());
72 assert_eq!(game.game_paths[0].challenge_ids().len(), 8);
73 assert_eq!(
74 game.game_paths[0].challenge_ids(),
75 vec![
76 "konnektoren-1",
77 "konnektoren-2",
78 "konnektoren-3",
79 "konnektoren-4",
80 "konnektoren-5",
81 "articles-1",
82 "past-tense-1",
83 "sentence-structure-1"
84 ]
85 );
86 let challenge = game.create_challenge("konnektoren-1");
87 assert!(challenge.is_ok());
88 }
89
90 #[test]
91 fn calculate_xp_reward() {
92 let game = Game::default();
93 let challenge = game.create_challenge("konnektoren-1").unwrap();
94 let xp = game.calculate_xp_reward(&challenge);
95 assert_eq!(xp, 0);
96 }
97
98 #[test]
99 fn get_challenge_config() {
100 let game = Game::default();
101 let challenge_config = game.get_challenge_config("konnektoren-1");
102 assert!(challenge_config.is_some());
103 }
104
105 #[test]
106 fn find_game_path_index() {
107 let game = Game::default();
108 let index = game.find_game_path_index("konnektoren-1");
109 assert_eq!(index, Some(0));
110 }
111}