mastermind/
lib.rs

1#![allow(dead_code, unused_imports, unused_variables, unused_must_use)]
2
3extern crate rand;
4
5mod color;
6mod peg;
7
8pub use color::Color;
9use rand::Rng;
10use std::fmt;
11use std::io;
12use io::Write;
13pub use peg::Peg;
14
15
16
17#[cfg(test)]
18mod tests {
19    use super::*;
20
21    #[test]
22    fn test_game_step() {
23
24        let mut state = GameState::new(4);
25        let guess = vec![Peg::new(Color::Red), Peg::new(Color::Red), Peg::new(Color::Red), Peg::new(Color::Red)];
26        let validity = state.step(guess);
27
28        println!("{:?}", validity);
29        // cargo test -- --nocapture
30    }
31}
32
33
34#[derive(Debug)]
35pub enum Correctness {
36    Partial,
37    Total,
38}
39
40impl fmt::Display for Correctness {
41    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42        write!(f, "{:?}", self)
43    }
44}
45
46pub struct GameState {
47    answer: Vec<Peg>,
48    current_turn: u32,
49}
50
51impl GameState {
52    pub fn new(num_pegs: usize) -> GameState {
53        let answer: Vec<Peg> = (0..num_pegs)
54            .map(|x: usize| Peg::new_random())
55            .collect();
56
57        GameState::new_with_answer(answer)
58    }
59
60    pub fn new_with_answer(answer: Vec<Peg>) -> GameState {
61        GameState {
62            answer,
63            current_turn: 0,
64        }
65    }
66
67    pub fn step(&mut self, guess: Vec<Peg>) -> Vec<Correctness> {
68        self.current_turn += 1;
69
70        self.make_guess_response(guess)
71    }
72
73    fn make_guess_response(&mut self, mut guess: Vec<Peg>) -> Vec<Correctness> {
74        use Correctness::*;
75
76        let mut answer = self.answer.clone();
77        // println!("ANSWER {:?}", self.answer);
78        let mut result: Vec<Correctness> = Vec::new();
79
80        for i in 0..guess.len() {
81            if guess[i].color() == answer[i].color() && !answer[i].found() {
82                result.push(Total);
83                answer[i].find();
84                guess[i].find();
85            }
86        }
87
88        guess.retain(|p| !p.found());
89        answer.retain(|p| !p.found());
90
91        for g in guess.iter() {
92            answer.iter()
93                .position(|p| p.color() == g.color())
94                .map(|index| {
95                    if !answer[index].found() {
96                        result.push(Partial);
97                        answer[index].find();
98                    }
99                });
100        }
101        result
102    }
103}