Created
January 2, 2025 01:38
-
-
Save BSN4/a624be23f49c9d1ee9545808d916af24 to your computer and use it in GitHub Desktop.
rock_paper_rust v1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use rand::Rng; | |
use std::io::{self, Write}; | |
#[derive(Debug)] | |
struct Score { | |
player: u32, | |
computer: u32, | |
} | |
#[derive(Debug, PartialEq, Clone)] | |
enum Move { | |
Rock, | |
Paper, | |
Scissors, | |
} | |
enum GameResult { | |
PlayerWins(Move, Move), | |
ComputerWins(Move, Move), | |
Draw(Move), | |
} | |
fn main() { | |
play(); | |
} | |
fn play() { | |
let mut score = Score { | |
player: 0, | |
computer: 0, | |
}; | |
for round in 1..=3 { | |
println!("\nRound {}", round); | |
play_round(&mut score); | |
} | |
announce_winner(&score); | |
maybe_play_again(); | |
} | |
fn play_round(score: &mut Score) { | |
match get_player_move() { | |
Ok(player_move) => { | |
let computer_move = random_move(); | |
println!("Computer chose: {}", move_to_str(&computer_move)); | |
let result = determine_winner(&player_move, &computer_move); | |
println!("{}", format_result(&result)); | |
update_score(&result, score); | |
} | |
Err(msg) => { | |
println!("{}", msg); | |
play_round(score); | |
} | |
} | |
} | |
fn get_player_move() -> Result<Move, &'static str> { | |
print!("Enter your move (rock/paper/scissors): "); | |
io::stdout().flush().unwrap(); | |
let mut input = String::new(); | |
io::stdin() | |
.read_line(&mut input) | |
.map_err(|_| "Failed to read input")?; | |
parse_move(&input) | |
} | |
fn parse_move(input: &str) -> Result<Move, &'static str> { | |
match input.trim().to_lowercase().as_str() { | |
"rock" => Ok(Move::Rock), | |
"paper" => Ok(Move::Paper), | |
"scissors" => Ok(Move::Scissors), | |
_ => Err("Invalid move. Please enter rock, paper, or scissors."), | |
} | |
} | |
fn move_to_str(move_: &Move) -> &'static str { | |
match move_ { | |
Move::Rock => "rock", | |
Move::Paper => "paper", | |
Move::Scissors => "scissors", | |
} | |
} | |
fn random_move() -> Move { | |
match rand::thread_rng().gen_range(0..3) { | |
0 => Move::Rock, | |
1 => Move::Paper, | |
_ => Move::Scissors, | |
} | |
} | |
fn determine_winner(player: &Move, computer: &Move) -> GameResult { | |
match (player, computer) { | |
(Move::Rock, Move::Scissors) => GameResult::PlayerWins(Move::Rock, Move::Scissors), | |
(Move::Paper, Move::Rock) => GameResult::PlayerWins(Move::Paper, Move::Rock), | |
(Move::Scissors, Move::Paper) => GameResult::PlayerWins(Move::Scissors, Move::Paper), | |
(p, c) if p == c => GameResult::Draw(p.clone()), | |
(p, c) => GameResult::ComputerWins(c.clone(), p.clone()), | |
} | |
} | |
fn format_result(result: &GameResult) -> String { | |
match result { | |
GameResult::PlayerWins(threw, beat) => { | |
format!( | |
"You won by throwing {} against {}", | |
move_to_str(threw), | |
move_to_str(beat) | |
) | |
} | |
GameResult::ComputerWins(threw, beat) => { | |
format!( | |
"Computer won by throwing {} against {}", | |
move_to_str(threw), | |
move_to_str(beat) | |
) | |
} | |
GameResult::Draw(move_) => { | |
format!("Draw! Both players threw {}", move_to_str(move_)) | |
} | |
} | |
} | |
fn update_score(result: &GameResult, score: &mut Score) { | |
match result { | |
GameResult::PlayerWins(_, _) => score.player += 1, | |
GameResult::ComputerWins(_, _) => score.computer += 1, | |
GameResult::Draw(_) => (), | |
} | |
} | |
fn announce_winner(score: &Score) { | |
println!( | |
"\nFinal Score - You: {}, Computer: {}", | |
score.player, score.computer | |
); | |
let result = if score.player > score.computer { | |
"You win the series!" | |
} else if score.player < score.computer { | |
"Computer wins the series!" | |
} else { | |
"The series is a draw!" | |
}; | |
println!("{}", result); | |
} | |
fn maybe_play_again() { | |
print!("\nPlay again? (y/n): "); | |
io::stdout().flush().unwrap(); | |
let mut input = String::new(); | |
match io::stdin().read_line(&mut input) { | |
Ok(_) => { | |
if input.trim().to_lowercase() == "y" { | |
play(); | |
} else { | |
println!("Thanks for playing!"); | |
} | |
} | |
Err(_) => println!("Error reading input. Game ended."), | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment