reset() {
- /* Before closing out the current round, we accumulate the score
- * for each player into their runnning total. */
- for (let score of this.state.scores.scores) {
- const player = this.players.find(p => p.name === score.player);
- if (player.score)
- player.score += score.score;
- else
- player.score = score.score;
-
- /* And broadcast that new score out. */
- this.broadcast_event('player-update', player.info_json());
+ /* Before closing out the current round, we accumulate into each
+ * player's overall score the results from the current round.
+ *
+ * Note: Rather than applying the actual points from each round
+ * into the player's score, we instead accumulate up the number of
+ * players that they bested in each round. This ensures that each
+ * round receives an equal weight in the overall scoring. */
+ let bested = this.state.scores.scores.reduce(
+ (total, score) => total + score.players.length, 0);
+ for (let i = 0; i < this.state.scores.scores.length; i++) {
+ const score = this.state.scores.scores[i];
+ bested -= score.players.length;
+ for (let player_name of score.players) {
+ const player = this.players.find(p => p.name === player_name);
+ if (player.score)
+ player.score += bested;
+ else
+ player.score = bested;
+
+ /* And broadcast that new score out. */
+ this.broadcast_event('player-update', player.info_json());
+ }
}
/* Now that we're done with the active prompt, we remove it from
return b.score - a.score;
});
+ /* After sorting individual players by score, group players
+ * together who have the same score. */
+ const reducer = (list, next) => {
+ if (list.length && list[list.length-1].score == next.score)
+ list[list.length-1].players.push(next.player);
+ else
+ list.push({players: [next.player], score: next.score});
+ return list;
+ };
+
+ const grouped_scores = scores.reduce(reducer, []);
+
/* Put the word groups into a form the client can consume.
*/
const words_submitted = word_groups.map(
/* Put this round's scores into the game state object so it will
* be sent to any new clients that join. */
this.state.scores = {
- scores: scores,
+ scores: grouped_scores,
words: words_submitted
};
# Usage: empathy_scores_names_numbers <player_name>
empathy_scores_names_numbers()
{
- empathy_get_event $1 game-state | jq '.scores.scores[]|.player,.score'
+ empathy_get_event $1 game-state | jq '.scores.scores[]|.players[],.score'
}
TEST_SUBSECTION "Scoring"
TEST "Verify the match passed the vote"
# echo here is to strip newlines
result=$(echo $(empathy_scores_names_numbers alice))
-test "$result" = '"alice" 2 "bob" 2 "charlie" 0 "dale" 0 "eric" 0 "fred" 0'
+test "$result" = '"alice" "bob" 2 "charlie" "dale" "eric" "fred" 0'
TEST_END
echo ""
TEST "Verify scores don't include inactive players"
# echo here is to strip newlines
result=$(echo $(empathy_scores_names_numbers alice))
-test "$result" = '"alice" 1 "bob" 1 "charlie" 0'
+test "$result" = '"alice" "bob" 1 "charlie" 0'
TEST_END
TEST_SUBSECTION "Deactivated players don't block future game phase advances"