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

Simulator   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 41
c 1
b 0
f 0
dl 0
loc 169
ccs 47
cts 47
cp 1
rs 10
wmc 19

8 Methods

Rating   Name   Duplication   Size   Complexity  
A simulateRounds() 0 19 4
A simulateRoundsReal() 0 15 3
A simulateRound() 0 6 3
A simulateTournamentReal() 0 2 1
A simulateGroup() 0 17 5
A simulateCategoryReal() 0 2 1
A simulateCategory() 0 2 1
A simulateTournament() 0 2 1
1
<?php
2
3
namespace TournamentGenerator\Helpers;
4
5
use Exception;
6
use TournamentGenerator\Category;
7
use TournamentGenerator\Game;
8
use TournamentGenerator\Group;
9
use TournamentGenerator\Interfaces\WithRounds;
10
use TournamentGenerator\Round;
11
use TournamentGenerator\Team;
12
use TournamentGenerator\TeamFilter;
13
use TournamentGenerator\Tournament;
14
15
/**
16
 * Class responsible for simulating a tournament
17
 *
18
 * Simulating a tournament can be useful if you want to generate all the games beforehand.
19
 * It generates random scores and progresses teams into next groups / rounds to generate them too.
20
 * This will allow generating the whole tournament beforehand to calculate all the games and time necessary to play.
21
 *
22
 * @author  Tomáš Vojík <[email protected]>
23
 *
24
 * @package TournamentGenerator\Helpers
25
 *
26
 * @since   0.3
27
 */
28
class Simulator
29
{
30
31
	/**
32
	 * Simulates games in a given group.
33
	 *
34
	 * @param Group                       $group   Group to simulate
35
	 * @param TeamFilter[]|TeamFilter[][] $filters Filters applied to returned teams (ex. if you only want to return the winning team)
36
	 * @param bool                        $reset   If the group should reset its scores after simulation
37
	 *
38
	 * @return Team[] Teams sorted and filtered after simulation
39
	 * @throws Exception
40
	 */
41 31
	public static function simulateGroup(Group $group, array $filters = [], bool $reset = true) : array {
42 31
		foreach ($group->getGames() as $game) {
43 28
			$teams = $game->getTeams();
44 28
			$results = [];
45 28
			foreach ($teams as $team) {
46 28
				$results[$team->getId()] = floor(random_int(0, 500));
47
			}
48 28
			$game->setResults($results);
49
		}
50 31
		$returnTeams = $group->sortTeams(null, $filters);
51 31
		if (!$reset) {
52 30
			return $returnTeams;
53
		}
54 5
		foreach ($group->getGames() as $game) {
55 1
			$game->resetResults();
56
		}
57 5
		return $returnTeams;
58
	}
59
60
	/**
61
	 * Simulates games in a round
62
	 *
63
	 * @param Round $round Round to simulate
64
	 *
65
	 * @throws Exception
66
	 */
67 27
	public static function simulateRound(Round $round) : void {
68 27
		foreach ($round->getGroups() as $group) {
69 27
			if ($group->isPlayed()) {
70 1
				continue;
71
			}
72 27
			$group->simulate([], false);
73
		}
74 27
	}
75
76
	/**
77
	 * Simulate the whole tournament as it was played for real
78
	 *
79
	 * Generates the games for each round, simulates it, progresses the teams and resets the scores. Uses dummy team objects to progress.
80
	 *
81
	 * @param Tournament $tournament Tournament to simulate
82
	 *
83
	 * @post The games' scores will be reset
84
	 *
85
	 * @return Game[] All played games
86
	 * @throws Exception
87
	 * @see  Simulator::simulateRounds()
88
	 *
89
	 */
90 14
	public static function simulateTournament(Tournament $tournament) : array {
91 14
		return self::simulateRounds($tournament);
92
	}
93
94
	/**
95
	 * Simulate the whole tournament as it was played for real
96
	 *
97
	 * Generates the games for each round, simulates it, progresses the teams and resets the scores. Uses dummy team objects to progress.
98
	 *
99
	 * @param WithRounds $object Tournament or Category to generate games from.
100
	 *
101
	 * @return Game[] All played games
102
	 * @throws Exception
103
	 * @post The games' scores will be reset
104
	 *
105
	 */
106 15
	public static function simulateRounds(WithRounds $object) : array {
107 15
		if (count($object->getRounds()) === 0) {
108 1
			throw new Exception('There are no rounds to simulate games from.');
109
		}
110
111
		/** @var Game[][] $games Array of games for each round */
112 14
		$games = [];
113
114 14
		foreach ($object->getRounds() as $round) {
115 14
			$games[] = $round->genGames();
116
			$round
117 13
				->simulate()
118 13
				->progress(true);
119
		}
120 13
		foreach ($object->getRounds() as $round) {
121 13
			$round->resetGames();
122
		}
123
124 13
		return array_merge(...$games);
125
	}
126
127
	/**
128
	 * Generates and simulates the tournament as if it was played for real.
129
	 *
130
	 * Progresses the real teams, does not create dummy teams.
131
	 *
132
	 * @param Tournament $tournament Tournament to simulate
133
	 *
134
	 * @return Game[]
135
	 * @throws Exception
136
	 * @see Simulator::simulateRoundsReal()
137
	 */
138 5
	public static function simulateTournamentReal(Tournament $tournament) : array {
139 5
		return self::simulateRoundsReal($tournament);
140
	}
141
142
	/**
143
	 * Generates and simulates rounds as if it was played for real.
144
	 *
145
	 * Progresses the real teams, does not create dummy teams.
146
	 *
147
	 * @param WithRounds $object Tournament or Category to generate games from.
148
	 *
149
	 * @return Game[]
150
	 * @throws Exception
151
	 */
152 6
	public static function simulateRoundsReal(WithRounds $object) : array {
153 6
		if (count($object->getRounds()) === 0) {
154 1
			throw new Exception('There are no rounds to simulate games from.');
155
		}
156
157
		/** @var Game[][] $games Array of games for each round */
158 5
		$games = [];
159
160 5
		foreach ($object->getRounds() as $round) {
161 5
			$games[] = $round->genGames();
162
			$round
163 5
				->simulate()
164 5
				->progress();
165
		}
166 5
		return array_merge(...$games);
167
	}
168
169
	/**
170
	 * Generates and simulates a tournament category.
171
	 *
172
	 * Generates the games for each round, simulates it, progresses the teams and resets the scores. Uses dummy team objects to progress.
173
	 *
174
	 * @param Category $category Category to simulate
175
	 *
176
	 * @return Game[]
177
	 * @throws Exception
178
	 * @see Simulator::simulateRounds()
179
	 */
180 1
	public static function simulateCategory(Category $category) : array {
181 1
		return self::simulateRounds($category);
182
	}
183
184
	/**
185
	 * Generates and simulates a category as if it was played for real.
186
	 *
187
	 * Progresses the real teams, does not create dummy teams.
188
	 *
189
	 * @param Category $category Category to simulate
190
	 *
191
	 * @return Game[]
192
	 * @throws Exception
193
	 * @see Simulator::simulateRoundsReal()
194
	 */
195 1
	public static function simulateCategoryReal(Category $category) : array {
196 1
		return self::simulateRoundsReal($category);
197
	}
198
199
}
200