dcss_api/
play.rs

1use crate::api_errors::BlockingError;
2use crate::Error;
3use crate::Webtile;
4use serde_json::json;
5
6impl Webtile {
7    /// Start an unseeded game by selecting the game_id and the character's
8    /// specifications.
9    ///
10    /// # Arguments
11    ///
12    /// * `game_id` - A string slice of the game's ID.
13    /// * `species` - A string slice for the character's species.
14    /// * `background` - A string slice for the character's background.
15    /// * `weapon` - A string slice for the character's weapon.
16    ///
17    /// # Example
18    ///
19    /// ```no_run
20    /// // Start a game on "dcss-web-trunk", for a Minotaur (b), Berserker (i), with a mace (c)
21    /// webtile.start_game("dcss-web-trunk", "b", "i", "c")?;
22    /// ```
23    pub fn start_game(
24        &mut self,
25        game_id: &str,
26        species: &str,
27        background: &str,
28        weapon: &str,
29    ) -> Result<(), Error> {
30        self.start_game_seeded(game_id, "0", false, species, background, weapon)
31    }
32
33    /// Continue a saved game by selecting it's game ID.
34    ///
35    /// # Arguments
36    ///
37    /// * `game_id` - A string slice of the game's ID.
38    ///
39    /// # Example
40    ///
41    /// ```no_run
42    /// // Continue a game on "dcss-web-trunk"
43    /// webtile.continue_game("dcss-web-trunk")?;
44    /// ```
45    pub fn continue_game(&mut self, game_id: &str) -> Result<(), Error> {
46        self.start_game_seeded(game_id, "", false, "", "", "")
47    }
48
49    /// Start an seeded game by selecting the game_id, the seed and the character's
50    /// specifications.
51    ///
52    /// # Arguments
53    ///
54    /// * `game_id` - A string slice of the game's ID.
55    /// * `seed` - A string slice of the game's seed.
56    /// * `pregenerate` - A bool on if the pregeneration option should be selected.
57    /// * `species` - A string slice for the character's species.
58    /// * `background` - A string slice for the character's background.
59    /// * `weapon` - A string slice for the character's weapon.
60    ///
61    /// # Example
62    ///
63    /// ```no_run
64    /// // Start a game on "dcss-web-trunk", for the "123" seed (pregenerated) for a
65    /// // Minotaur (b), Berserker (i), with a mace (b)
66    /// webtile.start_game_seeded("dcss-web-trunk", "123", true, "b", "i", "b")?;
67    /// ```
68    pub fn start_game_seeded(
69        &mut self,
70        game_id: &str,
71        seed: &str,
72        pregenerate: bool,
73        species: &str,
74        background: &str,
75        weapon: &str,
76    ) -> Result<(), Error> {
77        self.write_json(json!({"msg": "play", "game_id": game_id}))?;
78
79        let mut newgame_count = 0;
80        loop {
81            match self.read_until("map", None, None) {
82                Ok(_) => return Ok(()),
83                Err(e) => match e {
84                    Error::Blocking(BlockingError::SeedSelection) => {
85                        self.write_key("-")?;
86                        self.read_until("ui-state-sync", None, None)?;
87                        self.write_key(seed)?;
88                        if pregenerate {
89                            self.write_key("\t\t\t \r")?;
90                        } else {
91                            self.write_key("\r")?;
92                        }
93                    }
94                    Error::Blocking(BlockingError::NewGameChoice) => {
95                        match newgame_count {
96                            0 => self.write_key(species)?,
97                            1 => self.write_key(background)?,
98                            2 => self.write_key(weapon)?,
99                            _ => unreachable!(),
100                        }
101
102                        newgame_count += 1;
103                    }
104                    _ => return Err(e),
105                },
106            };
107        }
108    }
109
110    /// Save a game by sending the `CTRL + S` command.
111    ///
112    /// # Example
113    ///
114    /// ```no_run
115    /// webtile.save_game()?;
116    /// ```
117    pub fn save_game(&mut self) -> Result<(), Error> {
118        self.write_key("key_ctrl_s")?;
119
120        self.read_until("go_lobby", None, None)?;
121
122        Ok(())
123    }
124
125    /// Quit the game (same result as dying), by sending a `CTRL + Q` and
126    /// answering `yes`.
127    ///
128    /// # Example
129    ///
130    /// ```no_run
131    /// webtile.quit_game()?;
132    /// ```
133    pub fn quit_game(&mut self) -> Result<(), Error> {
134        self.write_key("key_ctrl_q")?;
135
136        match self.read_until("input_mode", Some("mode"), Some(7)) {
137            Ok(_) => (),
138            Err(e) => match e {
139                Error::Blocking(BlockingError::TextInput) => {
140                    self.write_key("yes")?;
141                    self.write_key("key_enter")?;
142                    self.message_found = false; // Otherwise close_input will be skipped
143                }
144                _ => return Err(e),
145            },
146        };
147
148        match self.read_until("close_input", None, None) {
149            Ok(_) => (),
150            Err(e) => match e {
151                Error::Blocking(BlockingError::More) => self.write_key("key_esc")?,
152                _ => return Err(e),
153            },
154        };
155
156        loop {
157            self.write_key("key_esc")?;
158            match self.read_until("go_lobby", None, None) {
159                Ok(_) => return Ok(()),
160                Err(e) => match e {
161                    Error::Blocking(BlockingError::More) => (),
162                    _ => return Err(e),
163                },
164            };
165        }
166    }
167}