Completed
Push — master ( c3f0f6...0c6e4d )
by Tomáš
02:30
created

Round::getGroups()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TournamentGenerator;
4
5
use Exception;
6
use TournamentGenerator\Containers\BaseContainer;
7
use TournamentGenerator\Containers\GameContainer;
8
use TournamentGenerator\Containers\HierarchyContainer;
9
use TournamentGenerator\Containers\TeamContainer;
10
use TournamentGenerator\Interfaces\WithGames;
11
use TournamentGenerator\Interfaces\WithGroups;
12
use TournamentGenerator\Interfaces\WithSkipSetters;
13
use TournamentGenerator\Interfaces\WithTeams;
14
use TournamentGenerator\Traits\WithGames as WithGamesTrait;
15
use TournamentGenerator\Traits\WithGroups as WithGroupsTrait;
16
use TournamentGenerator\Traits\WithSkipSetters as WithSkipSettersTrait;
17
use TournamentGenerator\Traits\WithTeams as WithTeamsTrait;
18
19
/**
20
 * Tournament round
21
 *
22
 * Round is a container for tournament groups. Groups in a round are played at the same time.
23
 * This modifies the generation of games - generate all games for each group and play them in alternating order (game 1 from group 1, game 1 from group 2, game 2 from group 1, ...).
24
 *
25
 * @package TournamentGenerator
26
 * @author  Tomáš Vojík <[email protected]>
27
 * @since   0.1
28
 */
29
class Round extends HierarchyBase implements WithSkipSetters, WithTeams, WithGroups, WithGames
30
{
31
	use WithTeamsTrait;
32
	use WithGroupsTrait;
33
	use WithSkipSettersTrait;
34
	use WithGamesTrait;
35
36
	/**
37
	 * Round constructor.
38
	 *
39
	 * @param string          $name Round name
40
	 * @param string|int|null $id   Round id - if omitted -> it is generated automatically as unique string
41
	 */
42 66
	public function __construct(string $name = '', $id = null) {
43 66
		$this->setName($name);
44 66
		$this->setId($id ?? uniqid('', false));
45 66
		$this->games = new GameContainer($this->id);
46 66
		$this->teams = new TeamContainer($this->id);
47 66
		$this->container = new HierarchyContainer($this->id);
48 66
	}
49
50
	/**
51
	 * Adds one or more group to round
52
	 *
53
	 * @param Group ...$groups
54
	 *
55
	 * @return $this
56
	 */
57 1
	public function addGroup(Group ...$groups) : Round {
58 1
		foreach ($groups as $group) {
59 1
			$this->insertIntoContainer($group);
60
		}
61 1
		return $this;
62
	}
63
64
	/**
65
	 * Creates a new group and adds it to round
66
	 *
67
	 * @param string          $name Group name
68
	 * @param string|int|null $id   Group id - if omitted -> it is generated automatically as unique string
69
	 *
70
	 * @return Group New group
71
	 */
72 51
	public function group(string $name, $id = null) : Group {
73 51
		$g = new Group($name, $id);
74 51
		$this->insertIntoContainer($g->setSkip($this->allowSkip));
75 51
		return $g;
76
	}
77
78
	/**
79
	 * Get all group ids
80
	 *
81
	 * @return string[]|int[] Array of ids
82
	 */
83 1
	public function getGroupsIds() : array {
84 1
		$groups = $this->orderGroups();
85 1
		return array_map(static function($a) {
86 1
			return $a->getId();
87 1
		}, $groups);
88
	}
89
90
	/**
91
	 * Sort groups by their order
92
	 *
93
	 * @return Group[] Sorted groups
94
	 */
95 2
	public function orderGroups() : array {
96 2
		$groups = $this->getGroups();
97 2
		usort($groups, static function($a, $b) {
98 2
			return $a->getOrder() - $b->getOrder();
99 2
		});
100 2
		return $groups;
101
	}
102
103
	/**
104
	 * Generate all games
105
	 *
106
	 * @return array
107
	 * @throws Exception
108
	 */
109 26
	public function genGames() : array {
110 26
		foreach ($this->getGroups() as $group) {
111 26
			$group->genGames();
112
		}
113 25
		return $this->getGames();
114
	}
115
116
	/**
117
	 * Check if all games in this round has been played
118
	 *
119
	 * @return bool
120
	 */
121 1
	public function isPlayed() : bool {
122 1
		if (count($this->games) === 0) {
123 1
			return false;
124
		}
125 1
		foreach ($this->getGroups() as $group) {
126 1
			if (!$group->isPlayed()) {
127 1
				return false;
128
			}
129
		}
130 1
		return true;
131
	}
132
133
	/**
134
	 * Split teams into its Groups
135
	 *
136
	 * @param Group[] $groups
137
	 *
138
	 * @return $this
139
	 * @throws Exception
140
	 * @noinspection CallableParameterUseCaseInTypeContextInspection
141
	 */
142 35
	public function splitTeams(Group ...$groups) : Round {
143 35
		if (count($groups) === 0) {
144 34
			$groups = $this->getGroups();
145
		}
146
147 35
		$teams = $this->getTeams();
148 35
		shuffle($teams);
149
150 35
		while (count($teams) > 0) {
151 35
			foreach ($groups as $group) {
152 35
				if (count($teams) > 0) {
153 35
					$group->addTeam(array_shift($teams));
154
				}
155
			}
156
		}
157 35
		return $this;
158
	}
159
160
	/**
161
	 * Progresses all teams from the round
162
	 *
163
	 * @param bool $blank If true -> creates dummy teams for (does not progress the real team objects) - used for simulation
164
	 *
165
	 * @return $this
166
	 * @throws Exception
167
	 */
168 26
	public function progress(bool $blank = false) : Round {
169 26
		foreach ($this->getGroups() as $group) {
170 26
			$group->progress($blank);
171
		}
172 26
		return $this;
173
	}
174
175
	/**
176
	 * Simulate all games in this round as they would be played for real
177
	 *
178
	 * @return $this
179
	 * @throws Exception
180
	 */
181 27
	public function simulate() : Round {
182 27
		Helpers\Simulator::simulateRound($this);
183 27
		return $this;
184
	}
185
186
	/**
187
	 * Reset all game results as if they were not played
188
	 *
189
	 * @post All games in this round are marked as "not played"
190
	 * @post All scores in this round are deleted
191
	 *
192
	 * @return $this
193
	 * @throws Exception
194
	 */
195 14
	public function resetGames() : Round {
196 14
		foreach ($this->getGroups() as $group) {
197 14
			$group->resetGames();
198
		}
199 14
		return $this;
200
	}
201
}
202