DrawLeague   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 4
dl 0
loc 184
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setTournament() 0 20 2
A handle() 0 17 3
A draw() 0 6 1
B drawBergerTable() 0 24 5
A addReversMarches() 0 14 3
A isOddTeamsCnt() 0 7 2
A setPairCnt() 0 4 1
A saveRounds() 0 19 3
1
<?php
2
3
namespace App\Jobs\Tournament;
4
5
use App\Match;
6
use App\Tournament;
7
use Illuminate\Database\Eloquent\Collection;
8
9
/**
10
 * Class DrawLeague
11
 * @package App\Jobs\Tournament
12
 */
13
class DrawLeague extends Job
14
{
15
    /**
16
     * @var array
17
     */
18
    protected $teams = [];
19
20
    /**
21
     * @var Collection
22
     */
23
    protected $rounds;
24
25
    /**
26
     * @var Collection
27
     */
28
    protected $matches;
29
30
    /**
31
     * @var boolean
32
     */
33
    protected $isOdd = false;
34
35
    /**
36
     * @var int
37
     */
38
    protected $teamsCount;
39
40
    /**
41
     * @var int
42
     */
43
    protected $pairCnt;
44
45
    /**
46
     * @name setTournament
47
     * @param Tournament $tournament
48
     */
49
    protected function setTournament(Tournament $tournament)
50
    {
51
        $this->tournament = $tournament;
52
53
        foreach ($this->tournament->tournamentTeams()->getResults() as $team) {
54
            $team->team->homeMatchesAmount = 0;
55
            $team->team->wasPulledOut = false;
56
            $team->team->pulledOut = false;
57
            $this->teams[] = [
58
                'id' => $team->id,
59
                'name' => $team->team->name
60
            ];
61
        }
62
63
        shuffle($this->teams);
64
65
        $this->teamsCount = count($this->teams);
66
        $this->isOddTeamsCnt();
67
        $this->setPairCnt();
68
    }
69
70
    /**
71
     * Handle the job
72
     *
73
     * @return void
74
     * @throws \UnexpectedValueException
75
     */
76
    public function handle()
77
    {
78
        if (Tournament::MIN_TEAMS_AMOUNT > count($this->teams)) {
79
            throw new \UnexpectedValueException('Tournament should have at least 2 teams.');
80
        }
81
82
        /**
83
         * @var $matches Collection
84
         */
85
        $matches = $this->tournament->matches()->getResults();
86
87
        if (0 < $matches->count()) {
88
            throw new \UnexpectedValueException('Tournament draw has been already done.');
89
        }
90
91
        $this->draw();
92
    }
93
94
    /**
95
     * @name draw
96
     */
97
    protected function draw()
98
    {
99
        $table = $this->drawBergerTable();
100
101
        $this->saveRounds($table);
102
    }
103
104
    /**
105
     * Create scheduling for one season by Berger algorithm https://en.wikipedia.org/wiki/Round-robin_tournament
106
     * @name drawBergerTable
107
     * @return array
108
     */
109
    protected function drawBergerTable()
110
    {
111
        $a = [];
112
        $table = [];
113
114
        for ($i = 1; $i < $this->teamsCount; $i++) {
115
            $a[] = $i;
116
        }
117
118
        for ($i = 0; $i < $this->teamsCount - 1; $i++) {
119
            $table[$i] = [];
120
            if (!$this->isOdd) {
121
                $table[$i][] = [$a[0], $this->teamsCount];
122
            }
123
            for ($j = 1; $j < $this->pairCnt; $j++) {
124
                $table[$i][] = [$a[$j], $a[$this->teamsCount - 1 - $j]];
125
            }
126
            $a[] = array_shift($a);
127
        }
128
129
        $table = $this->addReversMarches($table);
130
131
        return $table;
132
    }
133
134
    /**
135
     * @name addReversMarches
136
     * @param $table
137
     * @return array
138
     */
139
    protected function addReversMarches($table)
140
    {
141
        for ($i = count($table) - 1; $i >= 0; $i--) {
142
            $day = $table[$i];
143
144
            $nDay = [];
145
            foreach ($day as $match) {
146
                $nDay[] = [$match[1], $match[0]];
147
            }
148
            $table[] = $nDay;
149
        }
150
151
        return $table;
152
    }
153
154
    /**
155
     * Check if teams is odd count
156
     * @name isOddTeamsCnt
157
     */
158
    protected function isOddTeamsCnt()
159
    {
160
        if ($this->teamsCount % 2 != 0) {
161
            $this->isOdd = true;
162
            $this->teamsCount++;
163
        }
164
    }
165
166
    /**
167
     * @name setPairCnt
168
     */
169
    protected function setPairCnt()
170
    {
171
        $this->pairCnt = (int)$this->teamsCount / 2;
172
    }
173
174
    /**
175
     * @name saveRounds
176
     */
177
    protected function saveRounds($table)
178
    {
179
        foreach ($table as $key => $round) {
180
            foreach ($round as $match) {
181
                $this->tournament->matches()->create([
182
                    'homeTournamentTeamId' => $this->teams[$match[0] - 1]['id'],
183
                    'awayTournamentTeamId' => $this->teams[$match[1] - 1]['id'],
184
                    'homeScore' => 0,
185
                    'awayScore' => 0,
186
                    'homePenaltyScore' => 0,
187
                    'awayPenaltyScore' => 0,
188
                    'round' => $key + 1,
189
                    'gameType' => Match::GAME_TYPE_GROUP_STAGE,
190
                    'resultType' => Match::RESULT_TYPE_UNKNOWN,
191
                    'status' => Match::STATUS_NOT_STARTED
192
                ]);
193
            }
194
        }
195
    }
196
}
197