From 65ce38321377aaffa12fa1acf5e2a7790100e836 Mon Sep 17 00:00:00 2001 From: alingse Date: Sat, 4 Jun 2022 01:57:49 +0800 Subject: [PATCH 1/2] add 36 play even number game --- 35_Even_Wins/rust/Cargo.toml | 8 ++ 35_Even_Wins/rust/src/main.rs | 232 ++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 35_Even_Wins/rust/Cargo.toml create mode 100644 35_Even_Wins/rust/src/main.rs diff --git a/35_Even_Wins/rust/Cargo.toml b/35_Even_Wins/rust/Cargo.toml new file mode 100644 index 00000000..1ec69633 --- /dev/null +++ b/35_Even_Wins/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/35_Even_Wins/rust/src/main.rs b/35_Even_Wins/rust/src/main.rs new file mode 100644 index 00000000..52a2da31 --- /dev/null +++ b/35_Even_Wins/rust/src/main.rs @@ -0,0 +1,232 @@ +use std::io; + +fn print_intro() { + println!( + "Welcome to Even Wins! +Based on evenwins.bas from Creative Computing + +Even Wins is a two-person game. You start with +27 marbles in the middle of the table. + +Players alternate taking marbles from the middle. +A player can take 1 to 4 marbles on their turn, and +turns cannot be skipped. The game ends when there are +no marbles left, and the winner is the one with an even +number of marbles. +" + ); +} + +#[derive(Debug)] +enum PlayerType { + Human, + Computer, +} + +#[derive(Debug)] +struct Game { + turn: PlayerType, + middle: u32, + human: u32, + computer: u32, + min_take: u32, + max_take: u32, +} + +impl Game { + fn get_max_take(&mut self) -> u32 { + if self.max_take > self.middle { + return self.middle; + } + return self.max_take; + } + + fn take(&mut self, num: u32) -> bool { + if num > self.max_take { + println!("You can take at most {} marbles", self.max_take); + return false; + } + if num > self.middle { + println!("You can take at most {} marbles", self.middle); + return false; + } + if num < self.min_take { + println!("You must take at least {} marble!", self.min_take); + return false; + } + + self.middle -= num; + match self.turn { + PlayerType::Computer => self.computer += num, + PlayerType::Human => self.human += num, + } + return true; + } + + fn next(&mut self) { + self.turn = match self.turn { + PlayerType::Computer => PlayerType::Human, + PlayerType::Human => PlayerType::Computer, + } + } + + fn info(&mut self) { + println!(""); + println!( + "marbles in the middle: {} **************************", + self.middle + ); + println!("# marbles you have: {}", self.human); + println!("# marbles computer has: {}", self.computer); + println!(""); + } + + fn wininfo(&mut self) { + if self.middle != 0 { + return; + } + println!("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!! All the marbles are taken: Game Over!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + self.info(); + + if self.human % 2 == 0 { + println!("You are the winner! Congratulations!"); + } else { + println!("The computer wins: all hail mighty silicon!"); + } + + println!(""); + } +} + +fn human_play(game: &mut Game) { + println!("It's your turn!"); + loop { + let max_take = game.get_max_take(); + println!("Marbles to take? ({} - {}) --> ", game.min_take, max_take); + + let mut num = String::new(); + io::stdin() + .read_line(&mut num) + .expect("Failed to read line"); + + let _: u32 = match num.trim().to_uppercase().parse() { + Ok(num) => { + if game.take(num) { + println!("Okay, taking {} marble ...", num); + break; + }; + println!(""); + continue; + } + _ => { + println!("Please enter a whole number from 1 to 4"); + println!(""); + continue; + } + }; + } +} + +fn compute_play(game: &mut Game) { + println!("It's the computer's turn ..."); + + let mut marbles_to_take: u32 = 0; + + // the magic 6 and 1.5, 5.3 3.4 4.7 3.5 was copy from python implement + let r: f32 = (game.middle % 6) as f32; + if game.human % 2 == 0 { + if r < 1.5 || r > 5.3 { + marbles_to_take = 1; + } else { + marbles_to_take = (r - 1.0) as u32; + } + } else if game.middle <= 4 { + marbles_to_take = game.middle + } else if r > 3.4 { + if r < 4.7 || r > 3.5 { + marbles_to_take = 4; + } else { + marbles_to_take = 1; + } + } else { + marbles_to_take = (r + 1.0) as u32; + } + + game.take(marbles_to_take); + println!("Computer takes {} marble ...", marbles_to_take); +} + +fn run_game(turn: PlayerType) { + let mut game = Game { + turn: turn, + middle: 27, + computer: 0, + human: 0, + min_take: 1, + max_take: 4, + }; + + while game.middle > 0 { + match game.turn { + PlayerType::Computer => { + compute_play(&mut game); + } + PlayerType::Human => { + human_play(&mut game); + } + } + game.info(); + game.next(); + } + game.wininfo(); +} + +fn choose_first_player() -> PlayerType { + loop { + println!("Do you want to play first? (y/n) -->"); + + let mut flag = String::new(); + io::stdin() + .read_line(&mut flag) + .expect("Failed to read line"); + + match flag.trim().to_uppercase().as_str() { + "Y" => return PlayerType::Human, + "N" => return PlayerType::Computer, + _ => { + println!("Please enter \"y\" if you want to play first,\nor \"n\" if you want to play second.\n"); + } + }; + } +} + +fn choose_play_again() -> bool { + println!("Would you like to play again? (y/n) --> "); + let mut flag = String::new(); + io::stdin() + .read_line(&mut flag) + .expect("Failed to read line"); + + match flag.trim().to_uppercase().as_str() { + "Y" => { + println!("\nOk, let's play again ...\n"); + return true; + } + _ => { + println!("\nOk, thanks for playing ... goodbye!\n"); + return false; + } + } +} + +fn main() { + print_intro(); + loop { + let first = choose_first_player(); + run_game(first); + + if !choose_play_again() { + return; + } + } +} From e6c25377802b07ef6e577c120017cd246a90d504 Mon Sep 17 00:00:00 2001 From: alingse Date: Sat, 4 Jun 2022 02:04:24 +0800 Subject: [PATCH 2/2] fix warning --- 35_Even_Wins/rust/src/main.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/35_Even_Wins/rust/src/main.rs b/35_Even_Wins/rust/src/main.rs index 52a2da31..18a08a3a 100644 --- a/35_Even_Wins/rust/src/main.rs +++ b/35_Even_Wins/rust/src/main.rs @@ -42,12 +42,9 @@ impl Game { } fn take(&mut self, num: u32) -> bool { - if num > self.max_take { - println!("You can take at most {} marbles", self.max_take); - return false; - } - if num > self.middle { - println!("You can take at most {} marbles", self.middle); + let max_take = self.get_max_take(); + if num > max_take { + println!("You can take at most {} marbles", max_take); return false; } if num < self.min_take { @@ -130,7 +127,7 @@ fn human_play(game: &mut Game) { fn compute_play(game: &mut Game) { println!("It's the computer's turn ..."); - let mut marbles_to_take: u32 = 0; + let marbles_to_take: u32; // the magic 6 and 1.5, 5.3 3.4 4.7 3.5 was copy from python implement let r: f32 = (game.middle % 6) as f32;