settings: add coefficient to hint and wchoices

This commit is contained in:
nemunaire 2019-01-17 12:03:18 +01:00
parent 2623d9dd61
commit c5f8288f39
10 changed files with 43 additions and 13 deletions

View File

@ -54,6 +54,9 @@ func ApplySettings(config settings.FICSettings) {
fic.UnlockedChallenges = !config.EnableExerciceDepend
fic.FirstBlood = config.FirstBlood
fic.SubmissionCostBase = config.SubmissionCostBase
fic.HintCoefficient = config.HintCurCoefficient
fic.WChoiceCoefficient = config.WChoiceCurCoefficient
fic.SubmissionCostBase = config.SubmissionCostBase
fic.SubmissionUniqueness = config.SubmissionUniqueness
}

View File

@ -60,17 +60,29 @@
<hr>
<div class="form-group row">
<label for="firstBlood" class="col-sm-3 col-form-label col-form-label-sm">Bonus premier sang</label>
<label for="hintcoefficient" class="col-sm-3 col-form-label col-form-label-sm">Coefficient indices</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="firstBlood" ng-model="config.firstBlood" float>
<input type="text" class="form-control form-control-sm" id="hintcoefficient" ng-model="config.hintCurrentCoefficient" float>
</div>
<label for="wchoicescoefficient" class="offset-sm-2 col-sm-3 col-form-label col-form-label-sm">Coefficient WChoices</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="wchoicescoefficient" ng-model="config.wchoiceCurrentCoefficient" float>
</div>
</div>
<div class="form-group row">
<label for="submissionCostBase" class="col-sm-3 col-form-label col-form-label-sm">Coût de base d'une tentative</label>
<label for="firstBlood" class="col-sm-3 col-form-label col-form-label-sm">Bonus premier sang</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="firstBlood" ng-model="config.firstBlood" float>
</div>
<label for="submissionCostBase" class="offset-sm-1 col-sm-4 col-form-label col-form-label-sm">Coût de base d'une tentative</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="submissionCostBase" ng-model="config.submissionCostBase" float>
</div>
</div>
<div class="form-group row">
<div class="col text-right">
<button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Propager ces paramètres</button>
</div>

View File

@ -47,7 +47,9 @@ var lastRegeneration time.Time
var skipInitialGeneration = false
func reloadSettings(config settings.FICSettings) {
if lastRegeneration != config.Generation || fic.PartialValidation != config.PartialValidation || fic.UnlockedChallenges != !config.EnableExerciceDepend || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase {
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 {
fic.PartialValidation = config.PartialValidation
fic.UnlockedChallenges = !config.EnableExerciceDepend

View File

@ -73,7 +73,7 @@
<h4 class="list-group-item-heading">{{ hint.title }}</h4>
<p class="list-group-item-text" ng-if="!hint.file && hint.content && !hint.hidden" ng-bind-html="hint.content"></p>
<p class="list-group-item-text" ng-if="hint.file">Cliquez ici pour télécharger l'indice. <samp class="cksum" title="Somme de contrôle BLAKE2b : {{ hint.content }}">{{ hint.content }}</samp></p>
<p class="list-group-item-text" ng-if="!hint.file && !hint.content && (hint.hidden === true || hint.hidden === undefined)">Débloquer cet indice vous fera perdre <ng-pluralize count="hint.cost" when="{'one': '{} point', 'other': '{} points'}"></ng-pluralize>.</p>
<p class="list-group-item-text" ng-if="!hint.file && !hint.content && (hint.hidden === true || hint.hidden === undefined)">Débloquer cet indice vous fera perdre <ng-pluralize count="hint.cost * settings.hintCurrentCoefficient" when="{'one': '{} point', 'other': '{} points'}"></ng-pluralize>.</p>
</a>
</div>
</div>
@ -97,9 +97,9 @@
<input type="text" class="form-control flag" id="sol_{{ kid }}_{{ $index }}" autocomplete="off" name="sol_{{ kid }}" ng-model="key.values[$index]" ng-if="!key.choices" placeholder="{{ key.help }}" title="{{ key.help }}">
<select class="custom-select" id="sol_{{ kid }}" name="sol_{{ kid }}" ng-model="key.values[$index]" ng-if="key.choices" ng-options="l as v for (l, v) in key.choices"></select>
<div class="input-group-append" ng-if="key.choices_cost">
<button class="btn btn-success" type="button" ng-click="wantchoices(kid)" ng-class="{disabled: key.wcsubmitted}" title="Cliquez pour échanger ce champ de texte par une liste de choix. L'opération vous coûtera {{ key.choices_cost }} points.">
<button class="btn btn-success" type="button" ng-click="wantchoices(kid)" ng-class="{disabled: key.wcsubmitted}" title="Cliquez pour échanger ce champ de texte par une liste de choix. L'opération vous coûtera {{ key.choices_cost * settings.wchoiceCurrentCoefficient }} points.">
<span class="glyphicon glyphicon-tasks" aria-hidden="true"></span>
Liste de propositions ({{ key.choices_cost }} points)
Liste de propositions (<ng-pluralize count="key.choices_cost * settings.wchoiceCurrentCoefficient" when="{'one': '{} point', 'other': '{} points'}"></ng-pluralize>)
</button>
</div>
<div class="input-group-append" ng-if="key.separator && $last">

View File

@ -314,6 +314,7 @@ CREATE TABLE IF NOT EXISTS team_hints(
id_team INTEGER,
id_hint INTEGER,
time TIMESTAMP NOT NULL,
coefficient FLOAT NOT NULL DEFAULT 1.0,
CONSTRAINT uc_displayed UNIQUE (id_team,id_hint),
FOREIGN KEY(id_hint) REFERENCES exercice_hints(id_hint),
FOREIGN KEY(id_team) REFERENCES teams(id_team)
@ -326,6 +327,7 @@ CREATE TABLE IF NOT EXISTS team_wchoices(
id_team INTEGER,
id_flag INTEGER,
time TIMESTAMP NOT NULL,
coefficient FLOAT NOT NULL DEFAULT 1.0,
CONSTRAINT uc_displayed UNIQUE (id_team,id_flag),
FOREIGN KEY(id_flag) REFERENCES exercice_flags(id_flag),
FOREIGN KEY(id_team) REFERENCES teams(id_team)

View File

@ -5,6 +5,9 @@ import (
"strings"
)
// HintCoefficient is the current coefficient applied on its cost lost per showing
var HintCoefficient = 1.0
// EHint represents a challenge hint.
type EHint struct {
Id int64 `json:"id"`

View File

@ -30,8 +30,8 @@ func exoptsQuery(whereExo string) string {
func teamptsQuery() string {
return exoptsQuery("") + ` UNION ALL
SELECT D.id_team, D.time, H.cost AS points, -1.0 AS coeff, "Hint" AS reason, H.id_exercice FROM team_hints D INNER JOIN exercice_hints H ON H.id_hint = D.id_hint HAVING points != 0 UNION ALL
SELECT W.id_team, W.time, F.choices_cost AS points, -1.0 AS coeff, "Display choices" AS reason, F.id_exercice FROM team_wchoices W INNER JOIN exercice_flags F ON F.id_flag = W.id_flag HAVING points != 0`
SELECT D.id_team, D.time, H.cost AS points, D.coefficient * -1 AS coeff, "Hint" AS reason, H.id_exercice FROM team_hints D INNER JOIN exercice_hints H ON H.id_hint = D.id_hint HAVING points != 0 UNION ALL
SELECT W.id_team, W.time, F.choices_cost AS points, W.coefficient * -1 AS coeff, "Display choices" AS reason, F.id_exercice FROM team_wchoices W INNER JOIN exercice_flags F ON F.id_flag = W.id_flag HAVING points != 0`
}
func rankQuery(whereTeam string) string {

View File

@ -2,12 +2,16 @@ package fic
import (
"log"
"math"
"time"
)
// UnlockedChallenges disables dependancy requirement between challenges.
var UnlockedChallenges bool
// WchoiceCoefficient is the current coefficient applied on the cost of changing flag into choices
var WChoiceCoefficient = 1.0
// Team represents a group of players, come to solve our challenges.
type Team struct {
Id int64 `json:"id"`
@ -174,7 +178,7 @@ func (t Team) HasHint(h EHint) (bool) {
// OpenHint registers to the database that the Team has now revealed.
func (t Team) OpenHint(h EHint) (error) {
_, err := DBExec("INSERT INTO team_hints (id_team, id_hint, time) VALUES (?, ?, ?)", t.Id, h.Id, time.Now())
_, err := DBExec("INSERT INTO team_hints (id_team, id_hint, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, h.Id, time.Now(), math.Max(HintCoefficient, 0.0))
return err
}
@ -187,7 +191,7 @@ func (t Team) SeeChoices(k FlagKey) (bool) {
// DisplayChoices registers to the database that the Team has now revealed.
func (t Team) DisplayChoices(k FlagKey) (error) {
_, err := DBExec("INSERT INTO team_wchoices (id_team, id_flag, time) VALUES (?, ?, ?)", t.Id, k.Id, time.Now())
_, err := DBExec("INSERT INTO team_wchoices (id_team, id_flag, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, k.Id, time.Now(), math.Max(WChoiceCoefficient, 0.0))
return err
}

View File

@ -161,7 +161,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
return nil, err
} else {
for _, h := range hints {
if t == nil || t.HasHint(h) {
if t == nil || HintCoefficient < 0 || t.HasHint(h) {
exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, h.Content, h.File, h.Cost})
} else {
exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, "", "", h.Cost})
@ -210,7 +210,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
flag.Help = k.Help
if choices, err := k.GetChoices(); err != nil {
return nil, err
} else if t == nil || k.ChoicesCost == 0 || t.SeeChoices(k) {
} else if t == nil || WChoiceCoefficient < 0 || k.ChoicesCost == 0 || t.SeeChoices(k) {
flag.Choices = map[string]string{}
for _, c := range choices {
flag.Choices[c.Value] = c.Label

View File

@ -40,6 +40,10 @@ type FICSettings struct {
FirstBlood float64 `json:"firstBlood"`
// SubmissionCostBase is a complex number representing the cost of each attempts.
SubmissionCostBase float64 `json:"submissionCostBase"`
// HintCurrentCoefficient is the current coefficient applied to hint discovery.
HintCurCoefficient float64 `json:"hintCurrentCoefficient"`
// WChoiceCurCoefficient is the current coefficient applied to wanted choices.
WChoiceCurCoefficient float64 `json:"wchoiceCurrentCoefficient"`
// AllowRegistration permits unregistered Team to register themselves.
AllowRegistration bool `json:"allowRegistration"`