Skip to content

Commit a1d126c

Browse files
refactor(elections): remove mutable enum state and delegate operations to service
Remove mutable color field from SkyBlockMayor, use ElectionData.colorForIndex() instead. Remove local resolveElection/saveToService from ElectionManager, delegate to service endpoints. Fix loadFromService to not require minister for special mayors.
1 parent 7c3ab1c commit a1d126c

3 files changed

Lines changed: 76 additions & 222 deletions

File tree

type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionData.java

Lines changed: 17 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public class ElectionData {
2727
private String ministerPerk;
2828

2929
private List<CandidateData> candidates = new ArrayList<>();
30-
private transient Map<String, String> votes = new HashMap<>();
3130
private Map<String, Long> voteTallies = new HashMap<>();
3231
private boolean electionOpen;
3332

@@ -42,7 +41,7 @@ public ElectionData() {}
4241
public SkyBlockMayor getMayorEnum() {
4342
if (currentMayor == null) return null;
4443
try {
45-
return SkyBlockMayor.valueOf(currentMayor).setColor(currentMayorColor);
44+
return SkyBlockMayor.valueOf(currentMayor);
4645
} catch (IllegalArgumentException e) {
4746
return null;
4847
}
@@ -51,7 +50,7 @@ public SkyBlockMayor getMayorEnum() {
5150
public SkyBlockMayor getMinisterEnum() {
5251
if (currentMinister == null) return null;
5352
try {
54-
return SkyBlockMayor.valueOf(currentMinister).setColor(currentMinisterColor);
53+
return SkyBlockMayor.valueOf(currentMinister);
5554
} catch (IllegalArgumentException e) {
5655
return null;
5756
}
@@ -77,150 +76,17 @@ public List<SkyBlockMayor.Perk> getCurrentMayorPerkEnums() {
7776
}
7877

7978
public Map<String, Long> tallyVotes() {
80-
if (!voteTallies.isEmpty()) {
81-
return new HashMap<>(voteTallies);
82-
}
83-
Map<String, Long> tally = new HashMap<>();
84-
for (CandidateData candidate : candidates) {
85-
tally.put(candidate.getMayorName(), 0L);
86-
}
87-
for (String candidateName : votes.values()) {
88-
tally.merge(candidateName, 1L, Long::sum);
89-
}
90-
return tally;
79+
return new HashMap<>(voteTallies);
9180
}
9281

9382
public void updateTallies(Map<String, Long> newTallies) {
9483
voteTallies.clear();
9584
voteTallies.putAll(newTallies);
9685
}
9786

98-
public void incrementTally(String candidateName, String previousVote) {
99-
if (previousVote != null) {
100-
voteTallies.computeIfPresent(previousVote, (k, v) -> Math.max(0, v - 1));
101-
}
102-
voteTallies.merge(candidateName, 1L, Long::sum);
103-
}
104-
105-
public void resolveElection(int currentYear) {
106-
Map<String, Long> tally = tallyVotes();
107-
List<Map.Entry<String, Long>> sorted = new ArrayList<>(tally.entrySet());
108-
sorted.sort((a, b) -> Long.compare(b.getValue(), a.getValue()));
109-
110-
if (sorted.isEmpty()) return;
111-
112-
long topVotes = sorted.getFirst().getValue();
113-
List<Map.Entry<String, Long>> tied = sorted.stream()
114-
.filter(e -> e.getValue() == topVotes).toList();
115-
116-
String winnerName;
117-
if (tied.size() > 1) {
118-
winnerName = tied.get(ThreadLocalRandom.current().nextInt(tied.size())).getKey();
119-
} else {
120-
winnerName = sorted.getFirst().getKey();
121-
}
122-
123-
SkyBlockMayor winner = SkyBlockMayor.valueOf(winnerName);
124-
125-
CandidateData winnerCandidate = candidates.stream()
126-
.filter(c -> c.getMayorName().equals(winnerName))
127-
.findFirst().orElse(null);
128-
129-
currentMayor = winnerName;
130-
currentMayorColor = winner.getColor();
131-
currentMayorPerks = winnerCandidate != null
132-
? new ArrayList<>(winnerCandidate.getActivePerks())
133-
: Arrays.stream(winner.getAllPerks()).map(Enum::name).toList();
134-
mayorElectedYear = currentYear;
135-
lastElectedYear.put(winnerName, currentYear);
136-
137-
if (winner.isSpecial()) {
138-
currentMinister = null;
139-
ministerPerk = null;
140-
currentMinisterColor = null;
141-
} else {
142-
String secondPlace = sorted.stream().filter(entry -> !entry.getKey().equals(winnerName)).findFirst().map(Map.Entry::getKey).orElse(null);
143-
if (secondPlace != null) {
144-
SkyBlockMayor ministerMayor = SkyBlockMayor.valueOf(secondPlace);
145-
currentMinister = secondPlace;
146-
currentMinisterColor = ministerMayor.getColor();
147-
148-
CandidateData ministerCandidate = candidates.stream()
149-
.filter(c -> c.getMayorName().equals(secondPlace))
150-
.findFirst().orElse(null);
151-
152-
if (ministerCandidate != null && !ministerCandidate.getActivePerks().isEmpty()) {
153-
List<String> perks = ministerCandidate.getActivePerks();
154-
ministerPerk = perks.get(ThreadLocalRandom.current().nextInt(perks.size()));
155-
} else {
156-
SkyBlockMayor.Perk[] allPerks = ministerMayor.getAllPerks();
157-
ministerPerk = allPerks[ThreadLocalRandom.current().nextInt(allPerks.length)].name();
158-
}
159-
}
160-
}
161-
162-
for (CandidateData candidate : candidates) {
163-
if (candidate.getMayorName().equals(winnerName)) {
164-
candidateActivePerks.remove(winnerName);
165-
failedPerkGainLastTime.remove(winnerName);
166-
continue;
167-
}
168-
169-
SkyBlockMayor mayor = SkyBlockMayor.valueOf(candidate.getMayorName());
170-
if (mayor.isSpecial()) continue;
171-
172-
List<String> currentPerks = new ArrayList<>(candidate.getActivePerks());
173-
if (currentPerks.size() < mayor.getAllPerks().length) {
174-
boolean failedLast = Boolean.TRUE.equals(failedPerkGainLastTime.get(candidate.getMayorName()));
175-
boolean gainPerk = failedLast || ThreadLocalRandom.current().nextBoolean();
176-
177-
if (gainPerk) {
178-
List<String> available = new ArrayList<>();
179-
for (SkyBlockMayor.Perk perk : mayor.getAllPerks()) {
180-
if (!currentPerks.contains(perk.name())) {
181-
available.add(perk.name());
182-
}
183-
}
184-
if (!available.isEmpty()) {
185-
currentPerks.add(available.get(ThreadLocalRandom.current().nextInt(available.size())));
186-
}
187-
failedPerkGainLastTime.put(candidate.getMayorName(), false);
188-
} else {
189-
failedPerkGainLastTime.put(candidate.getMayorName(), true);
190-
}
191-
}
192-
candidateActivePerks.put(candidate.getMayorName(), currentPerks);
193-
}
194-
195-
SkyBlockMayor winnerEnum = SkyBlockMayor.valueOf(winnerName);
196-
if (!winnerEnum.isSpecial()) {
197-
SkyBlockMayor.Perk[] allPerks = winnerEnum.getAllPerks();
198-
SkyBlockMayor.Perk randomPerk = allPerks[ThreadLocalRandom.current().nextInt(allPerks.length)];
199-
candidateActivePerks.put(winnerName, List.of(randomPerk.name()));
200-
}
201-
202-
long totalVoteCount = tally.values().stream().mapToLong(Long::longValue).sum();
203-
ElectionResult electionResult = new ElectionResult();
204-
electionResult.setYear(currentYear);
205-
for (Map.Entry<String, Long> entry : sorted) {
206-
CandidateResult cr = new CandidateResult();
207-
cr.setMayorName(entry.getKey());
208-
cr.setVotes(entry.getValue());
209-
cr.setPercentage(totalVoteCount > 0 ? (entry.getValue() * 100.0) / totalVoteCount : 0);
210-
electionResult.getCandidateResults().add(cr);
211-
}
212-
this.lastElectionResult = electionResult;
213-
214-
candidates.clear();
215-
votes.clear();
216-
voteTallies.clear();
217-
electionOpen = false;
218-
}
219-
22087
public void startNewElection(int year) {
22188
this.electionYear = year;
22289
this.electionOpen = true;
223-
this.votes.clear();
22490
this.voteTallies.clear();
22591
this.candidates.clear();
22692

@@ -258,7 +124,7 @@ public void startNewElection(int year) {
258124

259125
CandidateData candidate = new CandidateData();
260126
candidate.setMayorName(specialCandidate.name());
261-
candidate.setIndex(selected.indexOf(specialCandidate));
127+
candidate.setIndex(candidates.size());
262128
candidate.setActivePerks(Arrays.stream(specialCandidate.getAllPerks()).map(Enum::name).toList());
263129
candidates.add(candidate);
264130
}
@@ -274,7 +140,7 @@ public void startNewElection(int year) {
274140
if (!alreadyInElection) {
275141
CandidateData diazCandidate = new CandidateData();
276142
diazCandidate.setMayorName(SkyBlockMayor.DIAZ.name());
277-
diazCandidate.setIndex(selected.indexOf(SkyBlockMayor.DIAZ));
143+
diazCandidate.setIndex(candidates.size());
278144
diazCandidate.setActivePerks(Arrays.stream(SkyBlockMayor.DIAZ.getAllPerks()).map(Enum::name).toList());
279145
candidates.add(diazCandidate);
280146
}
@@ -287,6 +153,17 @@ public int getYearsSinceLastElected(String mayorName, int currentYear) {
287153
return currentYear - lastYear;
288154
}
289155

156+
public static String colorForIndex(int index) {
157+
return switch (index) {
158+
case 0 -> "§c";
159+
case 1 -> "§a";
160+
case 2 -> "§b";
161+
case 3 -> "§e";
162+
case 4 -> "§d";
163+
default -> "§f";
164+
};
165+
}
166+
290167
@Getter
291168
@Setter
292169
public static class CandidateData {
@@ -315,14 +192,7 @@ public List<SkyBlockMayor.Perk> getActivePerkEnums() {
315192
}
316193

317194
public String getColor() {
318-
return switch (index) {
319-
case 0 -> "§c";
320-
case 1 -> "§a";
321-
case 2 -> "§b";
322-
case 3 -> "§e";
323-
case 4 -> "§d";
324-
default -> "§f";
325-
};
195+
return colorForIndex(index);
326196
}
327197

328198
public String getColoredName() {

0 commit comments

Comments
 (0)