Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Match 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 Match, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class Match extends UrlModel implements NamedModel |
||
15 | { |
||
16 | const OFFICIAL = "official"; |
||
17 | const SPECIAL = "special"; |
||
18 | const FUN = "fm"; |
||
19 | |||
20 | const TEAM_V_TEAM = 0; |
||
21 | const TEAM_V_MIXED = 1; |
||
22 | const MIXED_V_MIXED = 2; |
||
23 | |||
24 | use Timestamp; |
||
25 | |||
26 | /** |
||
27 | * The ID of the first team of the match |
||
28 | * @var int |
||
29 | */ |
||
30 | protected $team_a; |
||
31 | |||
32 | /** |
||
33 | * The ID of the second team of the match |
||
34 | * @var int |
||
35 | */ |
||
36 | protected $team_b; |
||
37 | |||
38 | /** |
||
39 | * The color of the first team |
||
40 | * @var string |
||
41 | */ |
||
42 | protected $team_a_color; |
||
43 | |||
44 | /** |
||
45 | * The color of the second team |
||
46 | * @var string |
||
47 | */ |
||
48 | protected $team_b_color; |
||
49 | |||
50 | /** |
||
51 | * The match points (usually the number of flag captures) Team A scored |
||
52 | * @var int |
||
53 | */ |
||
54 | protected $team_a_points; |
||
55 | |||
56 | /** |
||
57 | * The match points Team B scored |
||
58 | * @var int |
||
59 | */ |
||
60 | protected $team_b_points; |
||
61 | |||
62 | /** |
||
63 | * The BZIDs of players part of Team A who participated in the match, separated by commas |
||
64 | * @var string |
||
65 | */ |
||
66 | protected $team_a_players; |
||
67 | |||
68 | /** |
||
69 | * The BZIDs of players part of Team B who participated in the match, separated by commas |
||
70 | * @var string |
||
71 | */ |
||
72 | protected $team_b_players; |
||
73 | |||
74 | /** |
||
75 | * The ELO score of Team A after the match |
||
76 | * @var int |
||
77 | */ |
||
78 | protected $team_a_elo_new; |
||
79 | |||
80 | /** |
||
81 | * The ELO score of Team B after the match |
||
82 | * @var int |
||
83 | */ |
||
84 | protected $team_b_elo_new; |
||
85 | |||
86 | /** |
||
87 | * The map ID used in the match if the league supports more than one map |
||
88 | * @var int |
||
89 | */ |
||
90 | protected $map; |
||
91 | |||
92 | /** |
||
93 | * The type of match that occurred. Valid options: official, fm, special |
||
94 | * |
||
95 | * @var string |
||
96 | */ |
||
97 | protected $match_type; |
||
98 | |||
99 | /** |
||
100 | * A JSON string of events that happened during a match, such as captures and substitutions |
||
101 | * @var string |
||
102 | */ |
||
103 | protected $match_details; |
||
104 | |||
105 | /** |
||
106 | * The server location of there the match took place |
||
107 | * @var string |
||
108 | */ |
||
109 | protected $server; |
||
110 | |||
111 | /** |
||
112 | * The file name of the replay file of the match |
||
113 | * @var string |
||
114 | */ |
||
115 | protected $replay_file; |
||
116 | |||
117 | /** |
||
118 | * The value of the ELO score difference |
||
119 | * @var int |
||
120 | */ |
||
121 | protected $elo_diff; |
||
122 | |||
123 | /** |
||
124 | * The value of the player Elo difference |
||
125 | * @var int |
||
126 | */ |
||
127 | protected $player_elo_diff; |
||
128 | |||
129 | /** |
||
130 | * The timestamp representing when the match information was last updated |
||
131 | * @var TimeDate |
||
132 | */ |
||
133 | protected $updated; |
||
134 | |||
135 | /** |
||
136 | * The duration of the match in minutes |
||
137 | * @var int |
||
138 | */ |
||
139 | protected $duration; |
||
140 | |||
141 | /** |
||
142 | * The ID of the person (i.e. referee) who last updated the match information |
||
143 | * @var string |
||
144 | */ |
||
145 | protected $entered_by; |
||
146 | |||
147 | /** |
||
148 | * The status of the match. Can be 'entered', 'disabled', 'deleted' or 'reported' |
||
149 | * @var string |
||
150 | */ |
||
151 | protected $status; |
||
152 | |||
153 | /** |
||
154 | * The name of the database table used for queries |
||
155 | */ |
||
156 | const TABLE = "matches"; |
||
157 | |||
158 | const CREATE_PERMISSION = Permission::ENTER_MATCH; |
||
159 | const EDIT_PERMISSION = Permission::EDIT_MATCH; |
||
160 | const SOFT_DELETE_PERMISSION = Permission::SOFT_DELETE_MATCH; |
||
161 | const HARD_DELETE_PERMISSION = Permission::HARD_DELETE_MATCH; |
||
162 | |||
163 | /** |
||
164 | * {@inheritdoc} |
||
165 | */ |
||
166 | 40 | protected function assignResult($match) |
|
167 | { |
||
168 | 40 | $this->team_a = $match['team_a']; |
|
169 | 40 | $this->team_b = $match['team_b']; |
|
170 | 40 | $this->team_a_color = $match['team_a_color']; |
|
171 | 40 | $this->team_b_color = $match['team_b_color']; |
|
172 | 40 | $this->team_a_points = $match['team_a_points']; |
|
173 | 40 | $this->team_b_points = $match['team_b_points']; |
|
174 | 40 | $this->team_a_players = $match['team_a_players']; |
|
175 | 40 | $this->team_b_players = $match['team_b_players']; |
|
176 | 40 | $this->team_a_elo_new = $match['team_a_elo_new']; |
|
177 | 40 | $this->team_b_elo_new = $match['team_b_elo_new']; |
|
178 | 40 | $this->map = $match['map']; |
|
179 | 40 | $this->match_type = $match['match_type']; |
|
180 | 40 | $this->match_details = $match['match_details']; |
|
181 | 40 | $this->server = $match['server']; |
|
182 | 40 | $this->replay_file = $match['replay_file']; |
|
183 | 40 | $this->elo_diff = $match['elo_diff']; |
|
184 | 40 | $this->player_elo_diff = $match['player_elo_diff']; |
|
185 | 40 | $this->timestamp = TimeDate::fromMysql($match['timestamp']); |
|
186 | 40 | $this->updated = TimeDate::fromMysql($match['updated']); |
|
187 | 40 | $this->duration = $match['duration']; |
|
188 | 40 | $this->entered_by = $match['entered_by']; |
|
189 | 40 | $this->status = $match['status']; |
|
190 | 40 | } |
|
191 | |||
192 | /** |
||
193 | * Get the name of the route that shows the object |
||
194 | * @param string $action The route's suffix |
||
195 | * @return string |
||
196 | */ |
||
197 | 1 | public static function getRouteName($action = 'show') |
|
198 | { |
||
199 | 1 | return "match_$action"; |
|
200 | } |
||
201 | |||
202 | /** |
||
203 | * Get a one word description of a match relative to a team (i.e. win, loss, or draw) |
||
204 | * |
||
205 | * @param int|string|TeamInterface $teamID The team ID we want the noun for |
||
206 | * |
||
207 | * @return string Either "win", "loss", or "draw" relative to the team |
||
208 | */ |
||
209 | 1 | public function getMatchDescription($teamID) |
|
210 | { |
||
211 | 1 | if ($this->getScore($teamID) > $this->getOpponentScore($teamID)) { |
|
212 | 1 | return "win"; |
|
213 | 1 | } elseif ($this->getScore($teamID) < $this->getOpponentScore($teamID)) { |
|
214 | 1 | return "loss"; |
|
215 | } |
||
216 | |||
217 | 1 | return "tie"; |
|
218 | } |
||
219 | |||
220 | /** |
||
221 | * Get a one letter description of a match relative to a team (i.e. W, L, or T) |
||
222 | * |
||
223 | * @param int|string|TeamInterface $teamID The team ID we want the noun for |
||
224 | * |
||
225 | * @return string Either "W", "L", or "T" relative to the team |
||
226 | */ |
||
227 | 1 | public function getMatchLetter($teamID) |
|
228 | { |
||
229 | 1 | return strtoupper(substr($this->getMatchDescription($teamID), 0, 1)); |
|
230 | } |
||
231 | |||
232 | /** |
||
233 | * Get the score of a specific team |
||
234 | * |
||
235 | * @param int|string|TeamInterface $teamID The team we want the score for |
||
236 | * |
||
237 | * @return int The score that team received |
||
238 | */ |
||
239 | 23 | View Code Duplication | public function getScore($teamID) |
|
|||
240 | { |
||
241 | 23 | if ($teamID instanceof TeamInterface) { |
|
242 | // Oh no! The caller gave us a Team model instead of an ID! |
||
243 | 23 | $teamID = $teamID->getId(); |
|
244 | 2 | } elseif (is_string($teamID)) { |
|
245 | // Make sure we're comparing lowercase strings |
||
246 | $teamID = strtolower($teamID); |
||
247 | } |
||
248 | |||
249 | 23 | if ($this->getTeamA()->getId() == $teamID) { |
|
250 | 23 | return $this->getTeamAPoints(); |
|
251 | } |
||
252 | |||
253 | 23 | return $this->getTeamBPoints(); |
|
254 | } |
||
255 | |||
256 | /** |
||
257 | * Get the score of the opponent relative to a team |
||
258 | * |
||
259 | * @param int|string|TeamInterface $teamID The opponent of the team we want the score for |
||
260 | * |
||
261 | * @return int The score of the opponent |
||
262 | */ |
||
263 | 2 | public function getOpponentScore($teamID) |
|
264 | { |
||
265 | 2 | return $this->getScore($this->getOpponent($teamID)); |
|
266 | } |
||
267 | |||
268 | /** |
||
269 | * Get the opponent of a match relative to a team ID |
||
270 | * |
||
271 | * @param int|string|TeamInterface $teamID The team who is known in a match |
||
272 | * |
||
273 | * @return TeamInterface The opponent team |
||
274 | */ |
||
275 | 35 | View Code Duplication | public function getOpponent($teamID) |
276 | { |
||
277 | 35 | if ($teamID instanceof TeamInterface) { |
|
278 | 35 | $teamID = $teamID->getId(); |
|
279 | 2 | } elseif (is_string($teamID)) { |
|
280 | $teamID = strtolower($teamID); |
||
281 | } |
||
282 | |||
283 | 35 | if ($this->getTeamA()->getId() == $teamID) { |
|
284 | 23 | return $this->getTeamB(); |
|
285 | } |
||
286 | |||
287 | 14 | return $this->getTeamA(); |
|
288 | } |
||
289 | |||
290 | /** |
||
291 | * Get the timestamp of the last update of the match |
||
292 | * |
||
293 | * @return TimeDate The match's update timestamp |
||
294 | */ |
||
295 | 1 | public function getUpdated() |
|
296 | { |
||
297 | 1 | return $this->updated->copy(); |
|
298 | } |
||
299 | |||
300 | /** |
||
301 | * Set the timestamp of the match |
||
302 | * |
||
303 | * @param mixed $timestamp The match's new timestamp |
||
304 | * @return $this |
||
305 | */ |
||
306 | public function setTimestamp($timestamp) |
||
307 | { |
||
308 | $this->updateProperty($this->timestamp, "timestamp", TimeDate::from($timestamp)); |
||
309 | |||
310 | return $this; |
||
311 | } |
||
312 | |||
313 | /** |
||
314 | * Get the first team involved in the match |
||
315 | * @return TeamInterface Team A |
||
316 | */ |
||
317 | 40 | public function getTeamA() |
|
318 | { |
||
319 | 40 | $team = Team::get($this->team_a); |
|
320 | |||
321 | 40 | if ($this->match_type === self::OFFICIAL && $team->isValid()) { |
|
322 | 26 | return $team; |
|
323 | } |
||
324 | |||
325 | 15 | return new ColorTeam($this->team_a_color); |
|
326 | } |
||
327 | |||
328 | /** |
||
329 | * Get the second team involved in the match |
||
330 | * @return TeamInterface Team B |
||
331 | */ |
||
332 | 40 | public function getTeamB() |
|
333 | { |
||
334 | 40 | $team = Team::get($this->team_b); |
|
335 | |||
336 | 40 | if ($this->match_type === self::OFFICIAL && $team->isValid()) { |
|
337 | 24 | return $team; |
|
338 | } |
||
339 | |||
340 | 17 | return new ColorTeam($this->team_b_color); |
|
341 | } |
||
342 | |||
343 | /** |
||
344 | * Get the color of Team A |
||
345 | * @return string |
||
346 | */ |
||
347 | public function getTeamAColor() |
||
348 | { |
||
349 | return $this->team_a_color; |
||
350 | } |
||
351 | |||
352 | /** |
||
353 | * Get the color of Team B |
||
354 | * @return string |
||
355 | */ |
||
356 | public function getTeamBColor() |
||
357 | { |
||
358 | return $this->team_b_color; |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * Get the list of players on Team A who participated in this match |
||
363 | * @return Player[] Returns null if there were no players recorded for this match |
||
364 | */ |
||
365 | 3 | public function getTeamAPlayers() |
|
366 | { |
||
367 | 3 | return $this->parsePlayers($this->team_a_players); |
|
368 | } |
||
369 | |||
370 | /** |
||
371 | * Get the list of players on Team B who participated in this match |
||
372 | * @return Player[] Returns null if there were no players recorded for this match |
||
373 | */ |
||
374 | 3 | public function getTeamBPlayers() |
|
375 | { |
||
376 | 3 | return $this->parsePlayers($this->team_b_players); |
|
377 | } |
||
378 | |||
379 | /** |
||
380 | * Get the list of players for a team in a match |
||
381 | * @param Team|int|null The team or team ID |
||
382 | * @return Player[]|null Returns null if there were no players recorded for this match |
||
383 | */ |
||
384 | 40 | public function getPlayers($team = null) |
|
385 | { |
||
386 | 40 | if ($team instanceof TeamInterface) { |
|
387 | 1 | $team = $team->getId(); |
|
388 | } |
||
389 | |||
390 | 40 | if ($this->getTeamA()->isValid() && $team === $this->getTeamA()->getId()) { |
|
391 | 1 | return $this->getTeamAPlayers(); |
|
392 | 40 | } elseif ($this->getTeamB()->isValid() && $team === $this->getTeamB()->getId()) { |
|
393 | 1 | return $this->getTeamBPlayers(); |
|
394 | } |
||
395 | |||
396 | 40 | return $this->parsePlayers($this->team_a_players . "," . $this->team_b_players); |
|
397 | } |
||
398 | |||
399 | /** |
||
400 | * Set the players of the match's teams |
||
401 | * |
||
402 | * @param int[] $teamAPlayers An array of player IDs |
||
403 | * @param int[] $teamBPlayers An array of player IDs |
||
404 | * @return self |
||
405 | */ |
||
406 | public function setTeamPlayers($teamAPlayers = array(), $teamBPlayers = array()) |
||
407 | { |
||
408 | $this->updateProperty($this->team_a_players, "team_a_players", implode(',', $teamAPlayers)); |
||
409 | $this->updateProperty($this->team_b_players, "team_b_players", implode(',', $teamBPlayers)); |
||
410 | |||
411 | return $this; |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * Get an array of players based on a string representation |
||
416 | * @param string $playerString |
||
417 | * @return Player[] Returns null if there were no players recorded for this match |
||
418 | */ |
||
419 | 40 | private function parsePlayers($playerString) |
|
420 | { |
||
421 | 40 | if ($playerString == null) { |
|
422 | 1 | return []; |
|
423 | } |
||
424 | |||
425 | 40 | return Player::arrayIdToModel(explode(",", $playerString)); |
|
426 | } |
||
427 | |||
428 | /** |
||
429 | * Get the first team's points |
||
430 | * @return int Team A's points |
||
431 | */ |
||
432 | 25 | public function getTeamAPoints() |
|
433 | { |
||
434 | 25 | return $this->team_a_points; |
|
435 | } |
||
436 | |||
437 | /** |
||
438 | * Get the second team's points |
||
439 | * @return int Team B's points |
||
440 | */ |
||
441 | 25 | public function getTeamBPoints() |
|
442 | { |
||
443 | 25 | return $this->team_b_points; |
|
444 | } |
||
445 | |||
446 | /** |
||
447 | * Set the match team points |
||
448 | * |
||
449 | * @param int $teamAPoints Team A's points |
||
450 | * @param int $teamBPoints Team B's points |
||
451 | * @return self |
||
452 | */ |
||
453 | public function setTeamPoints($teamAPoints, $teamBPoints) |
||
454 | { |
||
455 | $this->updateProperty($this->team_a_points, "team_a_points", $teamAPoints); |
||
456 | $this->updateProperty($this->team_b_points, "team_b_points", $teamBPoints); |
||
457 | |||
458 | return $this; |
||
459 | } |
||
460 | |||
461 | /** |
||
462 | * Set the match team colors |
||
463 | * |
||
464 | * @param ColorTeam|string $teamAColor The color of team A |
||
465 | * @param ColorTeam|string $teamBColor The color of team B |
||
466 | * @return self |
||
467 | */ |
||
468 | public function setTeamColors($teamAColor, $teamBColor) |
||
469 | { |
||
470 | if ($this->isOfficial()) { |
||
471 | throw new \Exception("Cannot change team colors in an official match"); |
||
472 | } |
||
473 | |||
474 | if ($teamAColor instanceof ColorTeam) { |
||
475 | $teamAColor = $teamAColor->getId(); |
||
476 | } |
||
477 | if ($teamBColor instanceof ColorTeam) { |
||
478 | $teamBColor = $teamBColor->getId(); |
||
479 | } |
||
480 | |||
481 | $this->updateProperty($this->team_a_color, "team_a_color", $teamAColor); |
||
482 | $this->updateProperty($this->team_b_color, "team_b_color", $teamBColor); |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * Get the ELO difference applied to each team's old ELO |
||
487 | * |
||
488 | * @param bool $absoluteValue Whether or not to get the absolute value of the Elo difference |
||
489 | * |
||
490 | * @return int The ELO difference |
||
491 | */ |
||
492 | 28 | public function getEloDiff($absoluteValue = true) |
|
493 | { |
||
494 | 28 | return ($absoluteValue) ? abs($this->elo_diff) : $this->elo_diff; |
|
495 | } |
||
496 | |||
497 | /** |
||
498 | * Get the Elo difference applied to players |
||
499 | * |
||
500 | * @param bool $absoluteValue Whether or not to get the absolute value of the Elo difference |
||
501 | * |
||
502 | * @return int The Elo difference for players |
||
503 | */ |
||
504 | 22 | public function getPlayerEloDiff($absoluteValue = true) |
|
508 | |||
509 | /** |
||
510 | * Set the Elo difference applied to players |
||
511 | * |
||
512 | * @param int $diff |
||
513 | 7 | */ |
|
514 | public function setPlayerEloDiff($diff) |
||
515 | 7 | { |
|
516 | $this->updateProperty($this->player_elo_diff, 'player_elo_diff', $diff); |
||
517 | } |
||
518 | |||
519 | /** |
||
520 | * Get the first team's new ELO |
||
521 | * @return int Team A's new ELO |
||
522 | 7 | */ |
|
523 | public function getTeamAEloNew() |
||
524 | 7 | { |
|
525 | return $this->team_a_elo_new; |
||
526 | } |
||
527 | |||
528 | /** |
||
529 | * Get the second team's new ELO |
||
530 | * @return int Team B's new ELO |
||
531 | 6 | */ |
|
532 | public function getTeamBEloNew() |
||
533 | 6 | { |
|
536 | |||
537 | /** |
||
538 | * Get the first team's old ELO |
||
539 | * @return int |
||
540 | 6 | */ |
|
541 | public function getTeamAEloOld() |
||
545 | |||
546 | /** |
||
547 | * Get the second team's old ELO |
||
548 | * @return int |
||
549 | */ |
||
550 | public function getTeamBEloOld() |
||
554 | 1 | ||
555 | 1 | /** |
|
556 | 1 | * Get the team's new ELO |
|
557 | * @param Team $team The team whose new ELO to return |
||
558 | * @return int|null The new ELO, or null if the team provided has not |
||
559 | * participated in the match |
||
560 | */ |
||
561 | public function getTeamEloNew(Team $team) |
||
571 | 1 | ||
572 | 1 | /** |
|
573 | 1 | * Get the team's old ELO |
|
574 | * @param Team $team The team whose old ELO to return |
||
575 | * @return int|null The old ELO, or null if the team provided has not |
||
576 | * participated in the match |
||
577 | */ |
||
578 | public function getTeamEloOld(Team $team) |
||
588 | |||
589 | /** |
||
590 | * Get the map where the match was played on |
||
591 | * @return Map Returns an invalid map if no map was found |
||
592 | */ |
||
593 | public function getMap() |
||
597 | |||
598 | /** |
||
599 | * Set the map where the match was played |
||
600 | * @param int $map The ID of the map |
||
601 | * @return self |
||
602 | */ |
||
603 | public function setMap($map) |
||
607 | |||
608 | /** |
||
609 | * Get the type of official match this is. Whether it has just traditional teams or has mixed teams. |
||
610 | * |
||
611 | * Possible official match types: |
||
612 | 23 | * - Team vs Team |
|
613 | * - Team vs Mixed |
||
614 | 23 | * - Mixed vs Mixed |
|
615 | 9 | * |
|
616 | 14 | * @see Match::TEAM_V_TEAM |
|
617 | 9 | * @see Match::TEAM_V_MIXED |
|
618 | * @see Match::MIXED_V_MIXED |
||
619 | * |
||
620 | 5 | * @return int |
|
621 | */ |
||
622 | public function getTeamMatchType() |
||
632 | |||
633 | /** |
||
634 | * Get the match type |
||
635 | * |
||
636 | * @return string 'official', 'fm', or 'special' |
||
637 | */ |
||
638 | public function getMatchType() |
||
642 | |||
643 | /** |
||
644 | * Set the match type |
||
645 | * |
||
646 | * @param string $matchType A valid match type; official, fm, special |
||
647 | * |
||
648 | * @return static |
||
649 | */ |
||
650 | public function setMatchType($matchType) |
||
654 | |||
655 | /** |
||
656 | * Get a JSON decoded array of events that occurred during the match |
||
657 | * @return mixed|null Returns null if there were no events recorded for the match |
||
658 | 1 | */ |
|
659 | public function getMatchDetails() |
||
663 | |||
664 | /** |
||
665 | * Get the server address of the server where this match took place |
||
666 | * @return string|null Returns null if there was no server address recorded |
||
667 | */ |
||
668 | public function getServerAddress() |
||
672 | |||
673 | /** |
||
674 | * Set the server address of the server where this match took place |
||
675 | * |
||
676 | * @param string|null $server The server hostname |
||
677 | * @param int|null $port The server port |
||
678 | * @return self |
||
679 | */ |
||
680 | public function setServerAddress($server = null) |
||
686 | |||
687 | /** |
||
688 | 1 | * Get the name of the replay file for this specific map |
|
689 | * @param int $length The length of the replay file name; it will be truncated |
||
690 | * @return string Returns null if there was no replay file name recorded |
||
691 | */ |
||
692 | public function getReplayFileName($length = 0) |
||
700 | |||
701 | /** |
||
702 | * Get the match duration |
||
703 | * @return int The duration of the match in minutes |
||
704 | */ |
||
705 | public function getDuration() |
||
709 | |||
710 | /** |
||
711 | * Set the match duration |
||
712 | * |
||
713 | * @param int $duration The new duration of the match in minutes |
||
714 | * @return self |
||
715 | 2 | */ |
|
716 | public function setDuration($duration) |
||
720 | |||
721 | /** |
||
722 | * Get the user who entered the match |
||
723 | * @return Player |
||
724 | */ |
||
725 | 35 | public function getEnteredBy() |
|
729 | |||
730 | /** |
||
731 | 35 | * Get the loser of the match |
|
732 | * |
||
733 | * @return TeamInterface The team that was the loser or the team with the lower elo if the match was a draw |
||
734 | */ |
||
735 | public function getLoser() |
||
743 | |||
744 | /** |
||
745 | 35 | * Get the winner of a match |
|
746 | 20 | * |
|
747 | 16 | * @return TeamInterface The team that was the victor or the team with the lower elo if the match was a draw |
|
748 | 13 | */ |
|
749 | 3 | public function getWinner() |
|
769 | |||
770 | /** |
||
771 | * Determine whether the match was a draw |
||
772 | * @return bool True if the match ended without any winning teams |
||
773 | */ |
||
774 | public function isDraw() |
||
778 | |||
779 | /** |
||
780 | * Find out whether the match involves a team |
||
781 | * |
||
782 | * @param TeamInterface $team The team to check |
||
783 | 40 | * @return bool |
|
784 | */ |
||
785 | 40 | public function involvesTeam($team) |
|
789 | |||
790 | /** |
||
791 | * Find out if the match is played between official teams |
||
792 | */ |
||
793 | public function isOfficial() |
||
797 | |||
798 | /** |
||
799 | * Reset the ELOs of the teams participating in the match |
||
800 | * |
||
801 | * @return self |
||
802 | */ |
||
803 | public function resetELOs() |
||
812 | |||
813 | 1 | /** |
|
814 | * Calculate the match's contribution to the team activity |
||
815 | 1 | * |
|
816 | * @return float |
||
817 | */ |
||
818 | public function getActivity() |
||
831 | |||
832 | /** |
||
833 | * Calculate the Elo differences for players and teams for a given match. |
||
834 | * |
||
835 | * @param Team $a |
||
836 | * @param Team $b |
||
837 | * @param int $a_points |
||
838 | * @param int $b_points |
||
839 | * @param int[]|Player[] $a_players |
||
840 | * @param int[]|Player[] $b_players |
||
841 | * @param int $duration |
||
842 | * |
||
843 | * @throws InvalidArgumentException When a "Mixed" team is entered without a player roster |
||
844 | * |
||
845 | 41 | * @return array |
|
846 | */ |
||
847 | private static function calculateElos($a, $b, $a_points, $b_points, $a_players, $b_players, $duration) |
||
906 | 24 | ||
907 | 24 | /** |
|
908 | * Enter a new match to the database |
||
909 | * @param int $a Team A's ID |
||
910 | * @param int $b Team B's ID |
||
911 | 40 | * @param int $a_points Team A's match points |
|
912 | 40 | * @param int $b_points Team B's match points |
|
913 | * @param int $duration The match duration in minutes |
||
914 | 40 | * @param int|null $entered_by The ID of the player reporting the match |
|
915 | * @param string|DateTime $timestamp When the match was played |
||
916 | 40 | * @param int[] $a_players The IDs of the first team's players |
|
917 | 40 | * @param int[] $b_players The IDs of the second team's players |
|
918 | * @param string|null $server The address of the server where the match was played |
||
919 | * @param string $replayFile The name of the replay file of the match |
||
920 | 40 | * @param int $map The ID of the map where the match was played, only for rotational leagues |
|
921 | 40 | * @param string $matchType The type of match (e.g. official, fm, special) |
|
922 | * @param string $a_color Team A's color |
||
923 | 40 | * @param string $b_color Team b's color |
|
924 | 28 | * |
|
925 | * @throws InvalidArgumentException When a ColorTeam is selected for an official match and no players are defined |
||
926 | * for that team |
||
927 | 40 | * |
|
928 | * @return Match An object representing the match that was just entered |
||
929 | */ |
||
930 | 40 | public static function enterMatch( |
|
985 | |||
986 | /** |
||
987 | * Calculate the ELO score difference |
||
988 | * |
||
989 | * Computes the ELO score difference on each team after a match, based on |
||
990 | * GU League's rules. |
||
991 | * |
||
992 | * @param int $a_elo Team A's current ELO score |
||
993 | * @param int $b_elo Team B's current ELO score |
||
994 | * @param int $a_points Team A's match points |
||
995 | * @param int $b_points Team B's match points |
||
996 | * @param int $duration The match duration in minutes |
||
997 | * @return int The ELO score difference |
||
998 | */ |
||
999 | public static function calculateEloDiff($a_elo, $b_elo, $a_points, $b_points, $duration) |
||
1022 | |||
1023 | /** |
||
1024 | * Find if a match's stored ELO is correct |
||
1025 | */ |
||
1026 | public function isEloCorrect() |
||
1036 | |||
1037 | /** |
||
1038 | * Recalculate the match's elo and adjust the team ELO values |
||
1039 | */ |
||
1040 | public function recalculateElo() |
||
1065 | |||
1066 | /** |
||
1067 | * Get all the matches in the database |
||
1068 | */ |
||
1069 | public static function getMatches() |
||
1073 | |||
1074 | 22 | /** |
|
1075 | 22 | * Get a query builder for matches |
|
1076 | * @return MatchQueryBuilder |
||
1077 | 21 | */ |
|
1078 | 9 | public static function getQueryBuilder() |
|
1093 | |||
1094 | 22 | /** |
|
1095 | 22 | * {@inheritdoc} |
|
1096 | 22 | */ |
|
1097 | 22 | public function delete() |
|
1108 | |||
1109 | /** |
||
1110 | * {@inheritdoc} |
||
1111 | */ |
||
1112 | 28 | public static function getActiveStatuses() |
|
1116 | 28 | ||
1117 | /** |
||
1118 | * {@inheritdoc} |
||
1119 | */ |
||
1120 | public function getName() |
||
1152 | |||
1153 | 2 | /** |
|
1154 | * Get the average ELO for an array of players |
||
1155 | * |
||
1156 | * @param int[]|Player[] $players |
||
1157 | * |
||
1158 | * @return float|int |
||
1159 | */ |
||
1160 | private static function getAveragePlayerElo($players) |
||
1172 | |||
1173 | /** |
||
1174 | * Update the match count of the teams participating in the match |
||
1175 | * |
||
1176 | * @param bool $decrement Whether to decrement instead of incrementing the match count |
||
1177 | */ |
||
1178 | private function updateMatchCount($decrement = false) |
||
1194 | |||
1195 | /** |
||
1196 | * Update the Elos for the participating players in a match |
||
1197 | */ |
||
1198 | private function updatePlayerElo() |
||
1220 | } |
||
1221 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.