Skip to content

Commit

Permalink
✨ Added the ability to set Iterations
Browse files Browse the repository at this point in the history
Signed-off-by: Tomáš Vojík <vojik@wboy.cz>
  • Loading branch information
Heroyt committed Sep 30, 2023
1 parent eb1a925 commit 6b77b32
Show file tree
Hide file tree
Showing 17 changed files with 1,815 additions and 1,355 deletions.
Binary file modified build/coverage.serialized
Binary file not shown.
2,298 changes: 1,188 additions & 1,110 deletions build/coverage.xml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/TournamentGenerator/Export/Hierarchy/SetupExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ protected function getTournamentData(array &$data): void {
'type' => $this->object instanceof Preset ? get_class($this->object) : 'general',
'name' => $this->object->getName(),
'skip' => $this->object->getSkip(),
'iterations' => $this->object->getIterationCount(),
'timing' => (object)[
'play' => $this->object->getPlay(),
'gameWait' => $this->object->getGameWait(),
Expand Down Expand Up @@ -170,6 +171,7 @@ protected function getRoundData(Round $round): object {
'groups' => $round instanceof WithGroups ? $round->queryGroups()->ids()->get() : [],
'teams' => $round instanceof WithTeams ? $round->getTeamContainer()->ids()->unique()->get() : [],
'games' => $round instanceof WithGames ? $round->getGameContainer()->ids()->get() : [],
'iterations' => $round->getIterationCount(),
];
}

Expand Down Expand Up @@ -212,6 +214,7 @@ protected function getGroupData(Group $group): object {
'name' => $group->getName(),
'type' => $group->getType(),
'skip' => $group->getSkip(),
'iterations' => $group->getIterationCount(),
'points' => (object)[
'win' => $group->getWinPoints(),
'loss' => $group->getLostPoints(),
Expand Down
8 changes: 8 additions & 0 deletions src/TournamentGenerator/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use TournamentGenerator\Interfaces\WithSkipSetters;
use TournamentGenerator\Interfaces\WithTeams;
use TournamentGenerator\Traits\WithGames as WithGamesTrait;
use TournamentGenerator\Traits\WithIterations;
use TournamentGenerator\Traits\WithTeams as WithTeamsTrait;

/**
Expand All @@ -27,6 +28,7 @@ class Group extends HierarchyBase implements WithGeneratorSetters, WithSkipSette
{
use WithTeamsTrait;
use WithGamesTrait;
use WithIterations;

/** @var Helpers\Generator Generator class to generate games of this group */
protected Helpers\Generator $generator;
Expand Down Expand Up @@ -54,6 +56,7 @@ class Group extends HierarchyBase implements WithGeneratorSetters, WithSkipSette
/** @var int Group order in a round */
protected int $order = 0;


/**
* Group constructor.
*
Expand Down Expand Up @@ -598,4 +601,9 @@ public function jsonSerialize() : array {
];
}

public function setIterationCount(int $iterations): static {
$this->generator->setIterationCount($iterations);
$this->iterations = $iterations;
return $this;
}
}
97 changes: 71 additions & 26 deletions src/TournamentGenerator/Helpers/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use TournamentGenerator\Interfaces\WithGeneratorSetters;
use TournamentGenerator\Interfaces\WithSkipSetters;
use TournamentGenerator\Team;
use TournamentGenerator\Traits\WithIterations;
use TournamentGenerator\Traits\WithSkipSetters as WithSkipSettersTrait;

/**
Expand All @@ -23,6 +24,7 @@
class Generator implements WithGeneratorSetters, WithSkipSetters
{
use WithSkipSettersTrait;
use WithIterations;

/** @var Group Group object */
private Group $group;
Expand All @@ -33,6 +35,7 @@ class Generator implements WithGeneratorSetters, WithSkipSetters
/** @var int Maximum size of group before split */
private int $maxSize = 4;


/**
* Generator constructor.
*
Expand All @@ -47,7 +50,7 @@ public function __construct(Group $group) {
*
* @return string
*/
public function getType() : string {
public function getType(): string {
return $this->type;
}

Expand All @@ -59,12 +62,12 @@ public function getType() : string {
* @return $this
* @throws Exception
*/
public function setType(string $type = Constants::ROUND_ROBIN) : Generator {
public function setType(string $type = Constants::ROUND_ROBIN): Generator {
if (in_array($type, Constants::GroupTypes, true)) {
$this->type = $type;
}
else {
throw new Exception('Unknown group type: '.$type);
throw new Exception('Unknown group type: ' . $type);
}
return $this;
}
Expand All @@ -74,7 +77,7 @@ public function setType(string $type = Constants::ROUND_ROBIN) : Generator {
*
* @return int
*/
public function getInGame() : int {
public function getInGame(): int {
return $this->inGame;
}

Expand All @@ -86,9 +89,9 @@ public function getInGame() : int {
* @return $this
* @throws Exception
*/
public function setInGame(int $inGame) : Generator {
public function setInGame(int $inGame): Generator {
if ($inGame < 2 || $inGame > 4) {
throw new Exception('Expected 2,3 or 4 as inGame '.$inGame.' given');
throw new Exception('Expected 2,3 or 4 as inGame ' . $inGame . ' given');
}
$this->inGame = $inGame;
return $this;
Expand All @@ -99,7 +102,7 @@ public function setInGame(int $inGame) : Generator {
*
* @return int
*/
public function getMaxSize() : int {
public function getMaxSize(): int {
return $this->maxSize;
}

Expand All @@ -111,9 +114,9 @@ public function getMaxSize() : int {
* @return $this
* @throws Exception
*/
public function setMaxSize(int $size) : Generator {
public function setMaxSize(int $size): Generator {
if ($size < 2) {
throw new Exception('Max group size has to be at least 2, '.$size.' given');
throw new Exception('Max group size has to be at least 2, ' . $size . ' given');
}
$this->maxSize = $size;
return $this;
Expand All @@ -125,7 +128,7 @@ public function setMaxSize(int $size) : Generator {
* @return Game[] List of generated games
* @throws Exception
*/
public function genGames() : array {
public function genGames(): array {
switch ($this->type) {
case Constants::ROUND_ROBIN:
$this->group->addGame(...$this->r_rGames());
Expand All @@ -148,7 +151,7 @@ public function genGames() : array {
* @return Game[]
* @throws Exception
*/
protected function r_rGames(array $teams = []) : array {
protected function r_rGames(array $teams = []): array {
$games = [];
if (count($teams) === 0) {
$teams = $this->group->getTeams();
Expand All @@ -164,19 +167,22 @@ protected function r_rGames(array $teams = []) : array {
$games = $this->r_r4Games($teams, $games);
break;
}

$this->copyGameIterations($games);

return $games;
}

/**
* Generate games for round robin and 2 teams in one game
* Generate games for round-robin and 2 teams in one game
*
* @param array $teams
* @param Group $group
*
* @return Game[]
* @throws Exception
*/
public static function circle_genGames2(Group $group, array $teams = []) : array {
public static function circle_genGames2(Group $group, array $teams = []): array {

if (count($teams) % 2 !== 0) {
$teams[] = Constants::DUMMY_TEAM;
Expand All @@ -203,7 +209,7 @@ public static function circle_genGames2(Group $group, array $teams = []) : array
* @return Game[]
* @throws Exception
*/
public static function circle_saveBracket(array $teams, Group $group) : array {
public static function circle_saveBracket(array $teams, Group $group): array {

$bracket = [];

Expand Down Expand Up @@ -232,7 +238,7 @@ public static function circle_saveBracket(array $teams, Group $group) : array {
*
* @return array
*/
public static function circle_rotateBracket(array $teams) : array {
public static function circle_rotateBracket(array $teams): array {

$first = array_shift($teams); // THE FIRST TEAM REMAINS FIRST
$last = array_shift($teams); // THE SECOND TEAM MOVES TO LAST PLACE
Expand All @@ -251,7 +257,7 @@ public static function circle_rotateBracket(array $teams) : array {
* @return array
* @throws Exception
*/
protected function r_r3Games(array $teams, array &$games, Team $lockedTeam1 = null) : array {
protected function r_r3Games(array $teams, array &$games, Team $lockedTeam1 = null): array {
$teamsB = $teams;
$generatedGames = [];
while (count($teamsB) >= 3) {
Expand All @@ -278,7 +284,7 @@ protected function r_r3Games(array $teams, array &$games, Team $lockedTeam1 = nu
* @return array
* @throws Exception
*/
protected function r_r4Games(array $teams, array &$games) : array {
protected function r_r4Games(array $teams, array &$games): array {
$teamsB = $teams;
$lockedTeam1 = array_shift($teamsB);
while (count($teamsB) >= 4) {
Expand All @@ -289,6 +295,35 @@ protected function r_r4Games(array $teams, array &$games) : array {
return $games;
}

/**
* Copy games for each set iteration
*
* @param Game[] $games
*
* @return Game[]
* @throws Exception
*/
private function copyGameIterations(array &$games): array {
if (($iterations = $this->getIterationCount()) < 2) {
return [];
}
$originalGames = $games;
$newGames = [];
// Start from 1st iteration - 0th iteration is already generated
for ($i = 1; $i < $iterations; $i++) {
// Copy all games and flip the teams for every second iteration (starting from 0)
foreach ($originalGames as $game) {
$games[] = $newGame = new Game(
// Flip teams every 2nd iteration
$i % 2 === 0 ? $game->getTeams() : array_reverse($game->getTeams()),
$this->group
);
$newGames[] = $newGame;
}
}
return $newGames;
}

/**
* Generates games for teams, where a team plays only against one other team
*
Expand All @@ -297,7 +332,7 @@ protected function r_r4Games(array $teams, array &$games) : array {
* @return Generator
* @throws Exception
*/
protected function two_twoGames(array $teams = []) : Generator {
protected function two_twoGames(array $teams = []): Generator {
if (count($teams) === 0) {
$teams = $this->group->getTeams();
}
Expand All @@ -309,7 +344,14 @@ protected function two_twoGames(array $teams = []) : Generator {
$teams = $this->saveTwoTwoGames($teams);

if (!$this->allowSkip && count($discard) > 0) {
throw new Exception('Couldn\'t make games with all teams. Expected k*'.$this->inGame.' teams '.$count.' teams given - discarting '.count($discard).' teams ('.implode(', ', $discard).') in group '.$this->group.' - allow skip '.($this->allowSkip ? 'True' : 'False'));
throw new Exception(
'Couldn\'t make games with all teams. Expected k*' . $this->inGame . ' teams ' . $count . ' teams given - discarting ' . count(
$discard
) . ' teams (' . implode(
', ',
$discard
) . ') in group ' . $this->group . ' - allow skip ' . ($this->allowSkip ? 'True' : 'False')
);
}
return $this;
}
Expand All @@ -324,14 +366,17 @@ protected function two_twoGames(array $teams = []) : Generator {
* @return array
* @throws Exception
*/
protected function saveTwoTwoGames(array $teams) : array {
protected function saveTwoTwoGames(array $teams): array {
$games = [];
while (count($teams) > 0) {
$tInGame = [];
for ($i = 0; $i < $this->inGame; $i++) {
$tInGame[] = array_shift($teams);
}
$this->group->game($tInGame);
$games[] = $this->group->game($tInGame);
}
$newGames = $this->copyGameIterations($games);
$this->group->addGame(...$newGames);
return $teams;
}

Expand All @@ -343,7 +388,7 @@ protected function saveTwoTwoGames(array $teams) : array {
* @return Generator
* @throws Exception
*/
protected function cond_splitGames(array $teams = []) : Generator {
protected function cond_splitGames(array $teams = []): Generator {
if (count($teams) === 0) {
$teams = $this->group->getTeams();
}
Expand All @@ -353,7 +398,7 @@ protected function cond_splitGames(array $teams = []) : Generator {
$games = [];

// Split teams into chunks of maximum size
$groups = array_chunk($teams, (int) ceil($count / ceil($count / $this->maxSize)));
$groups = array_chunk($teams, (int)ceil($count / ceil($count / $this->maxSize)));
// Generate games for each chunk
foreach ($groups as $group) {
$games[] = $this->r_rGames($group);
Expand All @@ -377,7 +422,7 @@ protected function cond_splitGames(array $teams = []) : Generator {
*
* @throws Exception
*/
protected function fillGamesFromChunks(array $games) : void {
protected function fillGamesFromChunks(array $games): void {
$gameCount = Functions::nestedCount($games);
while ($gameCount > 0) {
foreach ($games as $key => $group) {
Expand All @@ -399,8 +444,8 @@ protected function fillGamesFromChunks(array $games) : void {
* @return array
* @throws Exception
*/
public function orderGames() : array {
return (new Sorter\GameSorter($this->group))->sort($this->group->getGames());
public function orderGames(): array {
return (new Sorter\GameSorter($this->group))->sort($this->group->getGames());
}

}
12 changes: 12 additions & 0 deletions src/TournamentGenerator/Import/ImportValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class ImportValidator
'default' => false,
'type' => 'bool',
],
'iterations' => [
'default' => 1,
'type' => 'int',
],
'timing' => [
'default' => null,
'type' => 'object',
Expand Down Expand Up @@ -156,6 +160,10 @@ class ImportValidator
'default' => false,
'type' => 'bool',
],
'iterations' => [
'default' => 1,
'type' => 'int',
],
'played' => [
'default' => false,
'type' => 'bool',
Expand Down Expand Up @@ -201,6 +209,10 @@ class ImportValidator
'default' => false,
'type' => 'bool',
],
'iterations' => [
'default' => 1,
'type' => 'int',
],
'points' => [
'default' => null,
'type' => 'object',
Expand Down
Loading

0 comments on commit 6b77b32

Please sign in to comment.