Passed
Push — master ( 795926...7012fc )
by Tomáš
11:11
created

Games   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Test Coverage

Coverage 98.94%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 85
c 1
b 0
f 0
dl 0
loc 243
ccs 93
cts 94
cp 0.9894
rs 9.44
wmc 37

9 Methods

Rating   Name   Duplication   Size   Complexity  
A cycle1() 0 11 3
A cycle2() 0 11 3
A orderCheckTeamsVal() 0 16 4
A cycle5() 0 11 3
A __construct() 0 2 1
B moveCalculatedGames() 0 21 8
B orderGames() 0 55 9
A cycle3() 0 11 3
A cycle4() 0 11 3
1
<?php
2
3
namespace TournamentGenerator\Helpers\Sorter;
4
5
use TournamentGenerator\Game;
6
use TournamentGenerator\Group;
7
8
/**
9
 * Tournament generator sorter for games
10
 *
11
 * WORKS BY COMPARING AVAILABLE GAMES BY THEIR TEAMS
12
 * TEAMS FROM LAST 3 GAMES
13
 * 1 = PLAYED ONLY 3RD GAME FROM END
14
 * 2 = PLAYED ONLY 2ND GAME FROM END
15
 * 3 = PLAYED 3RD AND 2ND GAME FROM END
16
 * 4 = PLAYED ONLY THE LAST GAME
17
 * 5 = PLAYED 3RD AND 1ST GAME FROM END
18
 * 6 = PLAYED 2ND ANS 1ST GAME FROM END
19
 * 7 = PLAYED ALL 3 LAST GAMES
20
 *
21
 * @author  Tomáš Vojík <[email protected]>
22
 *
23
 * @package TournamentGenerator\Helpers\Sorter
24
 * @since   0.3
25
 */
26
class Games
27
{
28
29
	/** @var Group */
30
	private Group $group;
31
	/** @var Game[] */
32
	private array $games = [];
33
34
	/**
35
	 * Orders games from group
36
	 *
37
	 * @param Group $group
38
	 */
39 23
	public function __construct(Group $group) {
40 23
		$this->group = $group;
41 23
	}
42
43
	/**
44
	 * Orders games from group
45
	 *
46
	 * @return array
47
	 */
48 23
	public function orderGames() : array {
49
50 23
		$games = $this->group->getGames();
51
52 23
		if (count($games) <= 4) {
53
			return $games;
54
		}
55
56 23
		$this->games = [];
57
58 23
		$teams = [];
59 23
		foreach ($this->group->getTeams() as $team) {
60 23
			$teams[$team->getId()] = 0;
61
		}
62
63 23
		$this->moveCalculatedGames(array_shift($games), $teams);
64
65 23
		while (count($games) > 0) {
66
			// CYCLE 1
67
			// TEAM WHICH DIDN'T PLAY IN LAST GAME (< 4)
68 23
			if ($this->cycle1($games, $teams)) {
69 23
				continue;
70
			}
71
72
			// CYCLE 2
73
			// NOT TEAM WHICH PLAYED IN LAST TWO GAMES (NOT 6 or 7)
74 23
			if ($this->cycle2($games, $teams)) {
75 23
				continue;
76
			}
77
78
			// CYCLE 3
79
			// NOT TEAM WHICH PLAYED IN LAST THREE GAMES (NOT 7)
80
			// TEAMS THAT DIDN'T PLAY IN LAST GAME WILL PLAY THIS GAME (< 4)
81 3
			if ($this->cycle3($games, $teams)) {
82 1
				continue;
83
			}
84
85
			// CYCLE 4
86
			// NOT TEAM WHICH PLAYED IN LAST THREE GAMES (NOT 7)
87 3
			if ($this->cycle4($games, $teams)) {
88 3
				continue;
89
			}
90
91
			// CYCLE 5
92
			// TEAMS THAT DIDN'T PLAY IN LAST GAME WILL PLAY THIS GAME (< 4)
93 2
			if ($this->cycle5($games, $teams)) {
94 2
				continue;
95
			}
96
97
			// CYCLE 6
98
			// FIRST AVAILABLE GAME
99 1
			$this->moveCalculatedGames(array_shift($games), $teams);
100
		}
101
102 23
		return $this->games;
103
	}
104
105
	/**
106
	 * Move teams that did not play in the last game (< 4)
107
	 *
108
	 * @param Game  $game
109
	 * @param array $teams
110
	 */
111 23
	private function moveCalculatedGames(Game $game, array &$teams) : void {
112
113 23
		$this->games[] = $game;
114
115 23
		foreach (end($this->games)->getTeamsIds() as $tid) {
116 23
			$teams[$tid] += 4;
117
		}
118
119 23
		if (count($this->games) > 1) {
120 23
			foreach (prev($this->games)->getTeamsIds() as $tid) {
121 23
				$teams[$tid] -= 2;
122
			}
123
		}
124 23
		if (count($this->games) > 2) {
125 23
			foreach (prev($this->games)->getTeamsIds() as $tid) {
126 23
				--$teams[$tid];
127
			}
128
		}
129 23
		if (count($this->games) > 3) {
130 23
			foreach (prev($this->games)->getTeamsIds() as $tid) {
131 23
				--$teams[$tid];
132
			}
133
		}
134
135 23
	}
136
137
	/**
138
	 * Teams that did not play in the last game (< 4)
139
	 *
140
	 * @param array $games
141
	 * @param array $teams
142
	 *
143
	 * @return bool
144
	 */
145 23
	private function cycle1(array &$games, array &$teams) : bool {
146 23
		$found = false;
147 23
		foreach ($games as $key => $game) {
148 23
			if ($this->orderCheckTeamsVal($game, $teams, [4, 5, 6, 7])) {
149 23
				$this->moveCalculatedGames($game, $teams);
150 23
				unset($games[$key]);
151 23
				$found = true;
152 23
				break;
153
			}
154
		}
155 23
		return $found;
156
	}
157
158
	/**
159
	 * Get first available game
160
	 *
161
	 * @param Game  $game
162
	 * @param array $teams
163
	 * @param array $checkVals
164
	 * @param array $required
165
	 *
166
	 * @return bool
167
	 */
168 23
	private function orderCheckTeamsVal(Game $game, array $teams, array $checkVals, array $required = []) : bool {
169
170 23
		$requiredTeams = array_filter($teams, static function($a) use ($required) {
171 23
			return in_array($a, $required, true);
172 23
		});
173
174 23
		foreach ($game->getTeamsIds() as $tid) {
175 23
			if (in_array($teams[$tid], $checkVals, true)) {
176 23
				return false;
177
			}
178 23
			if (isset($requiredTeams[$tid])) {
179 3
				unset($requiredTeams[$tid]);
180
			}
181
		}
182
183 23
		return !(count($requiredTeams) > 0);
184
185
	}
186
187
	/**
188
	 * Teams that did not play in the last two games (not 6 or 7)
189
	 *
190
	 * @param array $games
191
	 * @param array $teams
192
	 *
193
	 * @return bool
194
	 */
195 23
	private function cycle2(array &$games, array &$teams) : bool {
196 23
		$found = false;
197 23
		foreach ($games as $key => $game) {
198 23
			if ($this->orderCheckTeamsVal($game, $teams, [6, 7])) {
199 23
				$this->moveCalculatedGames($game, $teams);
200 23
				unset($games[$key]);
201 23
				$found = true;
202 23
				break;
203
			}
204
		}
205 23
		return $found;
206
	}
207
208
	/**
209
	 * Teams that did not play in the last three games (not 7) and teams that did not play in the last game (< 4)
210
	 *
211
	 * @param array $games
212
	 * @param array $teams
213
	 *
214
	 * @return bool
215
	 */
216 3
	private function cycle3(array &$games, array &$teams) : bool {
217 3
		$found = false;
218 3
		foreach ($games as $key => $game) {
219 3
			if ($this->orderCheckTeamsVal($game, $teams, [7], [1, 2, 3])) {
220 1
				$this->moveCalculatedGames($game, $teams);
221 1
				unset($games[$key]);
222 1
				$found = true;
223 1
				break;
224
			}
225
		}
226 3
		return $found;
227
	}
228
229
	/**
230
	 * Teams that did not play in the last three games (not 7)
231
	 *
232
	 * @param array $games
233
	 * @param array $teams
234
	 *
235
	 * @return bool
236
	 */
237 3
	private function cycle4(array &$games, array &$teams) : bool {
238 3
		$found = false;
239 3
		foreach ($games as $key => $game) {
240 3
			if ($this->orderCheckTeamsVal($game, $teams, [7])) {
241 3
				$this->moveCalculatedGames($game, $teams);
242 3
				unset($games[$key]);
243 3
				$found = true;
244 3
				break;
245
			}
246
		}
247 3
		return $found;
248
	}
249
250
	/**
251
	 * Teams that did not play in the last game will play this game (< 4)
252
	 *
253
	 * @param array $games
254
	 * @param array $teams
255
	 *
256
	 * @return bool
257
	 */
258 2
	private function cycle5(array &$games, array &$teams) : bool {
259 2
		$found = false;
260 2
		foreach ($games as $key => $game) {
261 2
			if ($this->orderCheckTeamsVal($game, $teams, [], [1, 2, 3])) {
262 2
				$this->moveCalculatedGames($game, $teams);
263 2
				unset($games[$key]);
264 2
				$found = true;
265 2
				break;
266
			}
267
		}
268 2
		return $found;
269
	}
270
271
}
272