Add a new setting to don't count same responses in scores

This commit is contained in:
nemunaire 2018-12-06 22:18:08 +01:00
parent 8dc460b507
commit 910ec94fd8
8 changed files with 44 additions and 5 deletions

View File

@ -54,6 +54,7 @@ func ApplySettings(config settings.FICSettings) {
fic.UnlockedChallenges = !config.EnableExerciceDepend fic.UnlockedChallenges = !config.EnableExerciceDepend
fic.FirstBlood = config.FirstBlood fic.FirstBlood = config.FirstBlood
fic.SubmissionCostBase = config.SubmissionCostBase fic.SubmissionCostBase = config.SubmissionCostBase
fic.SubmissionUniqueness = config.SubmissionUniqueness
} }
func reset(_ httprouter.Params, body []byte) (interface{}, error) { func reset(_ httprouter.Params, body []byte) (interface{}, error) {

View File

@ -116,6 +116,13 @@
</label> </label>
</div> </div>
<div class="form-check">
<label class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" ng-model="config.submissionUniqueness">
<span class="custom-control-label">Ne pas comptabiliser les tentatives identiques dans le score</span>
</label>
</div>
</fieldset> </fieldset>
</div> </div>
</form> </form>

View File

@ -54,6 +54,7 @@ func reloadSettings(config settings.FICSettings) {
fic.FirstBlood = config.FirstBlood fic.FirstBlood = config.FirstBlood
fic.SubmissionCostBase = config.SubmissionCostBase fic.SubmissionCostBase = config.SubmissionCostBase
fic.SubmissionUniqueness = config.SubmissionUniqueness
log.Println("Generating files...") log.Println("Generating files...")
go func() { go func() {

View File

@ -346,7 +346,12 @@ CREATE TABLE IF NOT EXISTS claim_descriptions(
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil { `); err != nil {
return err return err
}
if _, err := db.Exec("CREATE OR REPLACE VIEW exercice_distinct_tries AS SELECT id_exercice, id_team, MAX(time) AS time, cksum, nbdiff FROM exercice_tries GROUP BY id_team, id_exercice, cksum;"); err != nil {
return err
} }
return nil return nil
} }

View File

@ -343,8 +343,13 @@ func (e Exercice) SolvedCount() int64 {
// TriedTeamCount returns the number of Team that attempted to solve the exercice. // TriedTeamCount returns the number of Team that attempted to solve the exercice.
func (e Exercice) TriedTeamCount() int64 { func (e Exercice) TriedTeamCount() int64 {
tries_table := "exercice_tries"
if SubmissionUniqueness {
tries_table = "exercice_distinct_tries"
}
var nb int64 var nb int64
if err := DBQueryRow("SELECT COUNT(DISTINCT id_team) FROM exercice_tries WHERE id_exercice = ?", e.Id).Scan(&nb); err != nil { if err := DBQueryRow("SELECT COUNT(DISTINCT id_team) FROM " + tries_table + " WHERE id_exercice = ?", e.Id).Scan(&nb); err != nil {
return 0 return 0
} else { } else {
return nb return nb
@ -353,8 +358,13 @@ func (e Exercice) TriedTeamCount() int64 {
// TriedCount returns the number of cumulative attempts, all Team combined, for the exercice. // TriedCount returns the number of cumulative attempts, all Team combined, for the exercice.
func (e Exercice) TriedCount() int64 { func (e Exercice) TriedCount() int64 {
tries_table := "exercice_tries"
if SubmissionUniqueness {
tries_table = "exercice_distinct_tries"
}
var nb int64 var nb int64
if err := DBQueryRow("SELECT COUNT(id_team) FROM exercice_tries WHERE id_exercice = ?", e.Id).Scan(&nb); err != nil { if err := DBQueryRow("SELECT COUNT(id_team) FROM " + tries_table + " WHERE id_exercice = ?", e.Id).Scan(&nb); err != nil {
return 0 return 0
} else { } else {
return nb return nb

View File

@ -12,12 +12,20 @@ var FirstBlood = 0.12
// SubmissionCostBase is the basis amount of point lost per submission // SubmissionCostBase is the basis amount of point lost per submission
var SubmissionCostBase = 0.5 var SubmissionCostBase = 0.5
// SubmissionUniqueness don't count multiple times identical tries.
var SubmissionUniqueness = false
func exoptsQuery(whereExo string) string { func exoptsQuery(whereExo string) string {
tries_table := "exercice_tries"
if SubmissionUniqueness {
tries_table = "exercice_distinct_tries"
}
return `SELECT S.id_team, S.time, E.gain AS points, coeff FROM ( return `SELECT S.id_team, S.time, E.gain AS points, coeff FROM (
SELECT id_team, id_exercice, MIN(time) AS time, ` + fmt.Sprintf("%f", FirstBlood) + ` AS coeff FROM exercice_solved GROUP BY id_exercice UNION SELECT id_team, id_exercice, MIN(time) AS time, ` + fmt.Sprintf("%f", FirstBlood) + ` AS coeff FROM exercice_solved GROUP BY id_exercice UNION
SELECT id_team, id_exercice, time, coefficient AS coeff FROM exercice_solved SELECT id_team, id_exercice, time, coefficient AS coeff FROM exercice_solved
) S INNER JOIN exercices E ON S.id_exercice = E.id_exercice ` + whereExo + ` UNION ALL ) S INNER JOIN exercices E ON S.id_exercice = E.id_exercice ` + whereExo + ` UNION ALL
SELECT id_team, MAX(time) AS time, (FLOOR(COUNT(*)/10 - 1) * (FLOOR(COUNT(*)/10)))/0.2 + (FLOOR(COUNT(*)/10) * (COUNT(*)%10)) AS points, ` + fmt.Sprintf("%f", SubmissionCostBase * -1) + ` AS coeff FROM exercice_tries S ` + whereExo + ` GROUP BY id_exercice, id_team` SELECT id_team, MAX(time) AS time, (FLOOR(COUNT(*)/10 - 1) * (FLOOR(COUNT(*)/10)))/0.2 + (FLOOR(COUNT(*)/10) * (COUNT(*)%10)) AS points, ` + fmt.Sprintf("%f", SubmissionCostBase * -1) + ` AS coeff FROM ` + tries_table + ` S ` + whereExo + ` GROUP BY id_exercice, id_team`
} }
func rankQuery(whereTeam string) string { func rankQuery(whereTeam string) string {

View File

@ -145,12 +145,17 @@ func (t Team) CanSeeFlag(k Flag) bool {
// NbTry retrieves the number of attempts made by the Team to the given challenge. // NbTry retrieves the number of attempts made by the Team to the given challenge.
func NbTry(t *Team, e Exercice) int { func NbTry(t *Team, e Exercice) int {
tries_table := "exercice_tries"
if SubmissionUniqueness {
tries_table = "exercice_distinct_tries"
}
var cnt *int var cnt *int
if t != nil { if t != nil {
DBQueryRow("SELECT COUNT(*) FROM exercice_tries WHERE id_team = ? AND id_exercice = ?", t.Id, e.Id).Scan(&cnt) DBQueryRow("SELECT COUNT(*) FROM " + tries_table + " WHERE id_team = ? AND id_exercice = ?", t.Id, e.Id).Scan(&cnt)
} else { } else {
DBQueryRow("SELECT COUNT(*) FROM exercice_tries WHERE id_exercice = ?", e.Id).Scan(&cnt) DBQueryRow("SELECT COUNT(*) FROM " + tries_table + " WHERE id_exercice = ?", e.Id).Scan(&cnt)
} }
if cnt == nil { if cnt == nil {

View File

@ -49,6 +49,8 @@ type FICSettings struct {
PartialValidation bool `json:"partialValidation"` PartialValidation bool `json:"partialValidation"`
// EnableExerciceDepend don't show (or permit to solve) to team challenges they are not unlocked through dependancies. // EnableExerciceDepend don't show (or permit to solve) to team challenges they are not unlocked through dependancies.
EnableExerciceDepend bool `json:"enableExerciceDepend"` EnableExerciceDepend bool `json:"enableExerciceDepend"`
// SubmissionUniqueness don't count multiple times identical tries.
SubmissionUniqueness bool `json:"submissionUniqueness"`
} }
// ExistsSettings checks if the settings file can by found at the given path. // ExistsSettings checks if the settings file can by found at the given path.