GameController::newWord()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 14
rs 9.2
c 1
b 1
f 0
cc 4
eloc 8
nc 4
nop 1
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Events\RoomUpdate;
6
use App\Models\Room;
7
use App\Models\Word;
8
use Illuminate\Database\Eloquent\ModelNotFoundException;
9
use Illuminate\Routing\Controller;
10
11
class GameController extends Controller
12
{
13
    private $numberOfFields = [
14
        'red'     => 8,
15
        'blue'    => 8,
16
        'netural' => 7,
17
        'death'   => 1,
18
    ];
19
20
    private $nextPlayer = [
21
        'red'  => 'blue',
22
        'blue' => 'red',
23
    ];
24
25
    public function getRoomState($id = null)
26
    {
27
        try {
28
            $state = Room::whereId($id)->firstOrFail()->state;
29
        } catch (ModelNotFoundException $exception) {
30
            $state = $this->createRoom($id);
31
        }
32
33
        return $this->calcFieldPosition($state);
34
    }
35
36
    private function createRoom($id)
37
    {
38
        $state = [];
39
        $state['currentTeam'] = $this->randCurrentTeam();
40
        $wordList = $this->shuffleRandomWords();
41
        $typeList = $this->randFieldColors($state['currentTeam']);
42
43
        for ($i = 0; $i < 5; $i++) {
44
            for ($j = 0; $j < 5; $j++) {
45
                $state['table'][$i][$j]['word'] = $wordList[$i * 5 + $j]['word'];
46
                $state['table'][$i][$j]['type'] = $typeList[$i * 5 + $j];
47
                $state['table'][$i][$j]['flipped'] = false;
48
            }
49
        }
50
        $state['score'] = [
51
            'red'  => 0,
52
            'blue' => 0,
53
        ];
54
        $state['nextButton'] = 'Start';
55
        $state['state'] = 'start';
56
        $this->saveRoom($id, $state);
57
58
        return $state;
59
    }
60
61
    public function flip($id, $x, $y)
62
    {
63
        $room = Room::whereId($id)->firstOrFail();
64
        $state = $room->state;
65
        if ($state['state'] == 'start') {
66
            $state['table'][$x][$y]['word'] = '';
67
            $state['table'][$x][$y]['word'] = $this->newWord($state);
68
        }
69
        if ($state['state'] == 'game') {
70
            $state['table'][$x][$y]['flipped'] = true;
71
            switch ($state['table'][$x][$y]['type']) {
72
                case 'death':
73
                    if ($state['currentTeam'] === 'red') {
74
                        $state['score']['red'] = 0;
75
                    }
76
                    if ($state['currentTeam'] === 'blue') {
77
                        $state['score']['blue'] = 0;
78
                    }
79
                    $state['state'] = 'end';
80
                    $state['nextButton'] = 'Restart';
81
                    break;
82
                case 'netural':
83
                    $this->nextPlayer($state);
84
                    break;
85
                default:
86
                    $team = $state['table'][$x][$y]['type'];
87
                    $state['score'][$team]++;
88
                    if ($state['currentTeam'] != $team) {
89
                        $this->nextPlayer($state);
90
                    }
91
                    break;
92
            }
93
        }
94
        $room->state = $state;
95
        $room->save();
96
        $this->broadcast($room->id, $state);
97
    }
98
99
    public function turn($id = null)
100
    {
101
        $room = Room::whereId($id)->firstOrFail();
102
        $state = $room->state;
103
        switch ($state['state']) {
104
            case 'start':
105
                $state['nextButton'] = 'Next';
106
                $state['state'] = 'game';
107
                $room->state = $state;
108
                $room->save();
109
                break;
110
            case 'game':
111
                $this->nextPlayer($state);
112
                $room->state = $state;
113
                $room->save();
114
                break;
115
            default:
116
                $room->delete();
117
                $state = $this->createRoom($room->id);
118
                break;
119
        }
120
        $this->broadcast($id, $state);
121
    }
122
123
    private function nextPlayer(&$state)
124
    {
125
        $state['currentTeam'] = $this->nextPlayer[$state['currentTeam']];
126
    }
127
128
    /**
129
     * @param string $startTeam
130
     */
131
    private function randFieldColors($startTeam)
132
    {
133
        $this->numberOfFields[$startTeam] += 1;
134
135
        $typeList = [];
136
        foreach ($this->numberOfFields as $color => $number) {
137
            for ($i = 0; $i < $number; $i++) {
138
                $typeList[] = $color;
139
            }
140
        }
141
        shuffle($typeList);
142
143
        return $typeList;
144
    }
145
146
    private function newWord(&$state)
147
    {
148
        $newWord = Word::inRandomOrder()->first()->word;
149
        for ($i = 0; $i < 5; $i++) {
150
            for ($j = 0; $j < 5; $j++) {
151
                if ($newWord == $state['table'][$i][$j]['word']) {
152
                    $newWord = $this->newWord($state);
153
                    break 2;
154
                }
155
            }
156
        }
157
158
        return $newWord;
159
    }
160
161
    private function calcFieldPosition($state)
162
    {
163
        $x = 0;
164
        $y = 0;
165
        foreach ($state['table'] as &$rows) {
166
            foreach ($rows as &$cell) {
167
                $cell['x'] = $x;
168
                $cell['y'] = $y;
169
                $x++;
170
            }
171
            $x = 0;
172
            $y++;
173
        }
174
175
        return $state;
176
    }
177
178
    private function broadcast($roomId, $state)
179
    {
180
        event(new RoomUpdate($roomId, $this->calcFieldPosition($state)));
181
    }
182
183
    private function randCurrentTeam()
184
    {
185
        return rand(0, 1) == 0 ? 'red' : 'blue';
186
    }
187
188
    private function saveRoom($id, $state)
189
    {
190
        $room = new Room();
191
        $room->id = $id;
192
        $room->state = $state;
193
        $room->save();
194
    }
195
196
    private function shuffleRandomWords()
197
    {
198
        $wordList = Word::inRandomOrder()->take(25)->get()->toArray();
199
        shuffle($wordList);
200
201
        return $wordList;
202
    }
203
}
204