Test Failed
Push — master ( 943f49...1c4bf0 )
by Tomáš
09:55
created

Round::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 7
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TournamentGenerator;
4
5
use Exception;
6
use TournamentGenerator\Containers\GameContainer;
7
use TournamentGenerator\Containers\HierarchyContainer;
8
use TournamentGenerator\Containers\TeamContainer;
9
use TournamentGenerator\Helpers\Functions;
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 142
	public function __construct(string $name = '', $id = null) {
43 142
		$this->setName($name);
44
		/** @infection-ignore-all */
45 142
		$this->setId($id ?? uniqid('', false));
46 142
		$this->games = new GameContainer($this->id);
47 142
		$this->teams = new TeamContainer($this->id);
48 142
		$this->container = new HierarchyContainer($this->id);
49 142
	}
50
51
	/**
52
	 * Adds one or more group to round
53
	 *
54
	 * @param Group ...$groups
55
	 *
56
	 * @return $this
57
	 * @throws Exception
58
	 */
59 12
	public function addGroup(Group ...$groups) : Round {
60 12
		foreach ($groups as $group) {
61 12
			$this->insertIntoContainer($group);
62
		}
63 12
		return $this;
64
	}
65
66
	/**
67
	 * Creates a new group and adds it to round
68
	 *
69
	 * @param string          $name Group name
70
	 * @param string|int|null $id   Group id - if omitted -> it is generated automatically as unique string
71
	 *
72
	 * @return Group New group
73
	 * @throws Exception
74
	 */
75 130
	public function group(string $name, $id = null) : Group {
76 130
		$g = new Group($name, $id);
77 130
		$this->insertIntoContainer($g->setSkip($this->allowSkip));
78 130
		return $g;
79
	}
80
81
	/**
82
	 * Get all group ids
83
	 *
84
	 * @return string[]|int[] Array of ids
85
	 */
86 3
	public function getGroupsIds() : array {
87 3
		$groups = $this->orderGroups();
88 3
		return array_map(static function($a) {
89 3
			return $a->getId();
90 3
		}, $groups);
91
	}
92
93
	/**
94
	 * Sort groups by their order
95
	 *
96
	 * @return Group[] Sorted groups
97
	 */
98 4
	public function orderGroups() : array {
99 4
		$groups = $this->getGroups();
100 4
		usort($groups, static function($a, $b) {
101 4
			return $a->getOrder() - $b->getOrder();
102 4
		});
103 4
		return $groups;
104
	}
105
106
	/**
107
	 * Generate all games
108
	 *
109
	 * @return array
110
	 * @throws Exception
111
	 */
112 27
	public function genGames() : array {
113 27
		foreach ($this->getGroups() as $group) {
114 27
			$group->genGames();
115
		}
116 26
		return $this->getGames();
117
	}
118
119
	/**
120
	 * Check if all games in this round has been played
121
	 *
122
	 * @return bool
123
	 */
124 7
	public function isPlayed() : bool {
125 7
		if (count($this->games) === 0) {
126 5
			return false;
127
		}
128 5
		foreach ($this->getGroups() as $group) {
129 5
			if (!$group->isPlayed()) {
130 1
				return false;
131
			}
132
		}
133 5
		return true;
134
	}
135
136
	/**
137
	 * Split teams into its Groups
138
	 *
139
	 * @param Group[] $groups
140
	 *
141
	 * @return $this
142
	 * @throws Exception
143
	 * @noinspection CallableParameterUseCaseInTypeContextInspection
144
	 */
145 37
	public function splitTeams(Group ...$groups) : Round {
146 37
		if (count($groups) === 0) {
147 36
			$groups = $this->getGroups();
148
		}
149
150 37
		$teams = $this->getTeams(true, Constants::SEED);
151 37
		if ($this::isSeeded($teams)) {
152 2
			Functions::sortAlternate($teams);
153
		}
154
		else {
155 35
			shuffle($teams);
156
		}
157
158 37
		$split = ceil(count($teams) / count($groups));
159 37
		foreach ($groups as $where) {
160 37
			if (count($teams) > 0) {
161 37
				$where->addTeam(...array_splice($teams, 0, $split));
0 ignored issues
show
Bug introduced by
$split of type double is incompatible with the type integer|null expected by parameter $length of array_splice(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

161
				$where->addTeam(...array_splice($teams, 0, /** @scrutinizer ignore-type */ $split));
Loading history...
162
			}
163
		}
164 37
		return $this;
165
	}
166
167
	/**
168
	 * Progresses all teams from the round
169
	 *
170
	 * @param bool $blank If true -> creates dummy teams for (does not progress the real team objects) - used for simulation
171
	 *
172
	 * @return $this
173
	 * @throws Exception
174
	 */
175 26
	public function progress(bool $blank = false) : Round {
176 26
		foreach ($this->getGroups() as $group) {
177 26
			$group->progress($blank);
178
		}
179 26
		return $this;
180
	}
181
182
	/**
183
	 * Simulate all games in this round as they would be played for real
184
	 *
185
	 * @return $this
186
	 * @throws Exception
187
	 */
188 27
	public function simulate() : Round {
189 27
		Helpers\Simulator::simulateRound($this);
190 27
		return $this;
191
	}
192
193
	/**
194
	 * Reset all game results as if they were not played
195
	 *
196
	 * @post All games in this round are marked as "not played"
197
	 * @post All scores in this round are deleted
198
	 *
199
	 * @return $this
200
	 * @throws Exception
201
	 */
202 14
	public function resetGames() : Round {
203 14
		foreach ($this->getGroups() as $group) {
204 14
			$group->resetGames();
205
		}
206 14
		return $this;
207
	}
208
209
	/**
210
	 * @inheritDoc
211
	 * @return array
212
	 * @throws Exception
213
	 */
214
	public function jsonSerialize() : array {
215
		return [
216
			'id'     => $this->getId(),
217
			'name'   => $this->getName(),
218
			'games'  => $this->getGames(),
219
			'teams'  => $this->teams->ids(),
220
			'groups' => $this->queryGroups()->ids(),
221
		];
222
	}
223
}
224