Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Turnierplan.App/Client/src/app/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,11 @@ export const de = {
MatchWonPoints: 'Punkte für Sieg:',
MatchDrawnPoints: 'Punkte für Unentschieden:',
MatchLostPoints: 'Punkte für Niederlage:',
HigherScoreLoses: {
Label: 'Ergebnis invertieren:',
Tooltip: 'Wenn aktiviert, ist diejenige Mannschaft, welche weniger Tore geschossen hat, der Gewinner vom Spiel.',
Activated: 'Die Ergebnisse werden invertiert. Das heißt, die Mannschaft mit weniger Toren gewinnt.'
},
ComparisonModes: {
Label: 'Platzierungsregel in Gruppen:',
Values: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ <h4 class="modal-title" translate="Portal.ViewTournament.Settings.EditComputatio
</div>
</div>

<div class="mb-4 row align-items-center">
<div class="col-4">
<label
class="form-label mb-0"
for="higherScoreLoses"
translate="Portal.ViewTournament.Settings.EditComputationConfig.Properties.HigherScoreLoses.Label"></label>
</div>
<div class="col-8 d-flex flex-row align-items-center gap-1">
<div class="form-check form-switch">
<input class="form-check-input" id="higherScoreLoses" type="checkbox" [(ngModel)]="higherScoreLoses" />
</div>
<i
class="bi bi-info-circle"
[ngbTooltip]="'Portal.ViewTournament.Settings.EditComputationConfig.Properties.HigherScoreLoses.Tooltip' | translate"></i>
</div>
</div>

<label
class="form-label"
for="comparisonModes"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class ComputationConfigurationComponent {
protected matchWonPoints: number = 0;
protected matchDrawnPoints: number = 0;
protected matchLostPoints: number = 0;
protected higherScoreLoses: boolean = false;

protected standardComparisonModeOptions: ComparisonModeOption[] = [];
protected nonStandardComparisonModeOptions: ComparisonModeOption[] = [];
Expand All @@ -37,6 +38,7 @@ export class ComputationConfigurationComponent {
this.matchWonPoints = computationConfiguration.matchWonPoints;
this.matchDrawnPoints = computationConfiguration.matchDrawnPoints;
this.matchLostPoints = computationConfiguration.matchLostPoints;
this.higherScoreLoses = computationConfiguration.higherScoreLoses;

this.comparisonModeOptionId = '';
for (const option of availableComparisonModeOptions) {
Expand Down Expand Up @@ -67,6 +69,7 @@ export class ComputationConfigurationComponent {
matchWonPoints: this.matchWonPoints,
matchDrawnPoints: this.matchDrawnPoints,
matchLostPoints: this.matchLostPoints,
higherScoreLoses: this.higherScoreLoses,
comparisonModes: [...(comparisonModes ?? [])]
});
this.save$.complete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@
<span translate="Portal.ViewTournament.Settings.EditComputationConfig.Properties.MatchLostPoints"></span>
<span class="fw-bold">{{ tournament.computationConfiguration.matchLostPoints }}</span>
</div>
@if (tournament.computationConfiguration.higherScoreLoses) {
<div
class="mb-2"
translate="Portal.ViewTournament.Settings.EditComputationConfig.Properties.HigherScoreLoses.Activated"></div>
}
<div class="mb-3 d-flex flex-row">
<span class="me-2" translate="Portal.ViewTournament.Settings.EditComputationConfig.Properties.ComparisonModes.Label"></span>
@for (entry of tournament.computationConfiguration.comparisonModes; track entry; let isLast = $last) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private static async Task<IResult> Handle(
MatchWonPoints = request.Configuration.MatchWonPoints,
MatchDrawnPoints = request.Configuration.MatchDrawnPoints,
MatchLostPoints = request.Configuration.MatchLostPoints,
HigherScoreLoses = request.Configuration.HigherScoreLoses,
ComparisonModes = request.Configuration.ComparisonModes.ToList()
};

Expand Down
1 change: 1 addition & 0 deletions src/Turnierplan.App/Mapping/Rules/TournamentMappingRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ protected override TournamentDto Map(IMapper mapper, MappingContext context, Tou
MatchWonPoints = source.ComputationConfiguration.MatchWonPoints,
MatchDrawnPoints = source.ComputationConfiguration.MatchDrawnPoints,
MatchLostPoints = source.ComputationConfiguration.MatchLostPoints,
HigherScoreLoses = source.ComputationConfiguration.HigherScoreLoses,
ComparisonModes = source.ComputationConfiguration.ComparisonModes.ToArray()
},
PresentationConfiguration = mapper.Map<PresentationConfigurationDto>(source.PresentationConfiguration)
Expand Down
2 changes: 2 additions & 0 deletions src/Turnierplan.App/Models/ComputationConfigurationDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ public sealed record ComputationConfigurationDto

public required int MatchLostPoints { get; init; }

public required bool HigherScoreLoses { get; init; }

public required TeamComparisonMode[] ComparisonModes { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,58 @@ public sealed class TeamGroupStatisticsTest
}
};

public static readonly TheoryData<(int GoalsFor, int GoalsAgainst)[], TeamGroupStatistics> AddMatchOutcomeWhenHigherScoreLosesTestData = new()
{
{
[
(GoalsFor: 2, GoalsAgainst: 3),
(GoalsFor: 1, GoalsAgainst: 1),
(GoalsFor: 4, GoalsAgainst: 0)
],
new TeamGroupStatistics
{
ScoreFor = 2 + 1 + 4,
ScoreAgainst = 3 + 1 + 0,
MatchesWon = 1,
MatchesDrawn = 1,
MatchesLost = 1,
Points = 4
}
},
{
[
(GoalsFor: 1, GoalsAgainst: 0),
(GoalsFor: 2, GoalsAgainst: 2)
],
new TeamGroupStatistics
{
ScoreFor = 1 + 2,
ScoreAgainst = 0 + 2,
MatchesWon = 0,
MatchesDrawn = 1,
MatchesLost = 1,
Points = 1
}
},
{
[
(GoalsFor: 1, GoalsAgainst: 1),
(GoalsFor: 2, GoalsAgainst: 0),
(GoalsFor: 1, GoalsAgainst: 3),
(GoalsFor: 2, GoalsAgainst: 2)
],
new TeamGroupStatistics
{
ScoreFor = 1 + 2 + 1 + 2,
ScoreAgainst = 1 + 0 + 3 + 2,
MatchesWon = 1,
MatchesDrawn = 2,
MatchesLost = 1,
Points = 5
}
}
};

[Theory]
[InlineData(7, 3, 4)]
[InlineData(3, 7, -4)]
Expand Down Expand Up @@ -101,7 +153,7 @@ public void TeamGroupResults___Add_Match_Outcome___Works_As_Expected((int GoalsF

[Theory]
[MemberData(nameof(AddMatchOutcomeTestData))]
public void TeamGroupResults___Add_Match_Outcome_With_Custom_Computation_Configuration___Works_As_Expected((int GoalsFor, int GoalsAgainst)[] matchOutcomes, TeamGroupStatistics expectedResults)
public void TeamGroupResults___Add_Match_Outcome_With_Custom_Point_Counts___Works_As_Expected((int GoalsFor, int GoalsAgainst)[] matchOutcomes, TeamGroupStatistics expectedResults)
{
// Arrange
var results = new TeamGroupStatistics();
Expand All @@ -119,4 +171,22 @@ public void TeamGroupResults___Add_Match_Outcome_With_Custom_Computation_Configu
Points = expectedResults.MatchesDrawn * 2 + expectedResults.MatchesWon * 5
});
}

[Theory]
[MemberData(nameof(AddMatchOutcomeWhenHigherScoreLosesTestData))]
public void TeamGroupResults___Add_Match_Outcome_With_HigherScoreLoses_Enabled___Works_As_Expected((int GoalsFor, int GoalsAgainst)[] matchOutcomes, TeamGroupStatistics expectedResults)
{
// Arrange
var results = new TeamGroupStatistics();
var configuration = new ComputationConfiguration { HigherScoreLoses = true };

// Act
foreach (var matchOutcome in matchOutcomes)
{
results.AddMatchOutcome(matchOutcome.GoalsFor, matchOutcome.GoalsAgainst, configuration);
}

// Assert
results.Should().BeEquivalentTo(expectedResults);
}
}
3 changes: 3 additions & 0 deletions src/Turnierplan.Core/Tournament/ComputationConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public sealed record ComputationConfiguration
[JsonPropertyName("l")]
public int MatchLostPoints { get; set; } = 0;

[JsonPropertyName("r")]
public bool HigherScoreLoses { get; set; } = false;

[JsonPropertyName("cmp")]
public List<TeamComparisonMode> ComparisonModes { get; set; } = [..__defaultTeamComparisonModes];
}
35 changes: 27 additions & 8 deletions src/Turnierplan.Core/Tournament/TeamGroupStatistics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,39 @@ internal void AddMatchOutcome(int scoreFor, int scoreAgainst, ComputationConfigu
ScoreFor += scoreFor;
ScoreAgainst += scoreAgainst;

if (scoreFor > scoreAgainst)
{
MatchesWon++;
Points += computationConfiguration.MatchWonPoints;
}
else if (scoreFor == scoreAgainst)
if (scoreFor == scoreAgainst)
{
MatchesDrawn++;
Points += computationConfiguration.MatchDrawnPoints;

return;
}

if (computationConfiguration.HigherScoreLoses)
{
if (scoreFor > scoreAgainst)
{
MatchesLost++;
Points += computationConfiguration.MatchLostPoints;
}
else
{
MatchesWon++;
Points += computationConfiguration.MatchWonPoints;
}
}
else
{
MatchesLost++;
Points += computationConfiguration.MatchLostPoints;
if (scoreFor > scoreAgainst)
{
MatchesWon++;
Points += computationConfiguration.MatchWonPoints;
}
else
{
MatchesLost++;
Points += computationConfiguration.MatchLostPoints;
}
}
}
}
Loading
Loading