use std::io; use rand::{Rng,thread_rng}; extern crate rand; const NUMBER_OF_DIGITS: usize = 4; static DIGITS: [char; 9] = ['1', '2', '3', '4', '5', '6', '7', '8', '9']; fn generate_digits() -> Vec { let mut temp_digits: Vec<_> = (&DIGITS[..]).into(); thread_rng().shuffle(&mut temp_digits); return temp_digits.iter().take(NUMBER_OF_DIGITS).map(|&a| a).collect(); } fn parse_guess_string(guess: &str) -> Result, String> { let chars: Vec = (&guess).chars().collect(); if !chars.iter().all(|c| DIGITS.contains(c)) { return Err("only digits, please".to_string()); } if chars.len() != NUMBER_OF_DIGITS { return Err(format!("you need to guess with {} digits", NUMBER_OF_DIGITS)); } let mut uniques: Vec = chars.clone(); uniques.dedup(); if uniques.len() != chars.len() { return Err("no duplicates, please".to_string()); } return Ok(chars); } fn calculate_score(given_digits: &[char], guessed_digits: &[char]) -> (usize, usize) { let mut bulls = 0; let mut cows = 0; for i in 0..NUMBER_OF_DIGITS { let pos: Option = guessed_digits.iter().position(|&a| -> bool {a == given_digits[i]}); match pos { None => (), Some(p) if p == i => bulls += 1, Some(_) => cows += 1 } } return (bulls, cows); } fn main() { let reader = io::stdin(); loop { let given_digits = generate_digits(); println!("I have chosen my {} digits. Please guess what they are", NUMBER_OF_DIGITS); loop { let guess_string: String = { let mut buf = String::new(); reader.read_line(&mut buf).unwrap(); buf.trim().into() }; let digits_maybe = parse_guess_string(&guess_string); match digits_maybe { Err(msg) => { println!("{}", msg); continue; }, Ok(guess_digits) => { match calculate_score(&given_digits, &guess_digits) { (NUMBER_OF_DIGITS, _) => { println!("you win!"); break; }, (bulls, cows) => println!("bulls: {}, cows: {}", bulls, cows) } } } } } }