Completed
Push — master ( 5d9f44...4b85e8 )
by Tomáš
03:31
created

Tournament   B

Complexity

Total Complexity 52

Size/Duplication

Total Lines 196
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 101
dl 0
loc 196
rs 7.44
c 0
b 0
f 0
wmc 52

31 Methods

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

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
	private $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 setName(string $name) {
31
		$this->name = $name;
32
		return $this;
33
	}
34
	public function getName() {
35
		return $this->name;
36
	}
37
38
	public function setPlay(int $play) {
39
		$this->expectedPlay = $play;
40
		return $this;
41
	}
42
	public function getPlay() {
43
		return $this->expectedPlay;
44
	}
45
	public function setGameWait(int $wait) {
46
		$this->expectedGameWait = $wait;
47
		return $this;
48
	}
49
	public function getGameWait() {
50
		return $this->expectedGameWait;
51
	}
52
	public function setRoundWait(int $wait) {
53
		$this->expectedRoundWait = $wait;
54
		return $this;
55
	}
56
	public function getRoundWait() {
57
		return $this->expectedRoundWait;
58
	}
59
	public function setCategoryWait(int $wait) {
60
		$this->expectedCategoryWait = $wait;
61
		return $this;
62
	}
63
	public function getCategoryWait() {
64
		return $this->expectedCategoryWait;
65
	}
66
	public function getTournamentTime(){
67
		$games = count($this->getGames());
68
		return $games*$this->expectedPlay+$games*$this->expectedGameWait+count($this->getRounds())*$this->expectedRoundWait+count($this->getCategories())*$this->expectedCategoryWait;
69
	}
70
71
	public function allowSkip(){
72
		$this->allowSkip = true;
73
		return $this;
74
	}
75
	public function disallowSkip(){
76
		$this->allowSkip = false;
77
		return $this;
78
	}
79
	public function setSkip(bool $skip) {
80
		$this->allowSkip = $skip;
81
		return $this;
82
	}
83
	public function getSkip() {
84
		return $this->allowSkip;
85
	}
86
87
	public function addCategory(Category ...$categories){
88
		foreach ($categories as $category) {
89
			if ($category instanceof Category) $this->categories[] = $category;
90
			else throw new \Exception('Trying to add category which is not an instance of the Category class.');
91
		}
92
		return $this;
93
	}
94
	public function category(string $name = '') {
95
		$c = new Category($name);
96
		$this->categories[] = $c->setSkip($this->allowSkip);
97
		return $c;
98
	}
99
	public function getCategories() {
100
		return $this->categories;
101
	}
102
103
	public function addRound(Round ...$rounds) {
104
		foreach ($rounds as $round) {
105
			if ($round instanceof Round) $this->rounds[] = $round;
106
			else throw new \Exception('Trying to add round which is not an instance of the Round class.');
107
		}
108
		return $this;
109
	}
110
	public function round(string $name = '') {
111
		$r = new Round($name);
112
		$this->rounds[] = $r->setSkip($this->allowSkip);
113
		return $r;
114
	}
115
	public function getRounds() {
116
		if (count($this->categories) > 0) {
117
			$rounds = [];
118
			foreach ($this->categories as $category) {
119
				$rounds = array_merge($rounds, $category->getRounds());
120
			}
121
			return array_merge($rounds, $this->rounds);
122
		}
123
		return $this->rounds;
124
	}
125
126
	public function addTeam(Team ...$teams) {
127
		foreach ($teams as $team) {
128
			$this->teams[] = $team;
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 = \TournamentGenerator\Constants::POINTS) {
138
		$teams = $this->teams;
139
		foreach ($this->categories as $category) {
140
			$teams = array_merge($teams, $category->getTeams());
141
		}
142
		foreach ($this->rounds as $round) {
143
			$teams = array_merge($teams, $round->getTeams());
144
		}
145
		$this->teams = \array_unique($teams);
146
		if ($ordered) $this->sortTeams($ordering);
147
		return $this->teams;
148
	}
149
	public function sortTeams($ordering = \TournamentGenerator\Constants::POINTS) {
150
		$teams = [];
151
		for ($i = count($this->rounds)-1; $i >= 0; $i--) {
152
			$rTeams = array_filter($this->rounds[$i]->getTeams(true, $ordering), function($a) use ($teams) { return !in_array($a, $teams); });
153
			$teams = array_merge($teams, $rTeams);
154
		}
155
		$this->teams = $teams;
156
		return $this->teams;
157
	}
158
159
	public function getGames() {
160
		$games = [];
161
		foreach ($this->getRounds() as $round) {
162
			$games = array_merge($games, $round->getGames());
163
		}
164
		return $games;
165
	}
166
167
	public function splitTeams(Round ...$wheres) {
168
169
		if (count($wheres) === 0) $wheres = $this->getRounds();
170
171
		foreach ($wheres as $key => $value) {
172
			if (gettype($value) === 'array') {
173
				unset($wheres[$key]);
174
				$wheres = array_merge($wheres, $value);
175
				continue;
176
			}
177
		}
178
179
		$teams = $this->getTeams();
180
		shuffle($teams);
181
182
		while (count($teams) > 0) {
183
			foreach ($wheres as $where) {
184
				if (count($teams) > 0) $where->addTeam(array_shift($teams));
185
			}
186
		}
187
		foreach ($wheres as $where) {
188
			$where->splitTeams();
189
		}
190
		return $this;
191
	}
192
193
	public function genGamesSimulate(bool $returnTime = false) {
194
		$games = Utilis\Simulator::simulateTournament($this);
195
196
		if ($returnTime) return $this->getTournamentTime();
197
		return $games;
198
	}
199
	public function genGamesSimulateReal(bool $returnTime = false) {
200
		$games = Utilis\Simulator::simulateTournamentReal($this);
201
202
		if ($returnTime) return $this->getTournamentTime();
203
		return $games;
204
	}
205
206
}
207