commit 9694bbbef692604edc6de281a49da4dd63cada51 Author: neo Date: Thu Aug 22 02:09:53 2024 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d8a2a87 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,197 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_rust" +version = "0.1.0" +dependencies = [ + "rand", + "termion", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] + +[[package]] +name = "numtoa" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_termios" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb" + +[[package]] +name = "syn" +version = "2.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termion" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4648c7def6f2043b2568617b9f9b75eae88ca185dbc1f1fda30e95a85d49d7d" +dependencies = [ + "libc", + "libredox", + "numtoa", + "redox_termios", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..330f240 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_rust" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.5" +termion = "2.0.1" diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ce15a3f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,164 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io::{self, Write}; +use std::time::Instant; +use termion::{color, style}; + +// Define difficulty levels +enum Difficulty { + Easy, + Medium, + Hard, +} + +// Define game state +struct GameState { + secret_number: u32, + attempts: u32, + max_attempts: u32, + score: u32, + start_time: Instant, + difficulty: Difficulty, +} + +impl GameState { + fn new(difficulty: Difficulty) -> Self { + let (range, max_attempts) = match difficulty { + Difficulty::Easy => (1..=50, 10), + Difficulty::Medium => (1..=100, 7), + Difficulty::Hard => (1..=200, 5), + }; + + GameState { + secret_number: rand::thread_rng().gen_range(range), + attempts: 0, + max_attempts, + score: 1000, + start_time: Instant::now(), + difficulty, + } + } + + fn make_guess(&mut self, guess: u32) -> Ordering { + self.attempts += 1; + self.score = self.score.saturating_sub(50); // Deduct points for each attempt + guess.cmp(&self.secret_number) + } + + fn is_game_over(&self) -> bool { + self.attempts >= self.max_attempts + } + + fn calculate_final_score(&self) -> u32 { + let time_bonus = match self.difficulty { + Difficulty::Easy => 5, + Difficulty::Medium => 10, + Difficulty::Hard => 20, + }; + let time_taken = self.start_time.elapsed().as_secs(); + self.score + .saturating_add(time_bonus * (60u32.saturating_sub(time_taken as u32))) + } +} + +fn get_difficulty() -> Difficulty { + loop { + println!("Choose difficulty:"); + println!("1. Easy (1-50, 10 attempts)"); + println!("2. Medium (1-100, 7 attempts)"); + println!("3. Hard (1-200, 5 attempts)"); + print!("Enter your choice (1-3): "); + io::stdout().flush().unwrap(); + + let mut choice = String::new(); + io::stdin() + .read_line(&mut choice) + .expect("Failed to read line"); + match choice.trim() { + "1" => return Difficulty::Easy, + "2" => return Difficulty::Medium, + "3" => return Difficulty::Hard, + _ => println!("Invalid choice, please try again."), + } + } +} + +fn play_game(mut game: GameState) -> bool { + println!("{}{}Guess the number!", color::Fg(color::Blue), style::Bold); + println!( + "You have {} attempts. Good luck!{}", + game.max_attempts, + style::Reset + ); + + while !game.is_game_over() { + print!( + "{}Attempt {}/{}: ", + color::Fg(color::Green), + game.attempts + 1, + game.max_attempts + ); + io::stdout().flush().unwrap(); + + let mut guess = String::new(); + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + let guess: u32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => { + println!( + "{}Please enter a valid number!{}", + color::Fg(color::Red), + style::Reset + ); + continue; + } + }; + + match game.make_guess(guess) { + Ordering::Less => println!("{}Too small!{}", color::Fg(color::Yellow), style::Reset), + Ordering::Greater => println!("{}Too big!{}", color::Fg(color::Yellow), style::Reset), + Ordering::Equal => { + println!( + "{}{}You win!{}", + color::Fg(color::Green), + style::Bold, + style::Reset + ); + println!("Final score: {}", game.calculate_final_score()); + return true; + } + } + + println!("Current score: {}", game.score); + } + + println!( + "{}{}Game over! You've run out of attempts.{}", + color::Fg(color::Red), + style::Bold, + style::Reset + ); + println!("The secret number was: {}", game.secret_number); + false +} + +fn main() { + loop { + let difficulty = get_difficulty(); + let game = GameState::new(difficulty); + play_game(game); + + print!("{}Play again? (y/n): ", color::Fg(color::Blue)); + io::stdout().flush().unwrap(); + let mut play_again = String::new(); + io::stdin() + .read_line(&mut play_again) + .expect("Failed to read line"); + if play_again.trim().to_lowercase() != "y" { + break; + } + } + println!("Thanks for playing!"); +}