From 96a85ce98193adc90d58e6d7372e072dde55b3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Schr=C3=B6ter?= Date: Tue, 29 Dec 2020 15:19:43 +0000 Subject: [PATCH] Resolve "Balance occurrence of questions" --- endpoint/duel/query.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/endpoint/duel/query.go b/endpoint/duel/query.go index 314f184..64b4200 100644 --- a/endpoint/duel/query.go +++ b/endpoint/duel/query.go @@ -269,6 +269,23 @@ const queryDuelsByUser = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel` "WHERE `idduel` IN (SELECT `duel` FROM `duel_player_score` WHERE `user` = ?)" + "ORDER BY `idduel`" + // queryQuestionsForNewRound randomly queries questions for a new duel round. Questions which + // weren't played often by both users are preferred. Thus, the score for each question is + // calculated using the formula (#u1)^2 + (#u2) with some random factors for + // variance. #u1 and #u2 are the numbers of times the question has been played by the + // corresponding user. +const queryQuestionsForNewRound = "SELECT `pool_question`.`question` FROM `pool_question`" + + "JOIN `question` ON (`pool_question`.`question` = `question`.`idquestion`)" + + "LEFT JOIN `roundquestion` ON (`roundquestion`.`question`=`pool_question`.`question`)" + + "LEFT JOIN `useranswer` ON (`roundquestion`.`idroundquestion`=`useranswer`.`roundquestion`)" + + "WHERE" + + "`pool_question`.`pool`=? " + + "AND `pool_question`.`question` NOT IN (SELECT `question` FROM `roundquestion` INNER JOIN `round` ON (`round`.`idround` = `roundquestion`.`round`) WHERE `duel`=?)" + + "AND `question`.`published`=1 " + + "GROUP BY `pool_question`.`question`" + + "ORDER BY POW(COUNT(IF(`useranswer`.`user`=? AND RAND()<.9, 1, NULL)), 2) + POW(COUNT(IF(`useranswer`.`user`=? AND RAND()<.9, 1, NULL)), 2)" + + "LIMIT ?" + // DuelQuery provides functions to create, get and update duels in datastores. // There can be various implementations for different datastores. type DuelQuery interface { @@ -852,7 +869,7 @@ func (m *MySQLDuelQuery) SetPool(duelID, poolID, userID uint32) (*schemas.DuelSc } // Select questions and create roundquestions - questions, errQuestions := tx.Query("SELECT `pool_question`.`question` FROM `pool_question` JOIN `question` ON (`pool_question`.`question` = `question`.`idquestion`) WHERE `pool_question`.`pool`=? AND `pool_question`.`question` NOT IN (SELECT `question` FROM `roundquestion` INNER JOIN `round` ON (`round`.`idround` = `roundquestion`.`round`) WHERE `duel`=?) AND `question`.`published`=1 ORDER BY RAND() LIMIT ?", poolID, duelID, QuestionsPerRound) + questions, errQuestions := tx.Query(queryQuestionsForNewRound, poolID, duelID, user1, user2, QuestionsPerRound) if errQuestions != nil { return nil, errQuestions -- GitLab