diff --git a/admin/api/settings.go b/admin/api/settings.go index cbe9f759..4167d01f 100644 --- a/admin/api/settings.go +++ b/admin/api/settings.go @@ -51,7 +51,11 @@ func saveSettings(_ httprouter.Params, body []byte) (interface{}, error) { func ApplySettings(config settings.FICSettings) { fic.PartialValidation = config.PartialValidation - fic.UnlockedChallenges = !config.EnableExerciceDepend + if config.EnableExerciceDepend { + fic.UnlockedChallengeDepth = 0 + } else { + fic.UnlockedChallengeDepth = -1 + } fic.FirstBlood = config.FirstBlood fic.SubmissionCostBase = config.SubmissionCostBase fic.HintCoefficient = config.HintCurCoefficient diff --git a/backend/main.go b/backend/main.go index 16d7e51f..9c6c306d 100644 --- a/backend/main.go +++ b/backend/main.go @@ -49,9 +49,13 @@ var skipInitialGeneration = false func reloadSettings(config settings.FICSettings) { fic.HintCoefficient = config.HintCurCoefficient fic.WChoiceCoefficient = config.WChoiceCurCoefficient - if lastRegeneration != config.Generation || fic.PartialValidation != config.PartialValidation || fic.UnlockedChallenges != !config.EnableExerciceDepend || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase || fic.SubmissionUniqueness != config.SubmissionUniqueness { + if lastRegeneration != config.Generation || fic.PartialValidation != config.PartialValidation || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase || fic.SubmissionUniqueness != config.SubmissionUniqueness { fic.PartialValidation = config.PartialValidation - fic.UnlockedChallenges = !config.EnableExerciceDepend + if config.EnableExerciceDepend { + fic.UnlockedChallengeDepth = 0 + } else { + fic.UnlockedChallengeDepth = -1 + } fic.FirstBlood = config.FirstBlood fic.SubmissionCostBase = config.SubmissionCostBase diff --git a/libfic/team.go b/libfic/team.go index 3f8b6c25..a220f4f9 100644 --- a/libfic/team.go +++ b/libfic/team.go @@ -6,8 +6,8 @@ import ( "time" ) -// UnlockedChallenges disables dependancy requirement between challenges. -var UnlockedChallenges bool +// UnlockedChallengeDepth is the number of challenges to unlock ahead (0: only the next one, -1: all) +var UnlockedChallengeDepth int // WchoiceCoefficient is the current coefficient applied on the cost of changing flag into choices var WChoiceCoefficient = 1.0 @@ -99,14 +99,31 @@ func (t Team) Delete() (int64, error) { // HasAccess checks if the Team has access to the given challenge. func (t Team) HasAccess(e Exercice) bool { - if e.Depend == nil || UnlockedChallenges { + if UnlockedChallengeDepth < 0 { return true - } else { + } + + for i := UnlockedChallengeDepth; i >= 0; i-- { + // An exercice without dependency is accessible + if e.Depend == nil { + return true + } + ed := Exercice{} ed.Id = *e.Depend s, _ := t.HasSolved(ed) - return s + if s { + return s + } + + // Prepare next iteration + var err error + e, err = GetExercice(ed.Id) + if err != nil { + return false + } } + return false } // CanDownload checks if the Team has access to the given file.