Nicolas Winkler преди 4 години
родител
ревизия
c0f1f7b566
променени са 8 файла, в които са добавени 154 реда и са изтрити 41 реда
  1. 1 1
      TODO.txt
  2. 6 0
      src/config.rs
  3. 94 21
      src/server/gamelobby.rs
  4. 4 0
      src/server/messages.rs
  5. 7 0
      src/server/server.rs
  6. 32 12
      static/comm.js
  7. 3 2
      static/index.html
  8. 7 5
      static/style.css

+ 1 - 1
TODO.txt

@@ -1,6 +1,6 @@
 - one player ready => enough? how? YES
 - on ready click: bestätigung -> players green when ready YES
-- on word submit
+- on word submit 
 - guessing bug
 - results reveal einzeln
 - results: display whose words

+ 6 - 0
src/config.rs

@@ -18,3 +18,9 @@ pub struct ServerConfig {
 }
 
 
+#[derive(Deserialize)]
+pub struct LobbySettings {
+    pub n_vowels: usize,
+    pub n_consonants: usize,
+    pub custom_wordlist: Option<Vec<String>>
+}

+ 94 - 21
src/server/gamelobby.rs

@@ -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()

+ 4 - 0
src/server/messages.rs

@@ -29,6 +29,10 @@ pub struct UnreadyMsg(pub String);
 
 #[derive(Message)]
 #[rtype(result = "()")]
+pub struct RevealMsg(pub String);
+
+#[derive(Message)]
+#[rtype(result = "()")]
 pub struct LeaveMsg(pub String);
 
 #[derive(Message)]

+ 7 - 0
src/server/server.rs

@@ -232,6 +232,13 @@ impl GameConnection {
                         }
                     }
                 },
+                ClientMessage::Reveal => {
+                    if let Some(lobby) = &self.game_lobby {
+                        if let Some(nick) = &self.nick {
+                            lobby.do_send(RevealMsg(nick.clone()));
+                        }
+                    }
+                },
                 ClientMessage::SubmitWord{ word } => {
                     if let Some(lobby) = &self.game_lobby {
                         if let Some(nick) = &self.nick {

+ 32 - 12
static/comm.js

@@ -109,6 +109,10 @@ $(function() {
         };
         send(msg);
     });
+    $(document).on("click", "#reveal-button", function() {
+        var msg = "reveal";
+        send(msg);
+    });
 
     function connect(initial_message) {
         if (connection != null) {
@@ -180,9 +184,9 @@ $(function() {
                 var guesses = gs.state_data.guessing;
                 displayGuessing(guesses);
             }
-        }
-        else if (obj.round_result != null) {
-            displayResult(obj.round_result);
+            else if (gs.state_data.revealing != null) {
+                displayResult(gs.state_data.revealing.round_result, gs.state_data.players);
+            }
         }
         else {
             statusMessage("Unknown message retrieved");
@@ -200,7 +204,7 @@ $(function() {
     }
 
     function displayResult(result) {
-        var sol = result.solutions; 
+        var sol = result.solutions;
         var solution_dict = {};
         for (var i = 0; i < sol.length; i++) {
             solution_dict[sol[i][0]] = sol[i][1];
@@ -208,11 +212,25 @@ $(function() {
         var $table = $('<table/>');
         $table.addClass('result-table');
 
+        var row_shows = result.words.map(w => w[2]);
         var $row = $("<tr/>");
         $row.append($("<th/>"));
         for(var i = 0; i < result.words.length; i++) {
             var $wordline = $("<th/>");
-            $wordline.text(result.words[i]);
+            var $word = $("<p/>");
+            $word.text(result.words[i][1]);
+            $wordline.append($word);
+            if (!row_shows[i] && result.words[i][0] == nick) {
+                var $butt = $("<button/>");
+                $butt.attr("id", "reveal-button");
+                $butt.text("Reveal");
+                $wordline.append($butt);
+            }
+            else if (row_shows[i]) {
+                var $creator = $("<small/>");
+                $creator.text(result.words[i][0]);
+                $wordline.append($creator);
+            }
             $row.append($wordline);
         }
         $table.append($row);
@@ -224,13 +242,15 @@ $(function() {
             $row.append($header);
             for(var j = 0; j < result.words.length; j++) {
                 var $cell = $("<td/>");
-                if (solution_dict[result.words[j]] == result.questions[i]) {
-                    $cell.addClass("result-correct");
-                }
-                else {
-                    $cell.addClass("result-wrong");
+                if (row_shows[j]) {
+                    if (solution_dict[result.words[j][1]] == result.questions[i]) {
+                        $cell.addClass("result-correct");
+                    }
+                    else {
+                        $cell.addClass("result-wrong");
+                    }
+                    $cell.text(result.guesses[j][i]);
                 }
-                $cell.text(result.guesses[j][i]);
                 $row.append($cell);
             }
             $table.append($row);
@@ -244,7 +264,7 @@ $(function() {
         var $points = $("<tr/>");
         var pl = result.point_list;
         for(var i = 0; i < pl.length; i++) {
-            var $htd = $("<td/>"); $htd.text(pl[i][0]);
+            var $htd = $("<th/>"); $htd.text(pl[i][0]);
             var $ptd = $("<td/>"); $ptd.text(pl[i][1]);
             $header.append($htd);
             $points.append($ptd);

+ 3 - 2
static/index.html

@@ -10,7 +10,7 @@
 </head>
 <body>
     <div class="header">
-        <h1>Welcome to Eichelhäutgerät</h1>
+        <h1>Welcome to Elchhäutgerät</h1>
     </div>
     <aside class="side-control">
         <div id="side-info">
@@ -88,7 +88,8 @@
         </div>
         <div id="results" style="margin-top: 20px; display:none">
             <div id="guesses-table"></div>
-            <table id="points-table" class="points-table"></table>
+
+            <table id="points-table" class="points-tbl"></table>
         </div>
         <div id="status">
         </div>

+ 7 - 5
static/style.css

@@ -287,6 +287,7 @@ label {
 }
 
 .result-table {
+    width: 100%;
     border-collapse: collapse;
     margin: 12px 0px;
 }
@@ -296,16 +297,17 @@ label {
     padding: 8px;
 }
 
-.points-table {
+.points-tbl {
+    text-align: left;
     border-collapse: collapse;
     margin: 12px 0px;
 }
 
-.points-table th {
+.points-tbl td, th {
+    padding-top: 12px;
+    padding-bottom: 12px;
     border: 1px solid #2b2b4d;
-    font-size: larger;
-    background-color: var(--color-darker);
-    padding: 8px;
+    text-align: left;
 }
 
 .result-correct {