dilemma_tactix_lib/models/game_grid.rs
1// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2// * Copyright (c) 2023-2024
3// *
4// * This project is dual-licensed under the MIT and Apache licenses.
5// *
6// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7// ** APACHE 2.0 LICENSE
8// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
9// *
10// * Licensed under the Apache License, Version 2.0 (the "License");
11// * you may not use this file except in compliance with the License.
12// * You may obtain a copy of the License at
13// *
14// * http://www.apache.org/licenses/LICENSE-2.0
15// *
16// * Unless required by applicable law or agreed to in writing, software
17// * distributed under the License is distributed on an "AS IS" BASIS,
18// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19// * See the License for the specific language governing permissions and
20// * limitations under the License.
21// *
22// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
23// * * MIT LICENSE
24// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
25// *
26// * Permission is hereby granted, free of charge, to any person obtaining a copy
27// * of this software and associated documentation files (the "Software"), to deal
28// * in the Software without restriction, including without limitation the rights
29// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30// * copies of the Software, and to permit persons to whom the Software is
31// * furnished to do so, subject to the following conditions:
32// *
33// * The above copyright notice and this permission notice shall be included in all
34// * copies or substantial portions of the Software.
35// *
36// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42// * SOFTWARE.
43// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
44
45use prettytable::{
46 format::Alignment,
47 Cell,
48 Row,
49 Table,
50};
51
52use crate::{
53 Choice,
54 GameOptions,
55 NumberPair,
56};
57
58/// A representation of the game board.
59///
60/// The `GameGrid` struct is a representation of the game board. It encapsulates
61/// the various values that are used to represent the game board, including the
62/// Players Aleph and Beth, the four possible ways the two players can make
63/// their choices, and the corresponding scores.
64///
65/// The `GameGrid` struct also contains the `GameOptions` struct, which contains
66/// the various options that can be used to configure the game.
67///
68/// # Examples
69///
70/// ```
71/// use dilemma_tactix_lib::{
72/// Choice,
73/// GameGrid,
74/// GameOptions,
75/// };
76///
77/// let game_options = GameOptions::builder("customized").build();
78///
79/// let game_grid = GameGrid::new(game_options);
80///
81/// game_grid.show_grid();
82/// ```
83#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
84pub struct GameGrid {
85 pub game_options: GameOptions,
86}
87
88impl GameGrid {
89 /// Creates a new `GameGrid` instance.
90 ///
91 /// # Examples
92 ///
93 /// ```
94 /// use dilemma_tactix_lib::{
95 /// Choice,
96 /// GameGrid,
97 /// GameOptions,
98 /// };
99 ///
100 /// let game_options = GameOptions::builder("customized").build();
101 ///
102 /// let game_grid = GameGrid::new(game_options);
103 /// ```
104 ///
105 /// # Returns
106 ///
107 /// A new `GameGrid` instance.
108 ///
109 /// # See Also
110 ///
111 /// * [`GameOptions`](struct.GameOptions.html)
112 /// * [`GameOptionsBuilder`](struct.GameOptionsBuilder.html)
113 /// * [`GameOptions::new()`](struct.GameOptions.html#method.new)
114 /// * [`GameOptions::default()`](struct.GameOptions.html#impl-Default)
115 /// * [`GameOptions::builder()`](struct.GameOptions.html#method.builder)
116 /// * [`GameOptionsBuilder::build()`](struct.GameOptionsBuilder.html#method.build)
117 #[must_use]
118 pub const fn new(game_options: GameOptions) -> Self {
119 Self { game_options }
120 }
121
122 /// Format the `GameGrid` into a `Table`
123 ///
124 /// # Returns
125 ///
126 /// A `Table` representation of the `GameGrid`.
127 ///
128 /// # See Also
129 ///
130 /// * [`GameGrid::show_grid()`](struct.GameGrid.html#method.show_grid)
131 /// * [`Table`](https://docs.rs/prettytable/0.8.0/prettytable/struct.Table.html)
132
133 fn make_grid(&self) -> Table {
134 let mut table = Table::new();
135
136 table.add_row(Row::new(vec![
137 Cell::new(""),
138 Cell::new_align("Player 2", Alignment::CENTER).with_hspan(2),
139 ]));
140
141 table.add_row(Row::new(vec![
142 Cell::new("Player 1"),
143 Cell::new(self.game_options.choice_atlantis()),
144 Cell::new(self.game_options.choice_olympus()),
145 ]));
146
147 table.add_row(Row::new(vec![
148 Cell::new(self.game_options.choice_atlantis()),
149 Cell::new(self.game_options.atlantis_atlantis().to_string().as_str()),
150 Cell::new(self.game_options.atlantis_olympus().to_string().as_str()),
151 ]));
152
153 table.add_row(Row::new(vec![
154 Cell::new(self.game_options.choice_olympus()),
155 Cell::new(self.game_options.olympus_atlantis().to_string().as_str()),
156 Cell::new(self.game_options.olympus_olympus().to_string().as_str()),
157 ]));
158
159 table
160 }
161
162 /// Display the `GameGrid` in the terminal.
163 ///
164 /// # Examples
165 ///
166 /// ```
167 /// use dilemma_tactix_lib::{
168 /// Choice,
169 /// GameGrid,
170 /// GameOptions,
171 /// };
172 ///
173 /// let game_options = GameOptions::builder("customized").build();
174 ///
175 /// let game_grid = GameGrid::new(game_options);
176 ///
177 /// game_grid.show_grid();
178 /// ```
179 ///
180 /// # See Also
181 ///
182 /// * [`GameGrid::make_grid()`](struct.GameGrid.html#method.make_grid)
183 /// * [`Table::printstd()`](https://docs.rs/prettytable/0.8.0/prettytable/struct.Table.html#method.printstd)
184 /// * [`Table::to_string()`](https://docs.rs/prettytable/0.8.0/prettytable/struct.Table.html#method.to_string)
185 pub fn show_grid(&self) {
186 self.make_grid().printstd();
187 }
188
189 /// Return the score for the given choices.
190 ///
191 /// # Arguments
192 ///
193 /// * `aleph_choice` - The choice made by Player 1.
194 /// * `beth_choice` - The choice made by Player 2.
195 ///
196 /// # Examples
197 ///
198 /// ```
199 /// use dilemma_tactix_lib::{
200 /// Choice,
201 /// GameGrid,
202 /// GameOptions,
203 /// };
204 ///
205 /// let game_options = GameOptions::builder("customized").build();
206 ///
207 /// let game_grid = GameGrid::new(game_options);
208 ///
209 /// let result = game_grid.return_score(Choice::Atlantis, Choice::Atlantis);
210 /// ```
211 ///
212 /// # Returns
213 ///
214 /// A `NumberPair` containing the scores for the given choices.
215 ///
216 /// # See Also
217 ///
218 /// * [`NumberPair`](struct.NumberPair.html)
219 /// * [`GameOptions`](struct.GameOptions.html)
220 #[must_use]
221 pub const fn return_score(&self, aleph_choice: Choice, beth_choice: Choice) -> NumberPair {
222 match (aleph_choice, beth_choice) {
223 (Choice::Atlantis, Choice::Atlantis) => self.game_options.atlantis_atlantis(),
224 (Choice::Atlantis, Choice::Olympus) => self.game_options.atlantis_olympus(),
225 (Choice::Olympus, Choice::Atlantis) => self.game_options.olympus_atlantis(),
226 (Choice::Olympus, Choice::Olympus) => self.game_options.olympus_olympus(),
227 }
228 }
229}