dilemma_tactix_lib/models/
game_option_builder.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 crate::{
46    BuilderError,
47    GameOptions,
48    NumberPair,
49};
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq)]
52pub enum GameOptionsBuilderTypes {
53    /// This builder variant allows for full randomization
54    /// of the GameOptions struct that is being built.
55    Randomized,
56    /// This builder variant allows for the GameOptions struct
57    /// that is being built to be randomized, but seeded.
58    Seeded,
59    /// This builder variant allows for the GameOptions struct
60    /// that is being built to be fully customized.
61    Customized,
62}
63
64/// A builder struct to create a [`GameOptions`](crate::GameOptions).
65///
66/// This struct is designed to encapsulate different ways of generating a new
67/// `GameOptions` struct. It is designed to be used in conjunction with the
68/// [`GameOptions`](crate::GameOptions) struct.
69///
70/// The `GameOptionsBuilder::new()` method is used to create a new builder,
71/// which takes a `builder_type` argument. This argument is used to determine
72/// which variant of the builder is used. The `builder_type` argument can be one
73/// of the following:
74///
75/// * "randomized": This creates a builder of type
76///   [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized).
77/// * "seeded": This creates a builder of type
78///   [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded)
79/// * "customized": This creates a builder of type
80///   [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized)
81///
82/// Each of these variants has different fields that can be set and serve
83/// different purposes. The following table shows which fields should be set for
84/// each variant:
85///
86/// | Field | Randomized | Seeded | Customized | Type | Default |
87/// | ----- | ---------- | ------ | ---------- | ---- | ------- |
88/// | `min_value` | Yes | No | Yes | u32 | 1 |
89/// | `max_value` | Yes | No | Yes | u32 | 10 |
90/// | `choice_atlantis` | Yes | Yes | Yes | &'static str | "cooperate" |
91/// | `choice_olympus` | Yes | Yes | Yes | &'static str | "defect" |
92/// | `atlantis_atlantis` | No | No | Yes | `NumberPair` | `NumberPair::new(4, 4)` |
93/// | `atlantis_olympus` | No | No | Yes | `NumberPair` | `NumberPair::new(0, 5)` |
94/// | `olympus_atlantis` | No | No | Yes | `NumberPair` | `NumberPair::new(5, 0)` |
95/// | `olympus_olympus` | No | No | Yes | `NumberPair` | `NumberPair::new(3, 3)` |
96/// | `seed` | No | Yes | No | `u64` | `None` |
97/// # Example
98///
99/// ## `RandomizedBuilder`
100///
101/// This builder path takes in the lower bound and the upper bound for the
102/// scores that can be assigned to each option. It then generates a random
103/// score for each option within the given bounds.
104///
105/// ```
106/// use dilemma_tactix_lib::{
107///     GameOptionsBuilder as Builder,
108///     GameOptionsBuilderTypes as BuilderTypes,
109///     NumberPair,
110/// # BuilderError,
111/// };
112///
113/// let builder = Builder::new(BuilderTypes::Randomized);
114/// let builder = builder.min_value(1);
115/// # assert!(builder.is_ok());
116/// let builder = builder?.max_value(10);
117/// # assert!(builder.is_ok());
118/// let builder = builder?.choice_atlantis("cooperate");
119/// # assert!(builder.is_ok());
120/// let builder = builder?.choice_olympus("defect");
121/// # assert!(builder.is_ok());
122///
123/// let game_options = builder?.build();
124///
125/// # assert_eq!(game_options.choice_atlantis(), "cooperate");
126/// # assert_eq!(game_options.choice_olympus(), "defect");
127/// # assert!(game_options.atlantis_atlantis().first() >= 1);
128/// # assert!(game_options.atlantis_atlantis().first() <= 10);
129/// # assert!(game_options.atlantis_atlantis().second() >= 1);
130/// # assert!(game_options.atlantis_atlantis().second() <= 10);
131/// # assert!(game_options.atlantis_olympus().first() >= 1);
132/// # assert!(game_options.atlantis_olympus().first() <= 10);
133/// # assert!(game_options.atlantis_olympus().second() >= 1);
134/// # assert!(game_options.atlantis_olympus().second() <= 10);
135/// # assert!(game_options.olympus_atlantis().first() >= 1);
136/// # assert!(game_options.olympus_atlantis().first() <= 10);
137/// # assert!(game_options.olympus_atlantis().second() >= 1);
138/// # assert!(game_options.olympus_atlantis().second() <= 10);
139/// # assert!(game_options.olympus_olympus().first() >= 1);
140/// # assert!(game_options.olympus_olympus().first() <= 10);
141/// # assert!(game_options.olympus_olympus().second() >= 1);
142/// # assert!(game_options.olympus_olympus().second() <= 10);
143///
144/// # Ok::<(), BuilderError>(())
145/// ```
146/// ## `SeededBuilder`
147///
148/// This builder path takes in the lower bound and the upper bound for the
149/// scores that can be assigned to each option. It also takes a `seed` value
150/// It then generates a random score for each option within the given
151/// bounds and the given seed.
152///
153/// ```no_run
154/// use dilemma_tactix_lib::{
155///     GameOptionsBuilder as Builder,
156///     GameOptionsBuilderTypes as BuilderTypes,
157/// };
158///
159/// let builder = Builder::new(BuilderTypes::Seeded);
160/// # assert_eq!(builder.choice_atlantis, None);
161/// # assert_eq!(builder.choice_olympus, None);
162/// # assert_eq!(builder.atlantis_atlantis, None);
163/// # assert_eq!(builder.atlantis_olympus, None);
164/// # assert_eq!(builder.olympus_atlantis, None);
165/// # assert_eq!(builder.olympus_olympus, None);
166/// ```
167///
168/// ## `CustomizedBuilder`
169///
170/// This builder allows you to set all the scores for each possible
171/// outcome individually. This allows for the most customization of the
172/// `GameOptions` struct.
173///
174/// ```
175/// use dilemma_tactix_lib::{
176///     GameOptionsBuilder as Builder,
177///     GameOptionsBuilderTypes as BuilderTypes,
178///     NumberPair,
179/// # BuilderError,
180/// };
181///
182/// let builder = Builder::new(BuilderTypes::Customized);
183/// let builder = builder.choice_atlantis("cooperate");
184/// # assert!(builder.is_ok());
185/// let builder = builder?.choice_olympus("defect");
186/// # assert!(builder.is_ok());
187/// let builder = builder?.atlantis_atlantis(NumberPair::new(4, 4));
188/// # assert!(builder.is_ok());
189/// let builder = builder?.atlantis_olympus(NumberPair::new(0, 5));
190/// # assert!(builder.is_ok());
191/// let builder = builder?.olympus_atlantis(NumberPair::new(5, 0));
192/// # assert!(builder.is_ok());
193/// let builder = builder?.olympus_olympus(NumberPair::new(3, 3));
194/// # assert!(builder.is_ok());
195///
196/// let game_options = builder?.build();
197///
198/// # assert_eq!(game_options.choice_atlantis(), "cooperate");
199/// # assert_eq!(game_options.choice_olympus(), "defect");
200/// # assert_eq!(game_options.atlantis_atlantis(), NumberPair::new(4, 4));
201/// # assert_eq!(game_options.atlantis_olympus(), NumberPair::new(0, 5));
202/// # assert_eq!(game_options.olympus_atlantis(), NumberPair::new(5, 0));
203/// # assert_eq!(game_options.olympus_olympus(), NumberPair::new(3, 3));
204/// # Ok::<(), BuilderError>(())
205/// ```
206///
207/// # Notes
208///
209/// I chose to use the `Builder` pattern here because it allows for easier
210/// manipulation of the `GameOptions` struct. I also used a `State` or `Variant`
211/// pattern here because it had the lowest complexity in terms of understanding
212/// the flow of options that need to be set.
213///
214/// # See Also
215///
216/// * [`GameOptions`](crate::GameOptions)
217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
218pub struct GameOptionsBuilder {
219    builder_type:          GameOptionsBuilderTypes,
220    min_value:             Option<u32>,
221    max_value:             Option<u32>,
222    pub choice_atlantis:   Option<&'static str>,
223    pub choice_olympus:    Option<&'static str>,
224    pub atlantis_atlantis: Option<NumberPair>,
225    pub atlantis_olympus:  Option<NumberPair>,
226    pub olympus_atlantis:  Option<NumberPair>,
227    pub olympus_olympus:   Option<NumberPair>,
228    seed:                  Option<u64>,
229}
230
231impl GameOptionsBuilder {
232    /// Creates a new `GameOptionsBuilder` struct.
233    ///
234    /// This associated function creates a new `GameOptionsBuilder` struct with
235    /// the given `builder_type`. The `builder_type` argument can be one of the
236    /// following:
237    ///
238    /// * "randomized": This creates a builder of type
239    ///  [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized).
240    /// * "seeded": This creates a builder of type
241    /// [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded)
242    /// * "customized": This creates a builder of type
243    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized)
244    ///
245    /// # Arguments
246    ///
247    /// * `builder_type` - The type of builder to create.
248    ///
249    /// # Example
250    ///
251    /// ## `RandomizedBuilder`
252    ///
253    /// This builder path takes in the lower bound and the upper bound for the
254    /// scores that can be assigned to each option. It then generates a random
255    /// score for each option within the given bounds.
256    ///
257    /// ```
258    /// use dilemma_tactix_lib::{
259    ///     GameOptionsBuilder,
260    ///     GameOptionsBuilderTypes,
261    /// };
262    ///
263    /// let game_options_builder =
264    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
265    /// # assert_eq!(game_options_builder.choice_atlantis, None);
266    /// # assert_eq!(game_options_builder.choice_olympus, None);
267    /// # assert_eq!(game_options_builder.atlantis_atlantis, None);
268    /// # assert_eq!(game_options_builder.atlantis_olympus, None);
269    /// # assert_eq!(game_options_builder.olympus_atlantis, None);
270    /// # assert_eq!(game_options_builder.olympus_olympus, None);
271    /// ```
272    /// ## `SeededBuilder`
273    ///
274    /// This builder path takes in the lower bound and the upper bound for the
275    /// scores that can be assigned to each option. It also takes a `seed` value
276    /// It then generates a random score for each option within the given
277    /// bounds and the given seed.
278    ///
279    /// ```no_run
280    /// use dilemma_tactix_lib::{
281    ///     GameOptionsBuilder,
282    ///     GameOptionsBuilderTypes,
283    /// };
284    ///
285    /// let game_options_builder =
286    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
287    /// # assert_eq!(game_options_builder.choice_atlantis, None);
288    /// # assert_eq!(game_options_builder.choice_olympus, None);
289    /// # assert_eq!(game_options_builder.atlantis_atlantis, None);
290    /// # assert_eq!(game_options_builder.atlantis_olympus, None);
291    /// # assert_eq!(game_options_builder.olympus_atlantis, None);
292    /// # assert_eq!(game_options_builder.olympus_olympus, None);
293    /// ```
294    ///
295    /// ## `CustomizedBuilder`
296    ///
297    /// This builder allows you to set all the scores for each possible
298    /// outcome individually. This allows for the most customization of the
299    /// `GameOptions` struct.
300    ///
301    /// ```
302    /// use dilemma_tactix_lib::{
303    ///     GameOptionsBuilder,
304    ///     GameOptionsBuilderTypes,
305    /// };
306    ///
307    /// let game_options_builder =
308    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized);
309    /// # assert_eq!(game_options_builder.choice_atlantis, None);
310    /// # assert_eq!(game_options_builder.choice_olympus, None);
311    /// # assert_eq!(game_options_builder.atlantis_atlantis, None);
312    /// # assert_eq!(game_options_builder.atlantis_olympus, None);
313    /// # assert_eq!(game_options_builder.olympus_atlantis, None);
314    /// # assert_eq!(game_options_builder.olympus_olympus, None);
315    /// ```
316    ///
317    /// # Returns
318    ///
319    /// A new `GameOptionsBuilder` struct with a given builder type.
320    ///
321    /// # See Also
322    ///
323    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
324    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
325    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
326    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
327    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
328    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
329    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
330    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
331    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
332    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
333    #[must_use]
334    pub const fn new(builder_type: GameOptionsBuilderTypes) -> Self {
335        Self {
336            builder_type,
337            max_value: None,
338            min_value: None,
339            choice_atlantis: None,
340            choice_olympus: None,
341            atlantis_atlantis: None,
342            atlantis_olympus: None,
343            olympus_atlantis: None,
344            olympus_olympus: None,
345            seed: None,
346        }
347    }
348
349    /// Sets the minimum value for the `GameOptions`.
350    ///
351    /// This function sets the minimum value for the `GameOptions` struct that
352    /// is being built. This function is only valid for the
353    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
354    /// and the [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded)
355    /// variants of the `GameOptionsBuilder` struct.
356    ///
357    /// # Arguments
358    ///
359    /// * `min_value` - The minimum value for the `GameOptions`.
360    ///
361    /// # Example
362    ///
363    /// ## `RandomizedBuilder`
364    /// ```
365    /// use dilemma_tactix_lib::{
366    ///     GameOptionsBuilder,
367    ///     GameOptionsBuilderTypes,
368    /// };
369    ///
370    /// let game_options_builder =
371    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
372    ///         .min_value(1);
373    /// assert!(game_options_builder.is_ok());
374    /// ```
375    ///
376    /// ## `SeededBuilder`
377    ///
378    /// ```no_run
379    /// use dilemma_tactix_lib::{
380    ///     GameOptionsBuilder,
381    ///     GameOptionsBuilderTypes,
382    /// };
383    ///
384    /// let game_options_builder =
385    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).min_value(1);
386    ///
387    /// assert!(game_options_builder.is_ok());
388    /// ```
389    ///
390    /// ## `CustomizedBuilder`
391    ///
392    /// ```
393    /// use dilemma_tactix_lib::{
394    ///     GameOptionsBuilder,
395    ///     GameOptionsBuilderTypes,
396    /// };
397    ///
398    /// let game_options_builder =
399    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
400    ///         .min_value(1);
401    ///
402    /// assert!(game_options_builder.is_err());
403    /// ```
404    ///
405    /// # Errors
406    ///
407    /// This function will return an error if the `builder_type` is
408    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized).
409    ///
410    /// # Returns
411    ///
412    /// The `GameOptionsBuilder` struct with the `min_value` field set.
413    ///
414    /// # See Also
415    ///
416    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
417    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
418    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
419    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
420    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
421    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
422    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
423    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
424    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
425    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
426    pub fn min_value(mut self, min_value: u32) -> Result<Self, BuilderError> {
427        match self.builder_type {
428            GameOptionsBuilderTypes::Randomized | GameOptionsBuilderTypes::Seeded => {
429                self.min_value = Some(min_value);
430                Ok(self)
431            }
432            GameOptionsBuilderTypes::Customized => Err(BuilderError::InvalidOptionSpecified(
433                "min_value must not be set when using CusotmizedBuilder".to_string(),
434            )),
435        }
436    }
437
438    /// Sets the maximum value for the `GameOptions`.
439    ///
440    /// This function sets the maximum value for the `GameOptions` struct that
441    /// is being built. This function is only valid for the
442    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
443    /// and the [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded)
444    /// variants of the `GameOptionsBuilder` struct.
445    ///
446    /// # Arguments
447    ///
448    /// * `max_value` - The maximum value for the `GameOptions`.
449    ///
450    /// # Example
451    ///
452    /// ## `RandomizedBuilder`
453    /// ```
454    /// use dilemma_tactix_lib::{
455    ///     GameOptionsBuilder,
456    ///     GameOptionsBuilderTypes,
457    /// };
458    ///
459    /// let game_options_builder =
460    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
461    ///         .max_value(10);
462    /// assert!(game_options_builder.is_ok());
463    /// ```
464    ///
465    /// ## `SeededBuilder`
466    ///
467    /// ```no_run
468    /// use dilemma_tactix_lib::{
469    ///     GameOptionsBuilder,
470    ///     GameOptionsBuilderTypes,
471    /// };
472    ///
473    /// let game_options_builder =
474    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).max_value(10);
475    ///
476    /// assert!(game_options_builder.is_ok());
477    /// ```
478    ///
479    /// ## `CustomizedBuilder`
480    ///
481    /// ```
482    /// use dilemma_tactix_lib::{
483    ///     GameOptionsBuilder,
484    ///     GameOptionsBuilderTypes,
485    /// };
486    ///
487    /// let game_options_builder =
488    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
489    ///         .max_value(10);
490    ///
491    /// assert!(game_options_builder.is_err());
492    /// ```
493    ///
494    /// # Errors
495    ///
496    /// This function will return an error if the `builder_type` is
497    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized).
498    ///
499    /// # Returns
500    ///
501    /// The `GameOptionsBuilder` struct with the `max_value` field set.
502    ///
503    /// # See Also
504    ///
505    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
506    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
507    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
508    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
509    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
510    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
511    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
512    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
513    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
514    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
515    pub fn max_value(mut self, max_value: u32) -> Result<Self, BuilderError> {
516        match self.builder_type {
517            GameOptionsBuilderTypes::Randomized | GameOptionsBuilderTypes::Seeded => {
518                self.max_value = Some(max_value);
519                Ok(self)
520            }
521            GameOptionsBuilderTypes::Customized => Err(BuilderError::InvalidOptionSpecified(
522                "max_value must not be set when using CustomizedBuilder".to_string(),
523            )),
524        }
525    }
526
527    /// Sets the first choice available to players in `GameOptions`.
528    ///
529    /// This function sets the first choice available to players in
530    /// `GameOptions`. This function is valid for all variants of the
531    /// `GameOptionsBuilder` struct.
532    ///
533    /// # Arguments
534    ///
535    /// * `choice_atlantis` - The first choice available to players in `GameOptions`.
536    ///
537    /// # Example
538    ///
539    /// ## `RandomizedBuilder`
540    ///
541    /// ```
542    /// use dilemma_tactix_lib::{
543    ///     GameOptionsBuilder,
544    ///     GameOptionsBuilderTypes,
545    /// };
546    ///
547    /// let game_options_builder =
548    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
549    ///         .choice_atlantis("cooperate");
550    /// # assert!(game_options_builder.is_ok());
551    ///
552    /// let game_options = game_options_builder.unwrap().build();
553    ///
554    /// # assert_eq!(game_options.choice_atlantis(), "cooperate");
555    /// ```
556    ///
557    /// ## `SeededBuilder`
558    ///
559    /// ```no_run
560    /// use dilemma_tactix_lib::{
561    ///     GameOptionsBuilder,
562    ///     GameOptionsBuilderTypes,
563    /// };
564    /// use rand::SeedableRng;
565    ///
566    /// let game_options_builder =
567    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
568    ///         .choice_atlantis("cooperate");
569    /// # assert!(game_options_builder.is_ok());
570    ///
571    /// let game_options = game_options_builder.unwrap().build();
572    ///
573    /// # assert_eq!(game_options.choice_atlantis(), "cooperate");
574    /// ```
575    ///
576    /// ## `CustomizedBuilder`
577    ///
578    /// ```
579    /// use dilemma_tactix_lib::{
580    ///     GameOptionsBuilder,
581    ///     GameOptionsBuilderTypes,
582    /// };
583    ///
584    /// let game_options_builder =
585    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
586    ///         .choice_atlantis("cooperate");
587    /// # assert!(game_options_builder.is_ok());
588    ///
589    /// let game_options = game_options_builder.unwrap().build();
590    ///
591    /// # assert_eq!(game_options.choice_atlantis(), "cooperate");
592    /// ```
593    ///
594    /// # Errors
595    ///
596    /// This function will return an error if the `choice_atlantis` argument is
597    /// empty.
598    ///
599    /// # Returns
600    ///
601    /// The `GameOptionsBuilder` struct with the `choice_atlantis` field set.
602    ///
603    /// # See Also
604    ///
605    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
606    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
607    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
608    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
609    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
610    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
611    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
612    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
613    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
614    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
615    pub fn choice_atlantis(mut self, choice_atlantis: &'static str) -> Result<Self, BuilderError> {
616        if choice_atlantis.is_empty() {
617            return Err(BuilderError::InvalidOptionValueSpecified(
618                "choice_atlantis must not be empty".to_string(),
619            ));
620        }
621        self.choice_atlantis = Some(choice_atlantis);
622        Ok(self)
623    }
624
625    /// Sets the second choice available to players in `GameOptions`.
626    ///
627    /// This function sets the second choice available to players in
628    /// `GameOptions`. This function is valid for all variants of the
629    /// `GameOptionsBuilder` struct.
630    ///
631    /// # Arguments
632    ///
633    /// * `choice_olympus` - The second choice available to players in `GameOptions`.
634    ///
635    /// # Example
636    ///
637    /// ## `RandomizedBuilder`
638    ///
639    /// ```
640    /// use dilemma_tactix_lib::{
641    ///     GameOptionsBuilder,
642    ///     GameOptionsBuilderTypes,
643    /// };
644    ///
645    /// let game_options_builder =
646    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
647    ///         .choice_olympus("defect");
648    /// # assert!(game_options_builder.is_ok());
649    ///
650    /// let game_options = game_options_builder.unwrap().build();
651    ///
652    /// # assert_eq!(game_options.choice_olympus(), "defect");
653    /// ```
654    ///
655    /// ## `SeededBuilder`
656    ///
657    /// ```no_run
658    /// use dilemma_tactix_lib::{
659    ///     GameOptionsBuilder,
660    ///     GameOptionsBuilderTypes,
661    /// };
662    ///
663    /// let game_options_builder =
664    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
665    ///         .choice_olympus("defect");
666    /// # assert!(game_options_builder.is_ok());
667    ///
668    /// let game_options = game_options_builder.unwrap().build();
669    ///
670    /// # assert_eq!(game_options.choice_olympus(), "defect");
671    /// ```
672    ///
673    /// ## `CustomizedBuilder`
674    ///
675    /// ```
676    /// use dilemma_tactix_lib::{
677    ///     GameOptionsBuilder,
678    ///     GameOptionsBuilderTypes,
679    /// };
680    ///
681    /// let game_options_builder =
682    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
683    ///         .choice_olympus("defect");
684    /// # assert!(game_options_builder.is_ok());
685    ///
686    /// let game_options = game_options_builder.unwrap().build();
687    ///
688    /// # assert_eq!(game_options.choice_olympus(), "defect");
689    /// ```
690    ///
691    /// # Errors
692    ///
693    /// This function will return an error if the `choice_olympus` argument is
694    /// empty.
695    ///
696    /// # Returns
697    ///
698    /// The `GameOptionsBuilder` struct with the `choice_olympus` field set.
699    ///
700    /// # See Also
701    ///
702    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
703    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
704    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
705    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
706    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
707    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
708    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
709    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
710    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
711    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
712    pub fn choice_olympus(mut self, choice_olympus: &'static str) -> Result<Self, BuilderError> {
713        if choice_olympus.is_empty() {
714            return Err(BuilderError::InvalidOptionValueSpecified(
715                "choice_olympus must not be empty".to_string(),
716            ));
717        }
718        self.choice_olympus = Some(choice_olympus);
719        Ok(self)
720    }
721
722    /// Sets the score for the case when both players (Aleph and Beth) choose
723    /// the first (Atlantis) choice.
724    ///
725    /// This function sets the score for the case when both players choose the
726    /// first (Atlantis) choice. This function is only valid for the
727    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized)
728    /// variant of the `GameOptionsBuilder` struct.
729    ///
730    /// # Arguments
731    ///
732    /// * `atlantis_atlantis` - The score to set.
733    ///
734    /// # Example
735    ///
736    /// ## `RandomizedBuilder`
737    ///
738    /// ```
739    /// use dilemma_tactix_lib::{
740    ///     GameOptionsBuilder,
741    ///     GameOptionsBuilderTypes,
742    ///     NumberPair,
743    /// };
744    ///
745    /// let game_options_builder =
746    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
747    ///         .atlantis_atlantis(NumberPair::new(4, 4));
748    /// # assert!(game_options_builder.is_err());
749    /// ```
750    ///
751    /// ## `SeededBuilder`
752    ///
753    /// ```no_run
754    /// use dilemma_tactix_lib::{
755    ///     GameOptionsBuilder,
756    ///     GameOptionsBuilderTypes,
757    ///     NumberPair,
758    /// };
759    ///
760    /// let game_options_builder =
761    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
762    ///         .atlantis_atlantis(NumberPair::new(4, 4));
763    /// # assert!(game_options_builder.is_err());
764    /// ```
765    ///
766    /// ## `CustomizedBuilder`
767    ///
768    /// ```
769    /// use dilemma_tactix_lib::{
770    ///    GameOptionsBuilder,
771    ///   GameOptionsBuilderTypes,
772    ///    NumberPair,
773    /// };
774    ///
775    /// let game_options_builder =
776    ///    GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
777    ///       .atlantis_atlantis(NumberPair::new(4, 4));
778    ///
779    /// # assert!(game_options_builder.is_ok());
780    ///
781    /// let game_options = game_options_builder.unwrap().build();
782    ///
783    /// # assert_eq!(game_options.atlantis_atlantis(), NumberPair::new(4, 4));
784    /// ```
785    ///
786    /// # Errors
787    ///
788    /// This function will return an error if the `builder_type` is
789    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
790    /// or [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded).
791    ///
792    /// # Returns
793    ///
794    /// The `GameOptionsBuilder` struct with the `atlantis_atlantis` field set.
795    ///
796    /// # See Also
797    ///
798    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
799    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
800    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
801    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
802    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
803    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
804    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
805    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
806    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
807    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
808    pub fn atlantis_atlantis(
809        mut self,
810        atlantis_atlantis: NumberPair,
811    ) -> Result<Self, BuilderError> {
812        match self.builder_type {
813            GameOptionsBuilderTypes::Randomized => Err(BuilderError::InvalidOptionSpecified(
814                "Field atlantis_atlantis can not be set when using RandomizedBuilder".to_string(),
815            )),
816            GameOptionsBuilderTypes::Seeded => Err(BuilderError::InvalidOptionSpecified(
817                "Field atlantis_atlantis can not be set when using SeededBuilder".to_string(),
818            )),
819            GameOptionsBuilderTypes::Customized => {
820                self.atlantis_atlantis = Some(atlantis_atlantis);
821                Ok(self)
822            }
823        }
824    }
825
826    /// Sets the score for the case when Player Aleph chooses the first
827    /// (Atlantis) choice and Player Beth chooses the second (Olympus)
828    /// choice.
829    ///
830    /// This function sets the score for the case when Player Aleph chooses the
831    /// first (Atlantis) choice and Player Beth chooses the second (Olympus)
832    /// choice. This function is only valid for the
833    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized)
834    /// variant of the `GameOptionsBuilder` struct.
835    ///
836    /// # Arguments
837    ///
838    /// * `atlantis_olympus` - The score to set.
839    ///
840    /// # Example
841    ///
842    /// ## `RandomizedBuilder`
843    ///
844    /// ```
845    /// use dilemma_tactix_lib::{
846    ///     GameOptionsBuilder,
847    ///     GameOptionsBuilderTypes,
848    ///     NumberPair,
849    /// };
850    ///
851    /// let game_options_builder =
852    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
853    ///         .atlantis_olympus(NumberPair::new(0, 5));
854    /// # assert!(game_options_builder.is_err());
855    /// ```
856    ///
857    /// ## `SeededBuilder`
858    ///
859    /// ```
860    /// use dilemma_tactix_lib::{
861    ///     GameOptionsBuilder,
862    ///     GameOptionsBuilderTypes,
863    ///     NumberPair,
864    /// };
865    ///
866    /// let game_options_builder =
867    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
868    ///         .atlantis_olympus(NumberPair::new(0, 5));
869    /// # assert!(game_options_builder.is_err());
870    /// ```
871    ///
872    /// ## `CustomizedBuilder`
873    ///
874    /// ```
875    /// use dilemma_tactix_lib::{
876    ///     GameOptionsBuilder,
877    ///     GameOptionsBuilderTypes,
878    ///     NumberPair,
879    /// };
880    ///
881    /// let game_options_builder =
882    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
883    ///         .atlantis_olympus(NumberPair::new(0, 5));
884    /// # assert!(game_options_builder.is_ok());
885    ///
886    /// let game_options = game_options_builder.unwrap().build();
887    ///
888    /// # assert_eq!(game_options.atlantis_olympus(), NumberPair::new(0, 5));
889    /// ```
890    ///
891    /// # Errors
892    ///
893    /// This function will return an error if the `builder_type` is
894    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
895    /// or [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded).
896    ///
897    /// # Returns
898    ///
899    /// The `GameOptionsBuilder` struct with the `atlantis_olympus` field set.
900    ///
901    ///
902    /// # See Also
903    ///
904    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
905    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
906    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
907    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
908    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
909    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
910    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
911    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
912    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
913    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
914    pub fn atlantis_olympus(mut self, atlantis_olympus: NumberPair) -> Result<Self, BuilderError> {
915        match self.builder_type {
916            GameOptionsBuilderTypes::Randomized => Err(BuilderError::InvalidOptionSpecified(
917                "Field atlantis_olympus can not be set when using RandomizedBuilder".to_string(),
918            )),
919            GameOptionsBuilderTypes::Seeded => Err(BuilderError::InvalidOptionSpecified(
920                "Field atlantis_olympus can not be set when using SeededBuilder".to_string(),
921            )),
922            GameOptionsBuilderTypes::Customized => {
923                self.atlantis_olympus = Some(atlantis_olympus);
924                Ok(self)
925            }
926        }
927    }
928
929    /// Sets the score for the case when Player Aleph chooses the second
930    /// choice and Player Beth chooses the first choice.
931    ///
932    /// This function sets the score for the case when Player Aleph chooses the
933    /// second (Olympus) choice and Player Beth chooses the first (Atlantis)
934    /// choice. This function is only valid for the
935    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized)
936    /// variant of the `GameOptionsBuilder` struct.
937    ///
938    /// # Arguments
939    ///
940    /// * `olympus_atlantis` - The score to set.
941    ///
942    /// # Example
943    ///
944    /// ## `RandomizedBuilder`
945    ///
946    /// ```
947    /// use dilemma_tactix_lib::{
948    ///     GameOptionsBuilder,
949    ///     GameOptionsBuilderTypes,
950    ///     NumberPair,
951    /// };
952    ///
953    /// let game_options_builder =
954    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
955    ///         .olympus_atlantis(NumberPair::new(5, 0));
956    ///
957    /// # assert!(game_options_builder.is_err());
958    /// ```
959    ///
960    /// ## `SeededBuilder`
961    ///
962    /// ```
963    /// use dilemma_tactix_lib::{
964    ///     GameOptionsBuilder,
965    ///     GameOptionsBuilderTypes,
966    ///     NumberPair,
967    /// };
968    ///
969    /// let game_options_builder =
970    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
971    ///         .olympus_atlantis(NumberPair::new(5, 0));
972    ///
973    /// # assert!(game_options_builder.is_err());
974    /// ```
975    ///
976    /// ## `CustomizedBuilder`
977    ///
978    /// ```
979    /// use dilemma_tactix_lib::{
980    ///     GameOptionsBuilder,
981    ///     GameOptionsBuilderTypes,
982    ///     NumberPair,
983    /// };
984    ///
985    /// let game_options_builder =
986    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
987    ///         .olympus_atlantis(NumberPair::new(5, 0));
988    ///
989    /// # assert!(game_options_builder.is_ok());
990    ///
991    /// let game_options = game_options_builder.unwrap().build();
992    ///
993    /// # assert_eq!(game_options.olympus_atlantis(), NumberPair::new(5, 0));
994    /// ```
995    ///
996    /// # Errors
997    ///
998    /// This function will return an error if the `builder_type` is
999    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
1000    /// or [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded).
1001    ///
1002    /// # Returns
1003    ///
1004    /// The `GameOptionsBuilder` struct with the `olympus_atlantis` field set.
1005    ///
1006    ///
1007    /// # See Also
1008    ///
1009    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
1010    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
1011    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
1012    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
1013    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
1014    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
1015    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
1016    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
1017    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
1018    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
1019    pub fn olympus_atlantis(mut self, olympus_atlantis: NumberPair) -> Result<Self, BuilderError> {
1020        match self.builder_type {
1021            GameOptionsBuilderTypes::Randomized => Err(BuilderError::InvalidOptionSpecified(
1022                "Field olympus_atlantis can not be set when using RandomizedBuilder".to_string(),
1023            )),
1024            GameOptionsBuilderTypes::Seeded => Err(BuilderError::InvalidOptionSpecified(
1025                "Field olympus_atlantis can not be set when using SeededBuilder".to_string(),
1026            )),
1027            GameOptionsBuilderTypes::Customized => {
1028                self.olympus_atlantis = Some(olympus_atlantis);
1029                Ok(self)
1030            }
1031        }
1032    }
1033
1034    /// Sets the score for the case when both players (Aleph and Beth) choose
1035    /// the second (Olympus) choice.
1036    ///
1037    /// This function sets the score for the case when both players choose the
1038    /// second (Olympus) choice. This function is only valid for the
1039    /// [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized)
1040    /// variant of the `GameOptionsBuilder` struct.
1041    ///
1042    /// # Arguments
1043    ///
1044    /// * `olympus_olympus` - The score to set.
1045    ///
1046    /// # Example
1047    ///
1048    /// ## `RandomizedBuilder`
1049    ///
1050    /// ```
1051    /// use dilemma_tactix_lib::{
1052    ///     GameOptionsBuilder,
1053    ///     GameOptionsBuilderTypes,
1054    ///     NumberPair,
1055    /// };
1056    ///
1057    /// let game_options_builder =
1058    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1059    ///         .olympus_olympus(NumberPair::new(3, 3));
1060    ///
1061    /// # assert!(game_options_builder.is_err());
1062    /// ```
1063    ///
1064    /// ## `SeededBuilder`
1065    ///
1066    /// ```
1067    /// use dilemma_tactix_lib::{
1068    ///     GameOptionsBuilder,
1069    ///     GameOptionsBuilderTypes,
1070    ///     NumberPair,
1071    /// };
1072    ///
1073    /// let game_options_builder =
1074    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
1075    ///         .olympus_olympus(NumberPair::new(3, 3));
1076    ///
1077    /// # assert!(game_options_builder.is_err());
1078    /// ```
1079    ///
1080    /// ## `CustomizedBuilder`
1081    ///
1082    /// ```
1083    /// use dilemma_tactix_lib::{
1084    ///     GameOptionsBuilder,
1085    ///     GameOptionsBuilderTypes,
1086    ///     NumberPair,
1087    /// };
1088    ///
1089    /// let game_options_builder =
1090    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1091    ///         .olympus_olympus(NumberPair::new(3, 3));
1092    ///
1093    /// # assert!(game_options_builder.is_ok());
1094    ///
1095    /// let game_options = game_options_builder.unwrap().build();
1096    ///
1097    /// # assert_eq!(game_options.olympus_olympus(), NumberPair::new(3, 3));
1098    /// ```
1099    ///
1100    /// # Errors
1101    ///
1102    /// This function will return an error if the `builder_type` is
1103    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
1104    /// or [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded).
1105    ///
1106    /// # Returns
1107    ///
1108    /// The `GameOptionsBuilder` struct with the `olympus_olympus` field set.
1109    ///
1110    ///
1111    /// # See Also
1112    ///
1113    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
1114    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
1115    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
1116    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
1117    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
1118    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
1119    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
1120    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
1121    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
1122    /// * [`GameOptionsBuilder::seed()`](GameOptionsBuilder::seed())
1123    pub fn olympus_olympus(mut self, olympus_olympus: NumberPair) -> Result<Self, BuilderError> {
1124        match self.builder_type {
1125            GameOptionsBuilderTypes::Randomized => Err(BuilderError::InvalidOptionSpecified(
1126                "Field olympus_olympus can not be set when using RandomizedBuilder".to_string(),
1127            )),
1128            GameOptionsBuilderTypes::Seeded => Err(BuilderError::InvalidOptionSpecified(
1129                "Field olympus_olympus can not be set when using SeededBuilder".to_string(),
1130            )),
1131            GameOptionsBuilderTypes::Customized => {
1132                self.olympus_olympus = Some(olympus_olympus);
1133                Ok(self)
1134            }
1135        }
1136    }
1137
1138    /// Sets the seed for the `GameOptions`.
1139    ///
1140    /// This function sets the seed for the `GameOptions` struct that is being
1141    /// built. This function is only valid for the
1142    /// [`GameOptionsBuilderTypes::Seeded`](GameOptionsBuilderTypes::Seeded)
1143    /// variant of the `GameOptionsBuilder` struct.
1144    ///
1145    /// # Arguments
1146    ///
1147    /// * `seed` - The seed for the `GameOptions`.
1148    ///
1149    /// # Example
1150    ///
1151    /// ## `RandomizedBuilder`
1152    ///
1153    /// ```
1154    /// use dilemma_tactix_lib::{
1155    ///     GameOptionsBuilder,
1156    ///     GameOptionsBuilderTypes,
1157    /// };
1158    ///
1159    /// let game_options_builder =
1160    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1161    ///         .seed(123456789);
1162    ///
1163    /// # assert!(game_options_builder.is_err());
1164    /// ```
1165    ///
1166    /// ## `SeededBuilder`
1167    ///
1168    /// ```no_run
1169    /// use dilemma_tactix_lib::{
1170    ///     GameOptionsBuilder,
1171    ///     GameOptionsBuilderTypes,
1172    /// };
1173    ///
1174    /// let game_options_builder =
1175    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
1176    ///         .seed(123456789);
1177    ///
1178    /// # assert!(game_options_builder.is_ok());
1179    /// ```
1180    ///
1181    /// ## `CustomizedBuilder`
1182    ///
1183    /// ```
1184    /// use dilemma_tactix_lib::{
1185    ///     GameOptionsBuilder,
1186    ///     GameOptionsBuilderTypes,
1187    /// };
1188    ///
1189    /// let game_options_builder =
1190    ///     GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1191    ///         .seed(123456789);
1192    ///
1193    /// # assert!(game_options_builder.is_err());
1194    /// ```
1195    ///
1196    /// # Errors
1197    ///
1198    /// This function will return an error if the `builder_type` is
1199    /// [`GameOptionsBuilderTypes::Randomized`](GameOptionsBuilderTypes::Randomized)
1200    /// or [`GameOptionsBuilderTypes::Customized`](GameOptionsBuilderTypes::Customized).
1201    ///
1202    /// # Returns
1203    ///
1204    /// The `GameOptionsBuilder` struct with the `seed` field set.
1205    ///
1206    /// # See Also
1207    ///
1208    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
1209    /// * [`GameOptionsBuilder::build()`](GameOptionsBuilder::build())
1210    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
1211    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
1212    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
1213    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
1214    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
1215    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
1216    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
1217    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
1218    pub fn seed(mut self, seed: u64) -> Result<Self, BuilderError> {
1219        match self.builder_type {
1220            GameOptionsBuilderTypes::Randomized => Err(BuilderError::InvalidOptionSpecified(
1221                "Field seed can not be set when using RandomizedBuilder".to_string(),
1222            )),
1223            GameOptionsBuilderTypes::Seeded => {
1224                self.seed = Some(seed);
1225                Ok(self)
1226            }
1227            GameOptionsBuilderTypes::Customized => Err(BuilderError::InvalidOptionSpecified(
1228                "Field seed can not be set when using CustomizedBuilder".to_string(),
1229            )),
1230        }
1231    }
1232
1233    /// Builds the `GameOptions` struct.
1234    ///
1235    /// # Returns
1236    ///
1237    /// A new `GameOptions` struct.
1238    ///
1239    /// # Panics
1240    ///
1241    /// This function will panic if any of the required fields are not set.
1242    ///
1243    /// # See Also
1244    ///
1245    /// * [`GameOptionsBuilder::new()`](GameOptionsBuilder::new())
1246    /// * [`GameOptionsBuilder::max_value()`](GameOptionsBuilder::max_value())
1247    /// * [`GameOptionsBuilder::min_value()`](GameOptionsBuilder::min_value())
1248    /// * [`GameOptionsBuilder::choice_atlantis()`](GameOptionsBuilder::choice_atlantis())
1249    /// * [`GameOptionsBuilder::choice_olympus()`](GameOptionsBuilder::choice_olympus())
1250    /// * [`GameOptionsBuilder::atlantis_atlantis()`](GameOptionsBuilder::atlantis_atlantis())
1251    /// * [`GameOptionsBuilder::atlantis_olympus()`](GameOptionsBuilder::atlantis_olympus())
1252    /// * [`GameOptionsBuilder::olympus_atlantis()`](GameOptionsBuilder::olympus_atlantis())
1253    /// * [`GameOptionsBuilder::olympus_olympus()`](GameOptionsBuilder::olympus_olympus())
1254    #[must_use]
1255    pub fn build(self) -> GameOptions {
1256        match self.builder_type {
1257            GameOptionsBuilderTypes::Randomized => self.build_randomized(),
1258            GameOptionsBuilderTypes::Seeded => self.build_seeded(),
1259            GameOptionsBuilderTypes::Customized => self.build_customized(),
1260        }
1261    }
1262
1263    fn build_customized(&self) -> GameOptions {
1264        let choice_atlantis = self.choice_atlantis.unwrap_or("cooperate");
1265        let choice_olympus = self.choice_olympus.unwrap_or("defect");
1266        let atlantis_atlantis = self.atlantis_atlantis.unwrap_or(NumberPair::new(4, 4));
1267        let atlantis_olympus = self.atlantis_olympus.unwrap_or(NumberPair::new(5, 0));
1268        let olympus_atlantis = self.olympus_atlantis.unwrap_or(NumberPair::new(0, 5));
1269        let olympus_olympus = self.olympus_olympus.unwrap_or(NumberPair::new(3, 3));
1270
1271        GameOptions {
1272            choice_atlantis,
1273            choice_olympus,
1274            atlantis_atlantis,
1275            atlantis_olympus,
1276            olympus_atlantis,
1277            olympus_olympus,
1278        }
1279    }
1280
1281    fn build_seeded(&self) -> GameOptions {
1282        todo!()
1283    }
1284
1285    fn build_randomized(&self) -> GameOptions {
1286        let min_value = self.min_value.unwrap_or(1);
1287        let max_value = self.max_value.unwrap_or(10);
1288
1289        let choice_atlantis = self.choice_atlantis.unwrap_or("cooperate");
1290        let choice_olympus = self.choice_olympus.unwrap_or("defect");
1291
1292        let atlantis_atlantis = NumberPair::random(min_value, max_value);
1293        let atlantis_olympus = NumberPair::random(min_value, max_value);
1294        let olympus_atlantis = NumberPair::random(min_value, max_value);
1295        let olympus_olympus = NumberPair::random(min_value, max_value);
1296
1297        GameOptions {
1298            choice_atlantis,
1299            choice_olympus,
1300            atlantis_atlantis,
1301            atlantis_olympus,
1302            olympus_atlantis,
1303            olympus_olympus,
1304        }
1305    }
1306}
1307
1308#[cfg(test)]
1309mod tests {
1310    use super::*;
1311
1312    #[test]
1313    fn test_new() {
1314        let game_options_builder_randomized =
1315            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1316        assert_eq!(
1317            game_options_builder_randomized.builder_type,
1318            GameOptionsBuilderTypes::Randomized
1319        );
1320        let game_options_builder_seeded = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1321        assert_eq!(
1322            game_options_builder_seeded.builder_type,
1323            GameOptionsBuilderTypes::Seeded
1324        );
1325        let game_options_builder_customized =
1326            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized);
1327        assert_eq!(
1328            game_options_builder_customized.builder_type,
1329            GameOptionsBuilderTypes::Customized
1330        );
1331    }
1332
1333    #[test]
1334    fn test_min_value() {
1335        let game_options_builder_randomized =
1336            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized).min_value(1);
1337        assert!(game_options_builder_randomized.is_ok());
1338        let game_options_builder_seeded =
1339            GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).min_value(1);
1340        assert!(game_options_builder_seeded.is_ok());
1341        let game_options_builder_customized =
1342            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized).min_value(1);
1343        assert!(game_options_builder_customized.is_err());
1344    }
1345
1346    #[test]
1347    fn test_max_value() {
1348        let game_options_builder_randomized =
1349            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized).max_value(10);
1350        assert!(game_options_builder_randomized.is_ok());
1351        let game_options_builder_seeded =
1352            GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).max_value(10);
1353        assert!(game_options_builder_seeded.is_ok());
1354        let game_options_builder_customized =
1355            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized).max_value(10);
1356        assert!(game_options_builder_customized.is_err());
1357    }
1358
1359    #[test]
1360    fn test_choice_atlantis() {
1361        let game_options_builder_randomized =
1362            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1363                .choice_atlantis("cooperate");
1364        assert!(game_options_builder_randomized.is_ok());
1365        let game_options_builder_seeded =
1366            GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).choice_atlantis("cooperate");
1367        assert!(game_options_builder_seeded.is_ok());
1368        let game_options_builder_customized =
1369            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1370                .choice_atlantis("cooperate");
1371        assert!(game_options_builder_customized.is_ok());
1372    }
1373
1374    #[test]
1375    fn test_choice_olympus() {
1376        let game_options_builder_randomized =
1377            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized).choice_olympus("defect");
1378        assert!(game_options_builder_randomized.is_ok());
1379        let game_options_builder_seeded =
1380            GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).choice_olympus("defect");
1381        assert!(game_options_builder_seeded.is_ok());
1382        let game_options_builder_customized =
1383            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized).choice_olympus("defect");
1384        assert!(game_options_builder_customized.is_ok());
1385    }
1386
1387    #[test]
1388    fn test_atlantis_atlantis() {
1389        let game_options_builder_randomized =
1390            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1391                .atlantis_atlantis(NumberPair::new(1, 1));
1392        assert!(game_options_builder_randomized.is_err());
1393        let game_options_builder_seeded = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
1394            .atlantis_atlantis(NumberPair::new(1, 1));
1395        assert!(game_options_builder_seeded.is_err());
1396        let game_options_builder_customized =
1397            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1398                .atlantis_atlantis(NumberPair::new(1, 1));
1399        assert!(game_options_builder_customized.is_ok());
1400    }
1401
1402    #[test]
1403    fn test_atlantis_olympus() {
1404        let game_options_builder_randomized =
1405            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1406                .atlantis_olympus(NumberPair::new(1, 1));
1407        assert!(game_options_builder_randomized.is_err());
1408        let game_options_builder_seeded = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
1409            .atlantis_olympus(NumberPair::new(1, 1));
1410        assert!(game_options_builder_seeded.is_err());
1411        let game_options_builder_customized =
1412            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1413                .atlantis_olympus(NumberPair::new(1, 1));
1414        assert!(game_options_builder_customized.is_ok());
1415    }
1416
1417    #[test]
1418    fn test_olympus_atlantis() {
1419        let game_options_builder_randomized =
1420            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1421                .olympus_atlantis(NumberPair::new(1, 1));
1422        assert!(game_options_builder_randomized.is_err());
1423        let game_options_builder_seeded = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
1424            .olympus_atlantis(NumberPair::new(1, 1));
1425        assert!(game_options_builder_seeded.is_err());
1426        let game_options_builder_customized =
1427            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1428                .olympus_atlantis(NumberPair::new(1, 1));
1429        assert!(game_options_builder_customized.is_ok());
1430    }
1431
1432    #[test]
1433    fn test_olympus_olympus() {
1434        let game_options_builder_randomized =
1435            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized)
1436                .olympus_olympus(NumberPair::new(1, 1));
1437        assert!(game_options_builder_randomized.is_err());
1438        let game_options_builder_seeded = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded)
1439            .olympus_olympus(NumberPair::new(1, 1));
1440        assert!(game_options_builder_seeded.is_err());
1441        let game_options_builder_customized =
1442            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized)
1443                .olympus_olympus(NumberPair::new(1, 1));
1444        assert!(game_options_builder_customized.is_ok());
1445    }
1446
1447    #[test]
1448    fn test_seed() {
1449        let game_options_builder_randomized =
1450            GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized).seed(123456789);
1451        assert!(game_options_builder_randomized.is_err());
1452        let game_options_builder_seeded =
1453            GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded).seed(123456789);
1454        assert!(game_options_builder_seeded.is_ok());
1455        let game_options_builder_customized =
1456            GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized).seed(123456789);
1457        assert!(game_options_builder_customized.is_err());
1458    }
1459
1460    #[test]
1461    fn test_build_randomized() -> Result<(), BuilderError> {
1462        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1463        let builder = builder.min_value(1);
1464        assert!(builder.is_ok());
1465        let builder = builder?.max_value(10);
1466        assert!(builder.is_ok());
1467        let builder = builder?.choice_atlantis("cooperate");
1468        assert!(builder.is_ok());
1469        let builder = builder?.choice_olympus("defect");
1470        assert!(builder.is_ok());
1471        let game_options = builder?.build();
1472
1473        assert_eq!(game_options.choice_atlantis(), "cooperate");
1474        assert_eq!(game_options.choice_olympus(), "defect");
1475
1476        Ok(())
1477    }
1478
1479    #[test]
1480    #[ignore = "Seeded is not yet implemented"]
1481    fn test_build_seeded() -> Result<(), BuilderError> {
1482        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1483        let builder = builder.min_value(1);
1484        assert!(builder.is_ok());
1485        let builder = builder?.max_value(10);
1486        assert!(builder.is_ok());
1487        let builder = builder?.choice_atlantis("cooperate");
1488        assert!(builder.is_ok());
1489        let builder = builder?.choice_olympus("defect");
1490        assert!(builder.is_ok());
1491        let builder = builder?.seed(123456789);
1492        assert!(builder.is_ok());
1493        let game_options = builder?.build();
1494
1495        assert_eq!(game_options.choice_atlantis(), "cooperate");
1496        assert_eq!(game_options.choice_olympus(), "defect");
1497
1498        Ok(())
1499    }
1500
1501    #[test]
1502    fn test_build_customized() -> Result<(), BuilderError> {
1503        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized);
1504        let builder = builder.choice_atlantis("cooperate");
1505        assert!(builder.is_ok());
1506        let builder = builder?.choice_olympus("defect");
1507        assert!(builder.is_ok());
1508        let builder = builder?.atlantis_atlantis(NumberPair::new(1, 1));
1509        assert!(builder.is_ok());
1510        let builder = builder?.atlantis_olympus(NumberPair::new(1, 1));
1511        assert!(builder.is_ok());
1512        let builder = builder?.olympus_atlantis(NumberPair::new(1, 1));
1513        assert!(builder.is_ok());
1514        let builder = builder?.olympus_olympus(NumberPair::new(1, 1));
1515        assert!(builder.is_ok());
1516        let game_options = builder?.build();
1517
1518        assert_eq!(game_options.choice_atlantis(), "cooperate");
1519        assert_eq!(game_options.choice_olympus(), "defect");
1520
1521        Ok(())
1522    }
1523
1524    #[test]
1525    fn test_build_randomized_missing_min_value() {
1526        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1527        let builder = builder.max_value(10);
1528        assert!(builder.is_ok());
1529        let builder = builder.unwrap().choice_atlantis("cooperate");
1530        assert!(builder.is_ok());
1531        let builder = builder.unwrap().choice_olympus("defect");
1532        assert!(builder.is_ok());
1533        let game_options = builder.unwrap().build();
1534
1535        assert_eq!(game_options.choice_atlantis(), "cooperate");
1536        assert_eq!(game_options.choice_olympus(), "defect");
1537    }
1538
1539    #[test]
1540    fn test_build_randomized_missing_max_value() {
1541        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1542        let builder = builder.min_value(1);
1543        assert!(builder.is_ok());
1544        let builder = builder.unwrap().choice_atlantis("cooperate");
1545        assert!(builder.is_ok());
1546        let builder = builder.unwrap().choice_olympus("defect");
1547        assert!(builder.is_ok());
1548        let game_options = builder.unwrap().build();
1549
1550        assert_eq!(game_options.choice_atlantis(), "cooperate");
1551        assert_eq!(game_options.choice_olympus(), "defect");
1552    }
1553
1554    #[test]
1555    fn test_build_randomized_missing_choice_atlantis() {
1556        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1557        let builder = builder.min_value(1);
1558        assert!(builder.is_ok());
1559        let builder = builder.unwrap().max_value(10);
1560        assert!(builder.is_ok());
1561        let builder = builder.unwrap().choice_olympus("defect");
1562        assert!(builder.is_ok());
1563        let game_options = builder.unwrap().build();
1564
1565        assert_eq!(game_options.choice_atlantis(), "cooperate");
1566        assert_eq!(game_options.choice_olympus(), "defect");
1567    }
1568
1569    #[test]
1570    fn test_build_randomized_missing_choice_olympus() {
1571        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1572        let builder = builder.min_value(1);
1573        assert!(builder.is_ok());
1574        let builder = builder.unwrap().max_value(10);
1575        assert!(builder.is_ok());
1576        let builder = builder.unwrap().choice_atlantis("cooperate");
1577        assert!(builder.is_ok());
1578        let game_options = builder.unwrap().build();
1579
1580        assert_eq!(game_options.choice_atlantis(), "cooperate");
1581        assert_eq!(game_options.choice_olympus(), "defect");
1582    }
1583
1584    #[test]
1585    #[ignore = "Seeded build is not yet implemented"]
1586    fn test_build_seeded_missing_min_value() {
1587        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1588        let builder = builder.max_value(10);
1589        assert!(builder.is_ok());
1590        let builder = builder.unwrap().choice_atlantis("cooperate");
1591        assert!(builder.is_ok());
1592        let builder = builder.unwrap().choice_olympus("defect");
1593        assert!(builder.is_ok());
1594        let builder = builder.unwrap().seed(123456789);
1595        assert!(builder.is_ok());
1596        let game_options = builder.unwrap().build();
1597
1598        assert_eq!(game_options.choice_atlantis(), "cooperate");
1599        assert_eq!(game_options.choice_olympus(), "defect");
1600    }
1601
1602    #[test]
1603    #[ignore = "Seeded is not yet implemented"]
1604    fn test_build_seeded_missing_max_value() {
1605        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1606        let builder = builder.min_value(1);
1607        assert!(builder.is_ok());
1608        let builder = builder.unwrap().choice_atlantis("cooperate");
1609        assert!(builder.is_ok());
1610        let builder = builder.unwrap().choice_olympus("defect");
1611        assert!(builder.is_ok());
1612        let builder = builder.unwrap().seed(123456789);
1613        assert!(builder.is_ok());
1614        let game_options = builder.unwrap().build();
1615
1616        assert_eq!(game_options.choice_atlantis(), "cooperate");
1617        assert_eq!(game_options.choice_olympus(), "defect");
1618    }
1619
1620    #[test]
1621    #[ignore = "Seeded is not yet implemented"]
1622    fn test_build_seeded_missing_choice_atlantis() {
1623        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1624        let builder = builder.min_value(1);
1625        assert!(builder.is_ok());
1626        let builder = builder.unwrap().max_value(10);
1627        assert!(builder.is_ok());
1628        let builder = builder.unwrap().choice_olympus("defect");
1629        assert!(builder.is_ok());
1630        let builder = builder.unwrap().seed(123456789);
1631        assert!(builder.is_ok());
1632        let game_options = builder.unwrap().build();
1633
1634        assert_eq!(game_options.choice_atlantis(), "cooperate");
1635        assert_eq!(game_options.choice_olympus(), "defect");
1636    }
1637
1638    #[test]
1639    #[ignore = "Seeded is not yet implemented"]
1640    fn test_build_seeded_missing_choice_olympus() {
1641        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1642        let builder = builder.min_value(1);
1643        assert!(builder.is_ok());
1644        let builder = builder.unwrap().max_value(10);
1645        assert!(builder.is_ok());
1646        let builder = builder.unwrap().choice_atlantis("cooperate");
1647        assert!(builder.is_ok());
1648        let builder = builder.unwrap().seed(123456789);
1649        assert!(builder.is_ok());
1650        let game_options = builder.unwrap().build();
1651
1652        assert_eq!(game_options.choice_atlantis(), "cooperate");
1653        assert_eq!(game_options.choice_olympus(), "defect");
1654    }
1655
1656    #[test]
1657    #[ignore = "Seeded is not yet implemented"]
1658    fn test_build_seeded_missing_seed() {
1659        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1660        let builder = builder.min_value(1);
1661        assert!(builder.is_ok());
1662        let builder = builder.unwrap().max_value(10);
1663        assert!(builder.is_ok());
1664        let builder = builder.unwrap().choice_atlantis("cooperate");
1665        assert!(builder.is_ok());
1666        let builder = builder.unwrap().choice_olympus("defect");
1667        assert!(builder.is_ok());
1668        let game_options = builder.unwrap().build();
1669
1670        assert_eq!(game_options.choice_atlantis(), "cooperate");
1671        assert_eq!(game_options.choice_olympus(), "defect");
1672    }
1673
1674    #[test]
1675    #[should_panic]
1676    fn test_build_randomized_seed_panic() {
1677        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1678        let builder = builder.seed(123456789);
1679        assert!(builder.is_err());
1680        builder.unwrap();
1681    }
1682
1683    #[test]
1684    #[should_panic]
1685    fn test_build_randomized_atlantis_atlantis_panic() {
1686        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1687        let builder = builder.atlantis_atlantis(NumberPair::new(1, 1));
1688        assert!(builder.is_err());
1689        builder.unwrap();
1690    }
1691
1692    #[test]
1693    #[should_panic]
1694    fn test_build_randomized_atlantis_olympus_panic() {
1695        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1696        let builder = builder.atlantis_olympus(NumberPair::new(1, 1));
1697        assert!(builder.is_err());
1698        builder.unwrap();
1699    }
1700
1701    #[test]
1702    #[should_panic]
1703    fn test_build_randomized_olympus_atlantis_panic() {
1704        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1705        let builder = builder.olympus_atlantis(NumberPair::new(1, 1));
1706        assert!(builder.is_err());
1707        builder.unwrap();
1708    }
1709
1710    #[test]
1711    #[should_panic]
1712    fn test_build_randomized_olympus_olympus_panic() {
1713        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Randomized);
1714        let builder = builder.olympus_olympus(NumberPair::new(1, 1));
1715        assert!(builder.is_err());
1716        builder.unwrap();
1717    }
1718
1719    #[test]
1720    #[should_panic]
1721    fn test_build_seeded_atlantis_atlantis_panic() {
1722        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1723        let builder = builder.atlantis_atlantis(NumberPair::new(1, 1));
1724        assert!(builder.is_err());
1725        builder.unwrap();
1726    }
1727
1728    #[test]
1729    #[should_panic]
1730    fn test_build_seeded_atlantis_olympus_panic() {
1731        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1732        let builder = builder.atlantis_olympus(NumberPair::new(1, 1));
1733        assert!(builder.is_err());
1734        builder.unwrap();
1735    }
1736
1737    #[test]
1738    #[should_panic]
1739    fn test_build_seeded_olympus_atlantis_panic() {
1740        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1741        let builder = builder.olympus_atlantis(NumberPair::new(1, 1));
1742        assert!(builder.is_err());
1743        builder.unwrap();
1744    }
1745
1746    #[test]
1747    #[should_panic]
1748    fn test_build_seeded_olympus_olympus_panic() {
1749        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Seeded);
1750        let builder = builder.olympus_olympus(NumberPair::new(1, 1));
1751        assert!(builder.is_err());
1752        builder.unwrap();
1753    }
1754
1755    #[test]
1756    #[should_panic]
1757    fn test_build_customized_seed_panic() {
1758        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized);
1759        let builder = builder.seed(123456789);
1760        assert!(builder.is_err());
1761        builder.unwrap();
1762    }
1763
1764    #[test]
1765    #[should_panic]
1766    fn test_build_customized_min_value_panic() {
1767        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized);
1768        let builder = builder.min_value(1);
1769        assert!(builder.is_err());
1770        builder.unwrap();
1771    }
1772
1773    #[test]
1774    #[should_panic]
1775    fn test_build_customized_max_value_panic() {
1776        let builder = GameOptionsBuilder::new(GameOptionsBuilderTypes::Customized);
1777        let builder = builder.max_value(10);
1778        assert!(builder.is_err());
1779        builder.unwrap();
1780    }
1781}