mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-21 23:00:43 -08:00
Add Rust port of 05_Bagels
This commit is contained in:
9
05_Bagels/rust/Cargo.toml
Normal file
9
05_Bagels/rust/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[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]
|
||||
rand = "0.8.5"
|
||||
3
05_Bagels/rust/README.md
Normal file
3
05_Bagels/rust/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
|
||||
|
||||
Conversion to [Rust](https://www.rust-lang.org/) by Till Klister [tikste@github](https://github.com/tikste).
|
||||
131
05_Bagels/rust/src/main.rs
Normal file
131
05_Bagels/rust/src/main.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use std::io;
|
||||
use std::io::{stdin, stdout, Write};
|
||||
|
||||
use rand::prelude::SliceRandom;
|
||||
|
||||
type Digits = [u8; 3];
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
print_header();
|
||||
if !read_lowercase_input()?.starts_with('n') {
|
||||
print_rules();
|
||||
}
|
||||
let mut win_count = 0;
|
||||
loop {
|
||||
let solution = generate_random_digits();
|
||||
println!("\nO.K. I have a number in mind.");
|
||||
if guess(solution)? {
|
||||
win_count += 1;
|
||||
println!("You got it!!!");
|
||||
} else {
|
||||
println!(
|
||||
"\nOh well\nThat's twenty guesses: My number was {}{}{}",
|
||||
solution[0], solution[1], solution[2]
|
||||
);
|
||||
}
|
||||
println!("\nPlay again (yes or no)?");
|
||||
if read_lowercase_input()? != "yes" {
|
||||
println!();
|
||||
if win_count > 0 {
|
||||
println!("A {win_count} point bagels buff!!");
|
||||
}
|
||||
println!("Hope you had fun. Bye.");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_header() {
|
||||
println!(" Bagels");
|
||||
println!("Creative-Computing Morristown, New Jersey");
|
||||
println!();
|
||||
println!("Would you like the rules (yes or no)?");
|
||||
}
|
||||
|
||||
fn print_rules() {
|
||||
println!();
|
||||
println!("I am thinking of a three-digit number. Try to guess");
|
||||
println!("my number and I will give you clues as follows:");
|
||||
println!(" Pico - one digit correct but in the wrong position");
|
||||
println!(" Fermi - one digit correct and in the right position");
|
||||
println!(" Bagles - no digits correct");
|
||||
}
|
||||
|
||||
fn read_lowercase_input() -> io::Result<String> {
|
||||
let mut input = String::new();
|
||||
stdin().read_line(&mut input)?;
|
||||
Ok(input.trim().to_lowercase())
|
||||
}
|
||||
|
||||
fn generate_random_digits() -> Digits {
|
||||
let range = 0..10;
|
||||
let mut numbers = range.into_iter().collect::<Vec<u8>>();
|
||||
numbers.shuffle(&mut rand::thread_rng());
|
||||
let mut digits = Digits::default();
|
||||
let len = digits.len();
|
||||
digits.copy_from_slice(&numbers[..len]);
|
||||
digits
|
||||
}
|
||||
|
||||
fn guess(solution: Digits) -> io::Result<bool> {
|
||||
for round in 1..21 {
|
||||
let guess = read_valid_guess(round)?;
|
||||
if guess == solution {
|
||||
return Ok(true);
|
||||
} else {
|
||||
let mut pico = 0;
|
||||
let mut fermi = 0;
|
||||
for i in 0..guess.len() {
|
||||
if guess[i] == solution[i] {
|
||||
fermi += 1;
|
||||
} else if solution.contains(&guess[i]) {
|
||||
pico += 1;
|
||||
}
|
||||
}
|
||||
let mut status = String::new();
|
||||
if pico == 0 && fermi == 0 {
|
||||
status += "Bagels";
|
||||
} else {
|
||||
for _ in 0..pico {
|
||||
status += "Pico ";
|
||||
}
|
||||
for _ in 0..fermi {
|
||||
status += "Fermi ";
|
||||
}
|
||||
};
|
||||
println!("{}", status.trim_end());
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn read_valid_guess(round: u8) -> io::Result<Digits> {
|
||||
let mut guess = Digits::default();
|
||||
loop {
|
||||
let space = " ".repeat(if round < 10 { 5 } else { 4 });
|
||||
print!("Guess #{round}{space}? ");
|
||||
stdout().flush()?;
|
||||
let input = read_lowercase_input()?;
|
||||
if input.len() == guess.len() {
|
||||
let mut i = 0;
|
||||
for c in input.chars() {
|
||||
if let Ok(digit) = c.to_string().parse::<u8>() {
|
||||
if guess[..i].contains(&digit) {
|
||||
println!("\nOh, I forgot to tell you that the number I have in mind\nhas no two digits the same.");
|
||||
break;
|
||||
}
|
||||
guess[i] = digit;
|
||||
i += 1;
|
||||
if i == guess.len() {
|
||||
return Ok(guess);
|
||||
}
|
||||
} else {
|
||||
println!("What?");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Try guessing a three-digit number.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user