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
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void setCapacity(int capacity) {
*/
@Override
public boolean canJoin() {
return capacity == DEFAULT_CAPACITY || players.size() != capacity;
return capacity == DEFAULT_CAPACITY || players.size() < capacity;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ public class Splitter {
* @param evenTeams if teams should be forced to be even
* @param lowVariance if low variance is preferred
* @return optimal desired teams constellation
* @throws IllegalArgumentException if {@code evenTeams} is set without {@code lowVariance} and the players don't fit into the teams
*/
public DistributionTeam[] compute(DistributionTeam[] ts, DistributionPlayer[] ps, List<Integer> is, int teamSize, boolean evenTeams, boolean lowVariance) {
if (evenTeams && !lowVariance) {
validateCapacity(ts, ps, is, teamSize);
}
//initialize
this.ps = ps;
this.evenTeams = evenTeams;
Expand All @@ -54,6 +58,31 @@ public DistributionTeam[] compute(DistributionTeam[] ts, DistributionPlayer[] ps
return this.ts;
}

/**
* Checks if all players fit into the teams without exceeding the team size.
*
* @param ts outline for teams
* @param ps players
* @param is used player array indices
* @param teamSize size of each team
* @throws IllegalArgumentException if a team already exceeds the team size or not all players fit into the teams
*/
private void validateCapacity(DistributionTeam[] ts, DistributionPlayer[] ps, List<Integer> is, int teamSize) {
int assignedPlayers = 0;
for (DistributionTeam team : ts) {
if (team.length() > teamSize) {
throw new IllegalArgumentException("The team " + team.name().asString() + " already exceeds the team size of " + teamSize);
}
assignedPlayers += team.length();
}

int totalPlayers = assignedPlayers + ps.length - is.size();
int capacity = ts.length * teamSize;
if (totalPlayers > capacity) {
throw new IllegalArgumentException("Unable to distribute " + totalPlayers + " players into " + ts.length + " teams with a size of " + teamSize);
}
}

/**
* @param i current position in players array
* @param ts team array in development
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/net/theevilreaper/xerus/api/team/TeamTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package net.theevilreaper.xerus.api.team;

import net.kyori.adventure.key.Key;
import net.minestom.server.entity.Player;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -44,4 +47,19 @@ void testTeamEquality() {
assertEquals(team1, team2);
assertEquals(team1.hashCode(), team2.hashCode());
}

@Test
void testCanJoinWhenOverCapacity() {
Team team = Team.of(Key.key("xerus", "test"), 5);
for (int i = 0; i < 3; i++) {
team.getPlayers().add(Mockito.mock(Player.class));
}
assertTrue(team.canJoin());

team.setCapacity(3);
assertFalse(team.canJoin());

team.setCapacity(2);
assertFalse(team.canJoin());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package net.theevilreaper.xerus.api.team.distribution;

import net.kyori.adventure.key.Key;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.ArrayList;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;

class SplitterTest {

private static DistributionTeam[] createTeams(int amount) {
DistributionTeam[] teams = new DistributionTeam[amount];
for (int i = 0; i < amount; i++) {
teams[i] = new DistributionTeam(Key.key("xerus", "team" + i));
}
return teams;
}

private static DistributionPlayer[] createPlayers(int amount) {
DistributionPlayer[] players = new DistributionPlayer[amount];
for (int i = 0; i < amount; i++) {
players[i] = new DistributionPlayer(UUID.randomUUID(), 100 + i);
}
return players;
}

@Test
void testTooManyPlayersForEvenTeams() {
DistributionTeam[] teams = createTeams(2);
DistributionPlayer[] players = createPlayers(5);
Splitter splitter = new Splitter();

assertThrowsExactly(
IllegalArgumentException.class,
() -> splitter.compute(teams, players, new ArrayList<>(), 2, true, false)
);
}

@Test
void testTooManyPlayersWithExistingTeamMembers() {
DistributionTeam[] teams = createTeams(2);
teams[0].add(new DistributionPlayer(UUID.randomUUID(), 100));
DistributionPlayer[] players = createPlayers(4);
Splitter splitter = new Splitter();

assertThrowsExactly(
IllegalArgumentException.class,
() -> splitter.compute(teams, players, new ArrayList<>(), 2, true, false)
);
}

@ParameterizedTest
@ValueSource(booleans = {true, false})
void testPlayersFitIntoEvenTeams(boolean lowVariance) {
DistributionTeam[] teams = createTeams(2);
DistributionPlayer[] players = createPlayers(4);

DistributionTeam[] result = new Splitter().compute(teams, players, new ArrayList<>(), 2, true, lowVariance);

assertNotNull(result);
for (DistributionTeam team : result) {
assertEquals(2, team.length());
}
}

@ParameterizedTest
@ValueSource(booleans = {true, false})
void testUnevenTeamsIgnoreTeamSize(boolean lowVariance) {
DistributionTeam[] teams = createTeams(2);
DistributionPlayer[] players = createPlayers(5);

DistributionTeam[] result = new Splitter().compute(teams, players, new ArrayList<>(), 2, false, lowVariance);

assertNotNull(result);
assertEquals(5, result[0].length() + result[1].length());
}
}
Loading