Passed
Push — master ( b9aa7a...67756f )
by Tomáš
02:47
created

Tournament   F

Complexity

Total Complexity 64

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 120
c 3
b 0
f 0
dl 0
loc 224
rs 3.28
wmc 64

29 Methods

Rating   Name   Duplication   Size   Complexity  
A addRound() 0 6 3
A setCategoryWait() 0 3 1
A getPlay() 0 2 1
A setRoundWait() 0 3 1
A getRounds() 0 9 3
A getCategories() 0 2 1
A setGameWait() 0 3 1
A getTournamentTime() 0 3 1
A setSkip() 0 3 1
A addCategory() 0 6 3
A disallowSkip() 0 3 1
A category() 0 4 1
A getGameWait() 0 2 1
A getCategoryWait() 0 2 1
A setPlay() 0 3 1
A round() 0 4 1
A allowSkip() 0 3 1
A getSkip() 0 2 1
A getRoundWait() 0 2 1
A team() 0 4 1
A __construct() 0 2 1
A addTeam() 0 13 6
A __toString() 0 2 1
A getTeams() 0 15 5
A getGames() 0 6 2
A sortTeams() 0 8 2
A genGamesSimulateReal() 0 16 6
B splitTeams() 0 24 8
B genGamesSimulate() 0 18 7

How to fix   Complexity   

Complex Class

Complex classes like Tournament often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Tournament, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace TournamentGenerator;
4
5
/**
6
 *
7
 */
8
class Tournament
9
{
10
11
	public $name = '';
12
	private $categories = [];
13
	private $rounds = [];
14
	private $teams = [];
15
16
	private $expectedPlay = 0;
17
	private $expectedGameWait = 0;
18
	private $expectedRoundWait = 0;
19
	private $expectedCategoryWait = 0;
20
21
	private $allowSkip = false;
22
23
	function __construct(string $name = ''){
24
		$this->name = $name;
25
	}
26
	public function __toString() {
27
		return $this->name;
28
	}
29
30
	public function setPlay(int $play) {
31
		$this->expectedPlay = $play;
32
		return $this;
33
	}
34
	public function getPlay() {
35
		return $this->expectedPlay;
36
	}
37
	public function setGameWait(int $wait) {
38
		$this->expectedGameWait = $wait;
39
		return $this;
40
	}
41
	public function getGameWait() {
42
		return $this->expectedGameWait;
43
	}
44
	public function setRoundWait(int $wait) {
45
		$this->expectedRoundWait = $wait;
46
		return $this;
47
	}
48
	public function getRoundWait() {
49
		return $this->expectedRoundWait;
50
	}
51
	public function setCategoryWait(int $wait) {
52
		$this->expectedCategoryWait = $wait;
53
		return $this;
54
	}
55
	public function getCategoryWait() {
56
		return $this->expectedCategoryWait;
57
	}
58
	public function getTournamentTime(){
59
		$games = count($this->getGames());
60
		return $games*$this->expectedPlay+$games*$this->expectedGameWait+count($this->getRounds())*$this->expectedRoundWait+count($this->getCategories())*$this->expectedCategoryWait;
61
	}
62
63
	public function allowSkip(){
64
		$this->allowSkip = true;
65
		return $this;
66
	}
67
	public function disallowSkip(){
68
		$this->allowSkip = false;
69
		return $this;
70
	}
71
	public function setSkip(bool $skip) {
72
		$this->allowSkip = $skip;
73
		return $this;
74
	}
75
	public function getSkip() {
76
		return $this->allowSkip;
77
	}
78
79
	public function addCategory(Category ...$categories){
80
		foreach ($categories as $category) {
81
			if ($category instanceof Category) $this->categories[] = $category;
82
			else throw new \Exception('Trying to add category which is not an instance of the Category class.');
83
		}
84
		return $this;
85
	}
86
	public function category(string $name = '') {
87
		$c = new Category($name);
88
		$this->categories[] = $c->setSkip($this->allowSkip);
89
		return $c;
90
	}
91
	public function getCategories() {
92
		return $this->categories;
93
	}
94
95
	public function addRound(Round ...$rounds) {
96
		foreach ($rounds as $round) {
97
			if ($round instanceof Round) $this->rounds[] = $round;
98
			else throw new \Exception('Trying to add round which is not an instance of the Round class.');
99
		}
100
		return $this;
101
	}
102
	public function round(string $name = '') {
103
		$r = new Round($name);
104
		$this->rounds[] = $r->setSkip($this->allowSkip);
105
		return $r;
106
	}
107
	public function getRounds() {
108
		if (count($this->categories) > 0) {
109
			$rounds = [];
110
			foreach ($this->categories as $category) {
111
				$rounds = array_merge($rounds, $category->getRounds());
112
			}
113
			return $rounds;
114
		}
115
		return $this->rounds;
116
	}
117
118
	public function addTeam(...$teams) {
119
		foreach ($teams as $team) {
120
			if ($team instanceof Team)  {
121
				$this->teams[] = $team;
122
			}
123
			elseif (gettype($team) === 'array') {
124
				foreach ($team as $team2) {
125
					if ($team2 instanceof Team) $this->teams[] = $team2;
126
				}
127
			}
128
			else throw new \Exception('Trying to add team which is not an instance of Team class');
129
		}
130
		return $this;
131
	}
132
	public function team(string $name = '') {
133
		$t = new Team($name);
134
		$this->teams[] = $t;
135
		return $t;
136
	}
137
	public function getTeams(bool $ordered = false, $ordering = \POINTS) {
138
		if (count($this->teams) === 0) {
139
			$teams = [];
140
			foreach ($this->categories as $category) {
141
				$teams = array_merge($teams, $category->getTeams());
142
			}
143
			foreach ($this->rounds as $round) {
144
				$teams = array_merge($teams, $round->getTeams());
145
			}
146
			$this->teams = $teams;
147
		}
148
		if ($ordered) {
149
			$this->sortTeams($ordering);
150
		}
151
		return $this->teams;
152
	}
153
	public function sortTeams($ordering = \POINTS) {
154
		$teams = [];
155
		for ($i = count($this->rounds)-1; $i >= 0; $i--) {
156
			$rTeams = array_filter($this->rounds[$i]->getTeams(true, $ordering), function($a) use ($teams) { return !in_array($a, $teams); });
157
			$teams = array_merge($teams, $rTeams);
158
		}
159
		$this->teams = $teams;
160
		return $this->teams;
161
	}
162
163
	public function getGames() {
164
		$games = [];
165
		foreach ($this->getRounds() as $round) {
166
			$games = array_merge($games, $round->getGames());
167
		}
168
		return $games;
169
	}
170
171
	public function splitTeams(Round ...$wheres) {
172
173
		if (count($wheres) === 0) $wheres = $this->getRounds();
174
175
		foreach ($wheres as $key => $value) {
176
			if (gettype($value) === 'array') {
177
				unset($wheres[$key]);
178
				$wheres = array_merge($wheres, $value);
179
				continue;
180
			}
181
		}
182
183
		$teams = $this->getTeams();
184
		shuffle($teams);
185
186
		while (count($teams) > 0) {
187
			foreach ($wheres as $where) {
188
				if (count($teams) > 0) $where->addTeam(array_shift($teams));
189
			}
190
		}
191
		foreach ($wheres as $where) {
192
			$where->splitTeams();
193
		}
194
		return $this;
195
	}
196
197
	public function genGamesSimulate(bool $returnTime = false) {
198
		$games = [];
199
		if (count($this->categories) === 0 && count($this->rounds) === 0) throw new \Exception('There are no rounds or categories to simulate games from.');
200
201
		foreach ($this->categories as $category) {
202
			$games = array_merge($games, $category->genGamesSimulate());
203
		}
204
205
		foreach ($this->rounds as $round) {
206
			$games = array_merge($games, $round->genGames());
207
			$round->simulate()->progress(true);
208
		}
209
		foreach ($this->rounds as $round) {
210
			$round->resetGames();
211
		}
212
213
		if ($returnTime) return $this->getTournamentTime();
214
		return $games;
215
	}
216
	public function genGamesSimulateReal(bool $returnTime = false) {
217
		$games = [];
218
		if (count($this->categories) === 0 && count($this->rounds) === 0) throw new \Exception('There are no rounds or categories to simulate games from.');
219
220
		foreach ($this->categories as $category) {
221
			$games = array_merge($games, $category->genGamesSimulate());
222
		}
223
224
		foreach ($this->rounds as $round) {
225
			$games = array_merge($games, $round->genGames());
226
			$round->simulate();
227
			$round->progress();
228
		}
229
230
		if ($returnTime) return $this->getTournamentTime();
231
		return $games;
232
	}
233
234
}
235