Skip to main content

GameSettings

Struct GameSettings 

Source
pub struct GameSettings {
    pub first_to: u8,
}
Expand description

§GameSettings Struct

The GameSettings struct provides a simple yet flexible mechanism to configure the win conditions for a “Rock, Paper, Scissors” game session. It allows developers to define the number of wins required to declare an overall game winner.

§Fields

  • from_first_to
    • Specifies the number of round wins required for either the user or opponent to win the game.
    • This value defaults to 0 when initializing using GameSettings::new().

§Methods

§GameSettings::new()

Creates a new GameSettings instance with from_first_to set to 0. This can act as a placeholder until specific settings are defined.

use rock_paper_scissors::GameSettings;

let game_settings = GameSettings::new();
assert_eq!(game_settings.first_to, 1);

§GameSettings::first_to_3()

Provides a predefined configuration where the game is set to end after 3 wins from either the user or the opponent.

use rock_paper_scissors::GameSettings;

let game_settings = GameSettings::from_first_to(3);
assert_eq!(game_settings.first_to, 3);

§Examples

§Using Custom Win Conditions

Developers can define their own win conditions by directly instantiating the GameSettings struct:

use rock_paper_scissors::GameSettings;

let custom_game_settings = GameSettings {
    first_to: 5,
};

assert_eq!(custom_game_settings.first_to, 5);

§Combining with Scores

The GameSettings struct is designed to work seamlessly with the Scores struct to determine if a game session has reached its end:

use rock_paper_scissors::{Scores, GameSettings, Winner};

let game_settings = GameSettings::from_first_to(3);
let mut scores = Scores::new();

// Simulate some rounds
scores.user_wins = 3;

// Check for game winner
let winner = scores.check_for_winner(&game_settings);
assert_eq!(winner, Ok(Winner::User));

Fields§

§first_to: u8

Implementations§

Source§

impl GameSettings

Source

pub fn new() -> GameSettings

Creates a new game configuration with the default from_first_to value of 1.

§Examples
use rock_paper_scissors::GameSettings;

let settings = GameSettings::new();
assert_eq!(settings.first_to, 1);
Source

pub fn from_user_input() -> Result<GameSettings, &'static str>

The from_user_input method allows users to customize the game settings by providing input for the first_to win condition. The number entered defines how many victories are required to declare a winner in the game session.

§Description
  • This function prompts the user to input a number (representing the target win count).
  • It validates the input to ensure it’s a valid positive integer (u8).
  • If the input is valid, it returns a GameSettings instance with the first_to property set to the input value.
  • In case of invalid input, such as non-numeric values or parsing errors, it returns an error message.
§Behavior
  • Reads a line of input from the console.
  • Tries to parse the trimmed input into a u8 number.
  • If parsing succeeds:
    • The parsed number is assigned to the first_to field of the GameSettings struct.
    • Returns Ok(GameSettings).
  • If parsing fails:
    • Returns an error with a descriptive message (e.g., "Invalid input. Please enter a number.").
§Use Case

This method is designed to make game initialization interactive by letting users define the win condition directly from the console. For example, users can adjust how many game rounds they need to win to end the game.

§Examples
§Correct Input

When valid input is provided:

use rock_paper_scissors::GameSettings;

// Simulating valid user input:
// Let's say user enters "5" (first to 5 wins).
// let game_settings = GameSettings::from_user_input();
// returns the following:
let game_settings: Result<GameSettings, &'static str> = Ok(GameSettings {
    first_to: 5,
});
match game_settings {
    Ok(settings) => assert_eq!(settings.first_to, 5),
    Err(_) => panic!("This should not happen for valid input"),
}
§Invalid Input

Example of invalid

Examples found in repository?
examples/configurable.rs (line 10)
3fn main() {
4    let mut scores = Scores::new();
5
6    println!("Welcome to the Rock-Paper-Scissors game!");
7    println!("Please enter what you want to play to: ");
8
9    let game_settings = loop {
10        match GameSettings::from_user_input() {
11            Ok(game_settings) => break game_settings,
12            Err(err) => println!("Error: {}", err),
13        }
14    };
15
16    println!();
17    let mut round_counter = 0;
18    while scores.check_for_winner(&game_settings).is_err() {
19        round_counter += 1;
20        println!("Round {}:", round_counter);
21        let player_moves = PlayerMoves::build_from_input();
22        println!();
23        println!("User: {}", player_moves.user_move.convert_to_string());
24        println!("Enemy: {}", player_moves.enemy_move.convert_to_string());
25
26        let round_winner = player_moves.check_who_wins_round();
27        println!();
28        match round_winner {
29            Winner::Tie => {
30                println!("Tie!");
31                round_counter -= 1
32            },
33            Winner::User => {
34                println!("User win");
35                scores.user_wins += 1;
36            },
37            Winner::Enemy => {
38                println!("Enemy win");
39                scores.enemy_wins += 1;
40            }
41        }
42
43        println!("Current Scores -> User: {} :: Enemy: {}", scores.user_wins, scores.enemy_wins);
44    }
45
46    let game_winner = scores.check_for_winner(&game_settings).unwrap(); // can use unwrap here because the while loop
47    // will only break if the return is Ok()
48
49
50    println!("Game Winner: {}", game_winner.convert_to_string());
51}
Source

pub fn from_first_to(first_to: u8) -> GameSettings

Prebuilt configuration where the first player to win 3 rounds is declared the winner.

§Examples
use rock_paper_scissors::GameSettings;

let settings = GameSettings::from_first_to(3);
assert_eq!(settings.first_to, 3);
Examples found in repository?
examples/interactive.rs (line 6)
3fn main() {
4    let mut scores = Scores::new();
5
6    let game_settings = GameSettings::from_first_to(3);
7
8    println!("Welcome to Rock-Paper-Scissors!");
9
10    // Game loop
11    while scores.check_for_winner(&game_settings).is_err() {
12        let player_moves = PlayerMoves::build_from_input();
13
14        let round_winner = player_moves.check_who_wins_round();
15        println!(
16            "You chose {}. Enemy chose {}.",
17            player_moves.user_move.convert_to_string(),
18            player_moves.enemy_move.convert_to_string(),
19        );
20        println!("Result: {}", round_winner.convert_to_string());
21
22        // Update scores
23        match round_winner {
24            Winner::User => scores.user_wins += 1,
25            Winner::Enemy => scores.enemy_wins += 1,
26            Winner::Tie => (),
27        }
28
29        println!(
30            "Current Scores -> You: {}, Enemy: {}",
31            scores.user_wins, scores.enemy_wins
32        );
33    }
34
35    // Display final results
36    let game_winner = scores.check_for_winner(&game_settings).unwrap();
37    println!("Game over! {}", game_winner.convert_to_string());
38}
More examples
Hide additional examples
examples/loop.rs (line 5)
4fn main() {
5    let game_settings = GameSettings::from_first_to(3);
6
7    let mut scores = Scores::new();
8
9    let mut round_counter = 0;
10
11    loop {
12        round_counter += 1;
13        let player_moves = PlayerMoves::build_from_input();
14
15        let winner = player_moves.check_who_wins_round();
16
17        match winner {
18            Winner::User => {
19                scores.user_wins += 1;
20                println!("User wins round {}", round_counter)
21
22            },
23            Winner::Enemy => {
24                scores.enemy_wins += 1;
25                println!("Enemy wins round {}", round_counter)
26            },
27            Winner::Tie => {
28                println!("It's a tie! Replaying round {}...", round_counter);
29                round_counter -= 1;
30            },
31        }
32
33        if let Ok(winner) = scores.check_for_winner(&game_settings) {
34            println!("Game Over! Winner: {}", winner.convert_to_string());
35            println!();
36            println!("Final Scores:");
37            println!("    User: {}", scores.user_wins);
38            println!("    Enemy: {}", scores.enemy_wins);
39            break;
40        }
41    }
42}
examples/colored.rs (line 8)
4fn main() {
5    println!("{}", "Welcome to rock paper scissors!".blue().bold());
6
7    // create game_settings struct with 3.
8    let game_settings = GameSettings::from_first_to(3);
9
10    println!("{}", "Game will be first to 3 rounds.".blue().bold());
11
12    let mut scores = Scores::new(); // instantiate Scores struct
13
14    let mut round_counter = 0;
15
16    while scores.check_for_winner(&game_settings).is_err() { // checking to see if there has been a winner yet.
17        round_counter += 1;
18        let player_moves = PlayerMoves::build_from_input(); // build a PlayerMoves struct from input
19        let round_winner = player_moves.check_who_wins_round(); // check who wins round based on moves.
20
21        println!(
22            "{}{}{}",
23            "-----Round ".magenta(),
24            round_counter.to_string().magenta(),
25            "-----".magenta()
26        );
27
28        println!(
29            "{}{}{}{}{}",
30            "User: ".italic(),
31            player_moves.user_move.convert_to_string().italic(),
32            " :: ".italic(),
33            "Enemy: ".italic(),
34            player_moves.enemy_move.convert_to_string().italic()
35        );
36
37
38        match round_winner {
39            Winner::Tie => {
40                println!("{}", "It's a tie!".blue());
41                round_counter -= 1;
42            },
43            Winner::User => {
44                println!("{}", "You win!".green());
45                scores.user_wins += 1;
46            },
47            Winner::Enemy => {
48                println!("{}", "Enemy wins!".red());
49                scores.enemy_wins += 1;
50            }
51        }
52
53        // print scores
54        println!("{}", "[Scores]".magenta().bold());
55        println!("{}{}", "User: ".magenta(), scores.user_wins.to_string().magenta());
56        println!("{}{}", "Enemy: ".magenta(), scores.enemy_wins.to_string().magenta());
57    }
58
59
60    if scores.check_for_winner(&game_settings) == Ok(Winner::User) {
61        println!("{}", "You won the game!".green());
62    } else {
63        println!("{}", "You lost the game!".red());
64    }
65
66}

Trait Implementations§

Source§

impl Debug for GameSettings

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for GameSettings

Source§

fn eq(&self, other: &GameSettings) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for GameSettings

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V