|  | @@ -29,6 +29,8 @@ pub struct GameLobby {
 | 
	
		
			
				|  |  |      player_points: BTreeMap<String, i64>,
 | 
	
		
			
				|  |  |      waiting_players: BTreeMap<String, Addr<GameConnection>>,
 | 
	
		
			
				|  |  |      ready_players: Vec<String>,
 | 
	
		
			
				|  |  | +    revealed_players: Vec<String>,
 | 
	
		
			
				|  |  | +    round_result: Option<RoundResultData>,
 | 
	
		
			
				|  |  |      lobby_state: LobbyState,
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  |      //data_source: Arc<dyn datasource::DataSource<String>>,
 | 
	
	
		
			
				|  | @@ -104,6 +106,21 @@ impl Handler<UnreadyMsg> for GameLobby {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +impl Handler<RevealMsg> for GameLobby {
 | 
	
		
			
				|  |  | +    type Result = ();
 | 
	
		
			
				|  |  | +    fn handle(&mut self, rm: RevealMsg, _ctx: &mut Self::Context) -> Self::Result {
 | 
	
		
			
				|  |  | +        self.revealed_players.retain(|p| p != &rm.0);
 | 
	
		
			
				|  |  | +        self.revealed_players.push(rm.0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        self.send_game_to_all();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if self.all_revealed() {
 | 
	
		
			
				|  |  | +            self.set_state(LobbyState::Starting);
 | 
	
		
			
				|  |  | +            self.send_game_to_all();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  impl Handler<SubmitWordMsg> for GameLobby {
 | 
	
		
			
				|  |  |      type Result = ();
 | 
	
		
			
				|  |  |      fn handle(&mut self, swm: SubmitWordMsg, _ctx: &mut Self::Context) -> Self::Result {
 | 
	
	
		
			
				|  | @@ -132,7 +149,8 @@ impl Handler<SubmitGuessMsg> for GameLobby {
 | 
	
		
			
				|  |  |                  self.add_player_points(nick, *pts);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            self.broadcast_results(results);
 | 
	
		
			
				|  |  | +            //self.broadcast_results(results.clone());
 | 
	
		
			
				|  |  | +            self.round_result = Some(results);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              self.game.next_state();
 | 
	
		
			
				|  |  |              self.send_game_to_all();
 | 
	
	
		
			
				|  | @@ -152,7 +170,9 @@ impl GameLobby {
 | 
	
		
			
				|  |  |              game: game::Game::new(),
 | 
	
		
			
				|  |  |              player_points: BTreeMap::new(),
 | 
	
		
			
				|  |  |              waiting_players: BTreeMap::new(),
 | 
	
		
			
				|  |  | +            round_result: None,
 | 
	
		
			
				|  |  |              ready_players: Vec::new(),
 | 
	
		
			
				|  |  | +            revealed_players: Vec::new(),
 | 
	
		
			
				|  |  |              lobby_state: LobbyState::Starting,
 | 
	
		
			
				|  |  |              shuffler: datasource::Shuffler::create(data_source),
 | 
	
		
			
				|  |  |              letter_distribution: datasource::LetterDistribution::create()
 | 
	
	
		
			
				|  | @@ -175,6 +195,8 @@ impl GameLobby {
 | 
	
		
			
				|  |  |              _ => {}
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          self.ready_players.clear();
 | 
	
		
			
				|  |  | +        self.revealed_players.clear();
 | 
	
		
			
				|  |  | +        self.round_result = None;
 | 
	
		
			
				|  |  |          self.lobby_state = new_state;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -208,31 +230,65 @@ impl GameLobby {
 | 
	
		
			
				|  |  |          let (guesses, point_list) = self.game.create_results();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let words = self.game.players.iter()
 | 
	
		
			
				|  |  | -                        .map(|p| p.submitted_word.clone().unwrap())
 | 
	
		
			
				|  |  | +                        .map(|p| (
 | 
	
		
			
				|  |  | +                                p.nick.clone(), 
 | 
	
		
			
				|  |  | +                                p.submitted_word.clone().unwrap(),
 | 
	
		
			
				|  |  | +                                self.revealed_players.iter().any(|x| x == &p.nick)
 | 
	
		
			
				|  |  | +                            )
 | 
	
		
			
				|  |  | +                        )
 | 
	
		
			
				|  |  |                          .collect::<Vec<_>>();
 | 
	
		
			
				|  |  |          let questions = self.game.players.iter()
 | 
	
		
			
				|  |  |                          .map(|x| x.creating_exercise.as_ref().unwrap().question.clone())
 | 
	
		
			
				|  |  |                          .chain(self.game.additional_questions.clone().into_iter())
 | 
	
		
			
				|  |  |                          .collect::<Vec<_>>();
 | 
	
		
			
				|  |  |          let solutions = words.iter()
 | 
	
		
			
				|  |  | -                        .map(|x| x.clone())
 | 
	
		
			
				|  |  | +                        .map(|(_n, w, _r)| w.clone())
 | 
	
		
			
				|  |  |                          .zip(questions.iter().map(|x| x.clone()))
 | 
	
		
			
				|  |  |                          .collect::<Vec<_>>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        let mut permutation = (0..questions.len()).collect::<Vec<_>>();
 | 
	
		
			
				|  |  | +        permutation.shuffle(&mut thread_rng());
 | 
	
		
			
				|  |  | +        let mut shuffled_questions: Vec<String> = Vec::new();
 | 
	
		
			
				|  |  | +        let mut shuffled_guesses: Vec<Vec<Vec<String>>> = Vec::new();
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        for pi in &permutation {
 | 
	
		
			
				|  |  | +            shuffled_questions.push(questions[*pi].clone());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for guessline in guesses {
 | 
	
		
			
				|  |  | +            let mut shuffled_line: Vec<Vec<String>> = Vec::new();
 | 
	
		
			
				|  |  | +            for pi in &permutation {
 | 
	
		
			
				|  |  | +                if *pi < guessline.len() {
 | 
	
		
			
				|  |  | +                    shuffled_line.push(guessline[*pi].clone());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else {
 | 
	
		
			
				|  |  | +                    shuffled_line.push(Vec::new());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            shuffled_guesses.push(shuffled_line);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          RoundResultData {
 | 
	
		
			
				|  |  |              words,
 | 
	
		
			
				|  |  | -            questions,
 | 
	
		
			
				|  |  | +            questions: shuffled_questions,
 | 
	
		
			
				|  |  |              solutions,
 | 
	
		
			
				|  |  | -            guesses,
 | 
	
		
			
				|  |  | +            guesses: shuffled_guesses,
 | 
	
		
			
				|  |  |              point_list
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pub fn broadcast_results(&self, results: RoundResultData) {
 | 
	
		
			
				|  |  | +    /*pub fn broadcast_results(&self, results: RoundResultData) {
 | 
	
		
			
				|  |  | +        let has_revealed = self.revealed_players.iter()
 | 
	
		
			
				|  |  | +                            .map(|n| (n.clone(), self.revealed_players.iter().any(|x| x == n)))
 | 
	
		
			
				|  |  | +                            .collect::<Vec<_>>();
 | 
	
		
			
				|  |  |          for (_nick, player) in &self.connected_players {
 | 
	
		
			
				|  |  | -            player.do_send(ResultMsg{ results: results.clone() });
 | 
	
		
			
				|  |  | +            player.do_send(ResultMsg {
 | 
	
		
			
				|  |  | +                results: results.clone(),
 | 
	
		
			
				|  |  | +                //has_revealed: has_revealed.clone()
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    }*/
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      ///
 | 
	
		
			
				|  |  |      /// determines if a player is ready to progress into the next game state
 | 
	
	
		
			
				|  | @@ -269,19 +325,31 @@ impl GameLobby {
 | 
	
		
			
				|  |  |          GameData {
 | 
	
		
			
				|  |  |              players: self.create_playerlist(),
 | 
	
		
			
				|  |  |              state_data:
 | 
	
		
			
				|  |  | -                match self.game.state {
 | 
	
		
			
				|  |  | -                    game::GameState::Starting => {
 | 
	
		
			
				|  |  | -                        GameStateData::Starting
 | 
	
		
			
				|  |  | -                    },
 | 
	
		
			
				|  |  | -                    game::GameState::Creating => {
 | 
	
		
			
				|  |  | -                        GameStateData::Creating{
 | 
	
		
			
				|  |  | -                            question: player.unwrap().creating_exercise.as_ref().unwrap().question.clone(),
 | 
	
		
			
				|  |  | -                            available_chars: player.unwrap().creating_exercise.as_ref().unwrap().letters.clone()
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                    },
 | 
	
		
			
				|  |  | -                    game::GameState::Guessing => {
 | 
	
		
			
				|  |  | -                        self.create_guessing()
 | 
	
		
			
				|  |  | -                    },
 | 
	
		
			
				|  |  | +                if self.lobby_state == LobbyState::Revealing {
 | 
	
		
			
				|  |  | +                    let mut round_result = self.round_result.as_ref().unwrap().clone();
 | 
	
		
			
				|  |  | +                    for (nick, _word, revealed) in &mut round_result.words {
 | 
	
		
			
				|  |  | +                        *revealed = self.revealed_players.iter().any(|x| x == nick);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    GameStateData::Revealing {
 | 
	
		
			
				|  |  | +                        round_result
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else {
 | 
	
		
			
				|  |  | +                    match self.game.state {
 | 
	
		
			
				|  |  | +                        game::GameState::Starting => {
 | 
	
		
			
				|  |  | +                            GameStateData::Starting
 | 
	
		
			
				|  |  | +                        },
 | 
	
		
			
				|  |  | +                        game::GameState::Creating => {
 | 
	
		
			
				|  |  | +                            GameStateData::Creating{
 | 
	
		
			
				|  |  | +                                question: player.unwrap().creating_exercise.as_ref().unwrap().question.clone(),
 | 
	
		
			
				|  |  | +                                available_chars: player.unwrap().creating_exercise.as_ref().unwrap().letters.clone()
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                        },
 | 
	
		
			
				|  |  | +                        game::GameState::Guessing => {
 | 
	
		
			
				|  |  | +                            self.create_guessing()
 | 
	
		
			
				|  |  | +                        },
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -292,6 +360,11 @@ impl GameLobby {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    pub fn all_revealed(&self) -> bool {
 | 
	
		
			
				|  |  | +        self.connected_players.iter().all(|(nick, _p)| self.revealed_players.iter().any(|x| x == nick))
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      pub fn create_guessing(&self) -> GameStateData {
 | 
	
		
			
				|  |  |          self.check_optionals();
 | 
	
		
			
				|  |  |          let words_with_chars = self.game.players.iter()
 |