Browse Source

Merge branch 'score_rank' of irc.knacki.info/ircbot-quizz into master

isundil 6 years ago
parent
commit
a84b6b5778
2 changed files with 75 additions and 5 deletions
  1. 2 1
      index.js
  2. 73 4
      quizz.js

+ 2 - 1
index.js

@@ -35,7 +35,7 @@ function KnackiBot() {
         realName: this.name,
         stripColors: true
     });
-    if (USE_NS)
+    if (USE_NS) {
         var _this = this,
             registerHandler = 0;
 
@@ -65,6 +65,7 @@ function KnackiBot() {
             registerHandler = setInterval(tryRegister, 30000);
             tryRegister();
         });
+    }
     this.bot.addListener("error", console.error);
     this.bot.addListener("join", (chan, nick) => {
         chan = chan.toLowerCase();

+ 73 - 4
quizz.js

@@ -114,6 +114,49 @@ Question.prototype.end = function() {
         delete this.boundaries;
 }
 
+const ScoreUtils = (function() {
+    const getRank = function(pseudo) {
+        for (var i =0, len = this.length; i < len; ++i)
+            if (this[i].name === pseudo)
+                return i +1;
+        return null;
+    };
+
+    const diff = function(pseudo, pointIncrement) {
+        var oldIndex = this.getRank(pseudo) -1,
+            score = pointIncrement;
+        if (oldIndex < 0) {
+            oldIndex = this.length;
+            this.push({name: pseudo, score: pointIncrement});
+        } else {
+            this[oldIndex].score += pointIncrement;
+            score = this[oldIndex].score;
+        }
+        scores = this.sort((a, b) => b.score - a.score);
+        var newIndex = this.getRank(pseudo) -1;
+        var result = { newRank: newIndex +1, oldRank: oldIndex +1 };
+        if (newIndex < 0 || newIndex === oldIndex)
+            return result;
+        result.users = this.slice(newIndex +1, oldIndex +1);
+        return result;
+    };
+
+    return {
+        buildScoreArray: function(quizzBot, filter, limit) {
+            var scores = [];
+            for (var i in quizzBot.users)
+                if (filter(i))
+                    scores.push({name: quizzBot.users[i].name, score: quizzBot.users[i].score});
+            scores = scores.sort((a, b) => b.score - a.score);
+            if (limit !== undefined)
+                scores = scores.slice(0, limit);
+            scores.getRank = getRank.bind(scores);
+            scores.diff = diff.bind(scores);
+            return scores;
+        }
+    };
+})();
+
 function initQuestionList(filename) {
     return new Promise((ok, ko) => {
         console.log("Reloading question db");
@@ -318,14 +361,11 @@ QuizzBot.prototype.sumScores = function(onlyPresent) {
 }
 
 QuizzBot.prototype.sendScore = function(onlyPresent) {
-    var scores = [];
-    for (var i in this.users)
-        this.users[i].score && (this.activeUsers[i] || !onlyPresent) && scores.push({name: this.users[i].name, score: this.users[i].score});
+    var scores = ScoreUtils.buildScoreArray(this, user => this.users[user].score && (this.activeUsers[user] || !onlyPresent), 10);
     if (scores.length == 0) {
         this.bot.sendMsg(this.room, "Pas de points pour le moment");
         return;
     }
-    scores = scores.sort((a, b) => b.score - a.score).slice(0, 10);
     var index = 0;
     var scoreLines = arrayPad(scores.map(i => [ ((++index) +"."), i.name, (i.score +" points") ]));
     if (scoreLines[0].length < 30) {
@@ -371,6 +411,33 @@ QuizzBot.prototype.resetScores = function() {
     Cache.SetScores({});
 }
 
+/**
+ * This function is called when a user answer right,
+ * @param diff an object containing the new rank, the previous rank, and an
+ * array containing all the users having been overpassed
+ * @return a string with a message to be displayed or null if nothing to say
+**/
+QuizzBot.prototype.buildOverpassedMessage = function(username, diff) {
+    if (!diff.users || !diff.users.length)
+        return null;
+    const rankStr = diff.newRank == 1 ? "1ere" : `${diff.newRank}eme`;
+    if (diff.users.length > 1) // Advanced too much rank at once ! Only display new position
+        return `${username} prend la ${rankStr} place !`;
+
+    const looser = diff.users[0].name,
+        insults = [
+            () => `${username} prend la ${rankStr} place en doublant allegrement ${looser}`,
+            () => `${username} fait un gros pied de nez a ${looser} en prennant la ${rankStr} place`,
+            () => `${username} prends la ${rankStr} place et fait mordre la poussière à ${looser}`,
+            () => `${looser} est maintenant dans le sillage de ${username} qui lui a piqué la ${rankStr} place`,
+            () => `${username} envoie ${looser} dans les méandres de la loose en lui prenant la ${rankStr} place`,
+            () => `${looser} est maintenant visible en tout petit dans le rétroviseur de ${username} qui lui a piqué la ${rankStr} place`,
+            () => `La ${rankStr} place est maintenant la propriété de ${username} qui a envoyé ${looser} au tapis`,
+            () => `${username} tatoue un gros L de la loose sur le front de ${looser} qui vient de perdre la ${rankStr} place`
+        ];
+    return insults[Math.floor(Math.random() * insults.length)]();
+}
+
 QuizzBot.prototype.onMessageInternal = function(username, user, msg) {
     const lmsg = msg.toLowerCase();
     if (lmsg.startsWith("!reload")) {
@@ -520,9 +587,11 @@ QuizzBot.prototype.onMessageInternal = function(username, user, msg) {
         var dieOnFailure = this.currentQuestion.isBoolean() && this.currentQuestion.isBoolean(Question.normalize(msg));
         if (this.currentQuestion.check(msg)) {
             const nbPts = this.computeScore(username);
+            var overpassedMessage = this.buildOverpassedMessage(username, ScoreUtils.buildScoreArray(this, i => this.users[i].score).diff(username, nbPts));
             user.score += nbPts;
             Cache.SetScores(this.users);
             this.bot.sendMsg(this.room, nbPts +" points pour " +username +", qui cumule un total de " +user.score +" points !");
+            overpassedMessage && this.bot.sendMsg(this.room, overpassedMessage);
             this.bot.voice(this.room, username);
             this.nextQuestionWrapper();
         }