From 5d612bd3b33c26be43af83da328a3985a6d1bbff Mon Sep 17 00:00:00 2001 From: Software Magico Date: Mon, 13 Nov 2023 20:22:06 +0100 Subject: [PATCH] Generated Stormtrooper Syndrome logic --- README.md | 2 +- .../controller/AchievementController.java | 105 +++++++++++++++++- .../achievements/ScoreAchievementsTest.java | 60 ++++++++++ frontend/src/assets/i18n/ca.json | 6 +- frontend/src/assets/i18n/de.json | 6 +- frontend/src/assets/i18n/en.json | 6 +- frontend/src/assets/i18n/es.json | 6 +- frontend/src/assets/i18n/it.json | 6 +- frontend/src/assets/i18n/nl.json | 6 +- 9 files changed, 190 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fcc179de3..5e8fccadd 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![GitHub commit activity](https://img.shields.io/github/commit-activity/y/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager) [![GitHub last commit](https://img.shields.io/github/last-commit/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager) [![CircleCI](https://circleci.com/gh/softwaremagico/KendoTournamentManager.svg?style=shield)](https://circleci.com/gh/softwaremagico/KendoTournamentManager) -[![Time](https://img.shields.io/badge/development-514h-blueviolet.svg)]() +[![Time](https://img.shields.io/badge/development-514.5h-blueviolet.svg)]() [![Powered by](https://img.shields.io/badge/powered%20by%20java-orange.svg?logo=OpenJDK&logoColor=white)]() [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=kendo-tournament-backend&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=kendo-tournament-backend) diff --git a/backend/kendo-tournament-core/src/main/java/com/softwaremagico/kt/core/controller/AchievementController.java b/backend/kendo-tournament-core/src/main/java/com/softwaremagico/kt/core/controller/AchievementController.java index 164195a1a..67f40ba7f 100644 --- a/backend/kendo-tournament-core/src/main/java/com/softwaremagico/kt/core/controller/AchievementController.java +++ b/backend/kendo-tournament-core/src/main/java/com/softwaremagico/kt/core/controller/AchievementController.java @@ -33,16 +33,20 @@ import com.softwaremagico.kt.core.exceptions.TournamentNotFoundException; import com.softwaremagico.kt.core.providers.AchievementProvider; import com.softwaremagico.kt.core.providers.DuelProvider; +import com.softwaremagico.kt.core.providers.FightProvider; import com.softwaremagico.kt.core.providers.ParticipantProvider; import com.softwaremagico.kt.core.providers.RankingProvider; import com.softwaremagico.kt.core.providers.RoleProvider; +import com.softwaremagico.kt.core.providers.TeamProvider; import com.softwaremagico.kt.core.providers.TournamentProvider; import com.softwaremagico.kt.core.score.ScoreOfCompetitor; import com.softwaremagico.kt.core.score.ScoreOfTeam; import com.softwaremagico.kt.persistence.entities.Achievement; import com.softwaremagico.kt.persistence.entities.Duel; +import com.softwaremagico.kt.persistence.entities.Fight; import com.softwaremagico.kt.persistence.entities.Participant; import com.softwaremagico.kt.persistence.entities.Role; +import com.softwaremagico.kt.persistence.entities.Team; import com.softwaremagico.kt.persistence.entities.Tournament; import com.softwaremagico.kt.persistence.repositories.AchievementRepository; import com.softwaremagico.kt.persistence.values.AchievementGrade; @@ -120,8 +124,12 @@ public class AchievementController extends BasicInsertableController duelsFromTournament; + private List teamsFromTournament; + + private List fightsFromTournament; + private Map> scoresByParticipant = null; private Map> scoresReceivedByParticipant = null; private Map totalScoreFromParticipant = null; @@ -145,7 +157,8 @@ public class AchievementController extends BasicInsertableController getDuelsFromTournament() { return duelsFromTournament; } + private List getTeamsFromTournament() { + if (teamsFromTournament == null) { + teamsFromTournament = teamProvider.getAll(tournament); + } + return teamsFromTournament; + } + + private List getFightsFromTournament() { + if (fightsFromTournament == null) { + fightsFromTournament = fightProvider.getFights(tournament); + } + return fightsFromTournament; + } + private Map> getScoresByParticipant() { if (scoresByParticipant == null) { scoresByParticipant = new HashMap<>(); @@ -324,6 +353,8 @@ public List generateAchievements(TournamentDTO tournamentDTO) { this.totalScoreFromParticipant = null; this.totalScoreAgainstParticipant = null; this.rolesByParticipant = null; + this.fightsFromTournament = null; + this.teamsFromTournament = null; //Remove any achievement already calculated. getProvider().delete(tournament); @@ -363,6 +394,7 @@ public List generateAchievements(TournamentDTO tournamentDTO) { achievementsGenerated.addAll(generateTisButAScratchAchievement(tournament)); achievementsGenerated.addAll(generateFirstBloodAchievement(tournament)); achievementsGenerated.addAll(generateDarumaAchievement(tournament)); + achievementsGenerated.addAll(generateStormtrooperSyndromeAchievement(tournament)); // Now generate extra grades. achievementsGenerated.addAll(generateBillyTheKidAchievementBronze(tournament)); @@ -437,6 +469,9 @@ public List generateAchievements(TournamentDTO tournamentDTO) { achievementsGenerated.addAll(generateDarumaAchievementBronze(tournament)); achievementsGenerated.addAll(generateDarumaAchievementSilver(tournament)); achievementsGenerated.addAll(generateDarumaAchievementGold(tournament)); + achievementsGenerated.addAll(generateStormtrooperSyndromeAchievementBronze(tournament)); + achievementsGenerated.addAll(generateStormtrooperSyndromeAchievementSilver(tournament)); + achievementsGenerated.addAll(generateStormtrooperSyndromeAchievementGold(tournament)); return convertAll(achievementsGenerated); } @@ -718,7 +753,7 @@ private List generateJuggernautAchievement(Tournament tournament) { competitors.remove(duel.getCompetitor1()); } //No hits against him - if (duel.getCompetitor2Score().size() > 0) { + if (!duel.getCompetitor2Score().isEmpty()) { competitors.remove(duel.getCompetitor1()); } //Max score competitor 2. @@ -726,7 +761,7 @@ private List generateJuggernautAchievement(Tournament tournament) { competitors.remove(duel.getCompetitor2()); } //No hits against him - if (duel.getCompetitor1Score().size() > 0) { + if (!duel.getCompetitor1Score().isEmpty()) { competitors.remove(duel.getCompetitor2()); } }); @@ -1071,10 +1106,10 @@ private List generateLoveSharingAchievementGold(Tournament tourname private List generateTheCastleAchievement(Tournament tournament) { final List competitors = participantProvider.get(tournament, RoleType.COMPETITOR); getDuelsFromTournament().forEach(duel -> { - if (duel.getCompetitor2Score().size() > 0) { + if (!duel.getCompetitor2Score().isEmpty()) { competitors.remove(duel.getCompetitor1()); } - if (duel.getCompetitor1Score().size() > 0) { + if (!duel.getCompetitor1Score().isEmpty()) { competitors.remove(duel.getCompetitor2()); } }); @@ -1122,7 +1157,7 @@ private List generateTheCastleAchievementGold(Tournament tournament private List generateEntrenchedAchievement(Tournament tournament) { final List competitors = participantProvider.get(tournament, RoleType.COMPETITOR); getDuelsFromTournament().forEach(duel -> { - if (duel.getCompetitor1Score().size() > 0 || duel.getCompetitor2Score().size() > 0) { + if (!duel.getCompetitor1Score().isEmpty() || !duel.getCompetitor2Score().isEmpty()) { competitors.remove(duel.getCompetitor1()); competitors.remove(duel.getCompetitor2()); } @@ -1810,4 +1845,62 @@ private List generateDarumaAchievementGold(Tournament tournament) { }); return generateAchievement(AchievementType.DARUMA, AchievementGrade.GOLD, participantsDaruma, tournament); } + + /*** + * Be in a team, and all members of the teams does no score in the entire tournament. + * @param tournament The tournament to check. + * @return the generated achievements. + */ + private List generateStormtrooperSyndromeAchievement(Tournament tournament) { + final List teams = new ArrayList<>(getTeamsFromTournament()); + //Ensure that team is in fights. + final Set teamsWithFights = new HashSet<>(); + getFightsFromTournament().forEach(fight -> { + //Remove a tournament if it has some score. + fight.getDuels().forEach(duel -> { + if (!duel.getCompetitor1Score().isEmpty()) { + teams.remove(fight.getTeam1()); + } + if (!duel.getCompetitor2Score().isEmpty()) { + teams.remove(fight.getTeam2()); + } + }); + teamsWithFights.add(fight.getTeam1()); + teamsWithFights.add(fight.getTeam2()); + }); + teams.retainAll(teamsWithFights); + return generateAchievement(AchievementType.STORMTROOPER_SYNDROME, AchievementGrade.NORMAL, + teams.stream().flatMap(team -> team.getMembers().stream()).toList(), tournament); + } + + /** + * Achievement for the stormtrooper syndrome in two tournaments. + * + * @param tournament The tournament to check. + * @return a list of new achievements. + */ + private List generateStormtrooperSyndromeAchievementBronze(Tournament tournament) { + return generateConsecutiveGradeAchievements(tournament, DEFAULT_TOURNAMENT_NUMBER_BRONZE, + AchievementType.STORMTROOPER_SYNDROME, AchievementGrade.BRONZE); + } + + /*** + * Achievement for the stormtrooper syndrome in three tournaments. + * @param tournament The tournament to check. + * @return the generated achievements. + */ + private List generateStormtrooperSyndromeAchievementSilver(Tournament tournament) { + return generateConsecutiveGradeAchievements(tournament, DEFAULT_TOURNAMENT_NUMBER_SILVER, + AchievementType.STORMTROOPER_SYNDROME, AchievementGrade.SILVER); + } + + /*** + * Achievement for the stormtrooper syndrome in five tournaments. + * @param tournament The tournament to check. + * @return the generated achievements. + */ + private List generateStormtrooperSyndromeAchievementGold(Tournament tournament) { + return generateConsecutiveGradeAchievements(tournament, DEFAULT_TOURNAMENT_NUMBER_GOLD, + AchievementType.STORMTROOPER_SYNDROME, AchievementGrade.GOLD); + } } diff --git a/backend/kendo-tournament-core/src/test/java/com/softwaremagico/kt/core/tests/achievements/ScoreAchievementsTest.java b/backend/kendo-tournament-core/src/test/java/com/softwaremagico/kt/core/tests/achievements/ScoreAchievementsTest.java index 9b4a60e6d..860b7906c 100644 --- a/backend/kendo-tournament-core/src/test/java/com/softwaremagico/kt/core/tests/achievements/ScoreAchievementsTest.java +++ b/backend/kendo-tournament-core/src/test/java/com/softwaremagico/kt/core/tests/achievements/ScoreAchievementsTest.java @@ -63,6 +63,8 @@ public class ScoreAchievementsTest extends TournamentTestUtils { private static final String TOURNAMENT3_NAME = "Tournament 3"; + private static final String TOURNAMENT4_NAME = "Tournament 4"; + @Autowired private TournamentController tournamentController; @@ -78,6 +80,7 @@ public class ScoreAchievementsTest extends TournamentTestUtils { private TournamentDTO tournament1DTO; private TournamentDTO tournament2DTO; private TournamentDTO tournament3DTO; + private TournamentDTO tournament4DTO; private ParticipantDTO woodCutter; @@ -251,6 +254,56 @@ public void prepareTournament3() { achievementController.generateAchievements(tournament3DTO); } + @BeforeClass(dependsOnMethods = "prepareTournament3") + public void prepareTournament4() { + tournament4DTO = addTournament(TOURNAMENT4_NAME, MEMBERS, TEAMS, REFEREES, ORGANIZER, VOLUNTEER, PRESS, 1); + //Create Tournament + List fightDTOs = fightController.createFights(tournament4DTO.getId(), TeamsOrder.SORTED, 0, null); + + //Team1 and Team2 no scores. Team1 has no scores neither against itself. + + //Team1 vs Team2 + fightDTOs.get(0).getDuels().get(0).setFinished(true); + fightDTOs.get(0).getDuels().get(1).setFinished(true); + fightDTOs.get(0).getDuels().get(2).setFinished(true); + fightDTOs.set(0, fightController.update(fightDTOs.get(0), null)); + + //Team3 vs Team2 + fightDTOs.get(1).getDuels().get(0).addCompetitor1Score(Score.DO); + fightDTOs.get(1).getDuels().get(0).addCompetitor1ScoreTime(68); + fightDTOs.get(1).getDuels().get(0).setFinished(true); + fightDTOs.get(1).getDuels().get(1).setFinished(true); + fightDTOs.get(1).getDuels().get(2).setFinished(true); + fightDTOs.set(1, fightController.update(fightDTOs.get(1), null)); + + //Team3 vs Team4 + fightDTOs.get(2).getDuels().get(0).addCompetitor1Score(Score.DO); + fightDTOs.get(2).getDuels().get(0).addCompetitor1ScoreTime(68); + fightDTOs.get(2).getDuels().get(0).setFinished(true); + fightDTOs.get(2).getDuels().get(1).addCompetitor2Score(Score.MEN); + fightDTOs.get(2).getDuels().get(1).addCompetitor2ScoreTime(68); + fightDTOs.get(2).getDuels().get(1).setFinished(true); + fightDTOs.get(2).getDuels().get(2).setFinished(true); + fightDTOs.set(2, fightController.update(fightDTOs.get(2), null)); + + fightDTOs.get(3).getDuels().get(0).setFinished(true); + fightDTOs.get(3).getDuels().get(1).setFinished(true); + fightDTOs.get(3).getDuels().get(2).setFinished(true); + fightDTOs.set(3, fightController.update(fightDTOs.get(3), null)); + + fightDTOs.get(4).getDuels().get(0).setFinished(true); + fightDTOs.get(4).getDuels().get(1).setFinished(true); + fightDTOs.get(4).getDuels().get(2).setFinished(true); + fightDTOs.set(4, fightController.update(fightDTOs.get(4), null)); + + fightDTOs.get(5).getDuels().get(0).setFinished(true); + fightDTOs.get(5).getDuels().get(1).setFinished(true); + fightDTOs.get(5).getDuels().get(2).setFinished(true); + fightDTOs.set(5, fightController.update(fightDTOs.get(5), null)); + + achievementController.generateAchievements(tournament4DTO); + } + @Test public void checkWoodCutterAchievement() { List achievementsDTOs = achievementController.getAchievements(tournament1DTO, AchievementType.WOODCUTTER); @@ -381,6 +434,13 @@ public void firstBloodAchievement() { Assert.assertEquals(achievementsDTOs.size(), 6); } + @Test + public void stormtrooperAchievement() { + List achievementsDTOs = achievementController.getAchievements(tournament4DTO, AchievementType.STORMTROOPER_SYNDROME, AchievementGrade.NORMAL); + //Only Participant0, Participant1, Participant2, Participant3, Participant4, Participant5 + Assert.assertEquals(achievementsDTOs.size(), 6); + } + @AfterClass public void wipeOut() { super.wipeOut(); diff --git a/frontend/src/assets/i18n/ca.json b/frontend/src/assets/i18n/ca.json index 9d8efc2a7..31d10214c 100644 --- a/frontend/src/assets/i18n/ca.json +++ b/frontend/src/assets/i18n/ca.json @@ -825,7 +825,11 @@ }, "stormtrooperSyndrome": { "title": "Efecte stormtrooper", - "description": "Un equip falla tots els punts en un torneig." + "description": "Un equip falla tots els punts en un torneig.", + "normal": "Aconseguit en un torneig.", + "bronze": "Aconseguit en almenys dos tornejos successius.", + "silver": "Aconseguit en almenys tres tornejos successius.", + "gold": "Aconseguit en almenys cinc tornejos successius." } }, "removeTeams": "Treure Equips", diff --git a/frontend/src/assets/i18n/de.json b/frontend/src/assets/i18n/de.json index cb7127e93..ca815546e 100644 --- a/frontend/src/assets/i18n/de.json +++ b/frontend/src/assets/i18n/de.json @@ -813,7 +813,11 @@ }, "stormtrooperSyndrome": { "title": "Stormtrooper-Effekt", - "description": "Einem Team fehlen in einem Turnier alle Punkte." + "description": "Einem Team fehlen in einem Turnier alle Punkte.", + "normal": "Für ein Turnier erreicht.", + "bronze": "Erreicht in mindestens zwei aufeinanderfolgenden Turnieren erreicht.", + "silver": "Erreicht in mindestens drei aufeinanderfolgenden Turnieren erreicht.", + "gold": "Während mindestens fünf aufeinanderfolgenden Turnieren erreicht." } }, "removeTeams": "Teams entfernenn", diff --git a/frontend/src/assets/i18n/en.json b/frontend/src/assets/i18n/en.json index ee6cdfaa2..9bd0d5d75 100644 --- a/frontend/src/assets/i18n/en.json +++ b/frontend/src/assets/i18n/en.json @@ -836,7 +836,11 @@ }, "stormtrooperSyndrome": { "title": "Stormtrooper Syndrome", - "description": "A team miss all points on a tournament." + "description": "A team miss all points on a tournament.", + "normal": "Achieved for one tournament.", + "bronze": "Achieved for at least two consecutive tournaments.", + "silver": "Achieved for at least three consecutive tournaments.", + "gold": "Achieved for at least five consecutive tournaments." } }, "removeTeams": "Remove Teams", diff --git a/frontend/src/assets/i18n/es.json b/frontend/src/assets/i18n/es.json index b420b2bc1..126a3b697 100644 --- a/frontend/src/assets/i18n/es.json +++ b/frontend/src/assets/i18n/es.json @@ -826,7 +826,11 @@ }, "stormtrooperSyndrome": { "title": "Efecto stormtrooper", - "description": "Un equipo falla todos los puntos en un torneo." + "description": "Un equipo falla todos los puntos en un torneo.", + "normal": "Conseguido para un torneo.", + "bronze": "Logrado durante al menos dos torneos.", + "silver": "Logrado durante al menos tres torneos.", + "gold": "Logrado durante al menos cinco torneos." } }, "removeTeams": "Quitar equipos", diff --git a/frontend/src/assets/i18n/it.json b/frontend/src/assets/i18n/it.json index ce3b4d34e..42a05a418 100644 --- a/frontend/src/assets/i18n/it.json +++ b/frontend/src/assets/i18n/it.json @@ -819,7 +819,11 @@ }, "stormtrooperSyndrome": { "title": "Effetto Stormtrooper", - "description": "Una squadra sbaglia tutti i punti in un torneo." + "description": "Una squadra sbaglia tutti i punti in un torneo.", + "normal": "Ottenuto per un torneo.", + "bronze": "Ottenuto durante almeno due tornei consecutivi.", + "silver": "Ottenuto durante almeno tre tornei consecutivi.", + "gold": "Ottenuto durante almeno cinque tornei consecutivi." } }, "removeTeams": "Rimuovi squadre", diff --git a/frontend/src/assets/i18n/nl.json b/frontend/src/assets/i18n/nl.json index f5422500d..d723aaf7f 100644 --- a/frontend/src/assets/i18n/nl.json +++ b/frontend/src/assets/i18n/nl.json @@ -813,7 +813,11 @@ }, "stormtrooperSyndrome": { "title": "Stormtrooper-effect", - "description": "Een team mist alle punten in een toernooi." + "description": "Een team mist alle punten in een toernooi.", + "normal": "Bereikt voor één toernooi.", + "bronze": "Behaald tijdens ten minste twee opeenvolgende toernooien.", + "silver": "Behaald tijdens ten minste drie opeenvolgende toernooien.", + "gold": "Behaald tijdens ten minste vijf opeenvolgende toernooien." } }, "removeTeams": "Teams verwijderen",