View difference between Paste ID: YVQTjVqe and WbNLej2d
SHOW: | | - or go back to the newest paste.
1
<?php
2
3
namespace Equidea;
4
5
use Equidea\Core\Controller;
6
use Equidea\Core\Response;
7
8
use Equidea\Display\Template;
9
10
/**
11
 * Controller that handles requests to the websites root.
12
 */
13
class Index extends Controller
14
{
15
    // @parent: $container, $request, $response
16
    // @construct: $template
17
    
18
    public function __construct(
19
        private Template $template
20
    ) {}
21
    
22
    /**
23
     * Renders the webpage and puts it inside of the response body.
24
     */
25
    private function renderWebsite(array $data = []) : Response
26
    {
27
        $view = $this->template->render('index', $data);
28
        return $this->response->withBody($view);
29
    }
30
    
31
    /**
32
     * Serves the index page.
33
     */
34
    public function getIndex() : Response {
35
        return $this->renderWebsite();
36
	}
37
    
38
    /**
39
     * Attempts to calculate foal exterieur on correct user input.
40
     */
41
    public function postExterieur() : Response
42
    {
43
        // GET AND CLEAN INPUT
44
        
45
        $stallion = $_POST['stallion'] ?? '';
46
        $stallion = trim($stallion);
47
        
48
        $mare = $_POST['mare'] ?? '';
49
        $mare = trim($mare);
50
        
51
        // CHECK FOR EVERY FIELD BEING FILLED OUT
52
        
53
        if (empty($stallion) || empty($mare)) {
54
            $error = 'Du hast nicht alle Felder ausgefüllt';
55
            return $this->renderWebsite(['error' => $error]);
56
        }
57
        
58
        // ON VALID INPUT CALCULATE EXTERIEUR
59
        
60
        if ($this->validateInput($mare) && $this->validateInput($stallion))
61
        {
62
            // BREAK GENE STRINGS INTO PARTS
63
            
64
            $stallionGenes = $this->importExterieur($stallion);
65
            $mareGenes = $this->importExterieur($mare);
66
            
67
            // CALCULATE EXTERIEUR ONE BY ONE
68
            
69
            $foal = [];
70
            
71
            $worst = $this->calculateWorst($stallionGenes, $mareGenes);
72-
            $foal['worst'] = $this->exportExterieur($worst);
72+
            $foal['worst']['genes'] = $this->exportExterieur($worst);
73
            $foal['worst']['grade'] = $this->calculateGrade($worst);
74
            
75-
            $foal['best'] = $this->exportExterieur($best);
75+
            $average = $this->calculateAverage($stallionGenes, $mareGenes);
76
            $foal['average']['genes'] = $this->exportExterieur($average);
77
            $foal['average']['grade'] = $this->calculateGrade($average);
78
            
79
            $best = $this->calculateBest($stallionGenes, $mareGenes);
80-
                'stallion' => $stallion,
80+
            $foal['best']['genes'] = $this->exportExterieur($best);
81-
                'mare' => $mare,
81+
            $foal['best']['grade'] = $this->calculateGrade($best);
82
            
83
            // $foal['average'] = null;
84
            
85
            return $this->renderWebsite([
86
                'stallion' => [
87
                    'genes' => $stallion,
88
                    'grade' => $this->calculateGrade($stallionGenes)
89
                ],
90
                'mare' => [
91
                    'genes' => $mare,
92
                    'grade' => $this->calculateGrade($mareGenes)
93
                ],
94
                'foal' => $foal
95
            ]);
96
        }
97
        
98
        // OTHERWISE RENDER ERROR
99
        
100
        $error = 'Die Eingabe war fehlerhaft.';
101
        return $this->renderWebsite(['error' => $error]);
102
    }
103
    
104
    /**
105
     * Checks whether user input is valid.
106
     */
107
    private function validateInput(string $input) : bool
108
    {
109
        $regex = '#^([Hh]{2}\s){7}[Hh]{2}$#';
110
        return preg_match($regex, $input) == 1;
111
    }
112
    
113
    /**
114
     * Translates the gene string into an array of arrays
115
     */
116
    private function importExterieur(string $raw) : array
117
    {
118
        $rawGenes = explode(' ', $raw);
119-
    private function exportExterieur(array $raw) : string
119+
120
        
121
        foreach ($rawGenes as $key => $value) {
122
            $genes[$key] = str_split($value);
123
        }
124
        
125
        return $genes;
126
    }
127-
        return implode(' ', $genes);
127+
128
    /**
129
     * Translates an array of genes into a string.
130
     */
131
    private function getArrayGenesAsString(array $raw) : array
132
    {
133
        $genes = [];
134
        
135
        foreach ($raw as $key => $value) {
136
            $genes[$key] = implode($value);
137
        }
138
        
139
        return $genes;
140
    }
141
    
142
    /**
143
     * Translates the gene array of array into a readable string
144
     */
145
    private function exportExterieur(array $genes) : string {
146
        return implode(' ', $this->getArrayGenesAsString($genes));
147
    }
148
    
149
    /**
150
     * Calculates the theoretical foal with the worst possible exterieur.
151
     */
152
    private function calculateWorst(array $stallion, array $mare) : array
153
    {
154
        $foal = [];
155
        
156
        for ($i = 0; $i < 4; $i++)
157
        {
158
            $left = in_array('h', $stallion[$i]) ? 'h' : 'H';
159
            $right = in_array('h', $mare[$i]) ? 'h' : 'H';
160
            $foal[$i] = [$left, $right];
161
        }
162
        
163
        for ($i = 4; $i < 8; $i++)
164
        {
165
            $left = in_array('H', $stallion[$i]) ? 'H' : 'h';
166
            $right = in_array('H', $mare[$i]) ? 'H' : 'h';
167
            $foal[$i] = [$left, $right];
168
        }
169
        
170
        return $foal;
171
    }
172
    
173
    /**
174
     * Calculates the average foal exterieur.
175
     */
176
    private function calculateAverage(array $stallion, array $mare) : array
177
    { 
178
        $foal = [];
179
        
180
        $stallion = $this->getArrayGenesAsString($stallion);
181
        $mare = $this->getArrayGenesAsString($mare);
182
        
183
        for ($i = 0; $i < 8; $i++)
184
        {
185
            // HH + x
186
            if ($stallion[$i] == 'HH')
187
            {
188
                if ($mare[$i] == 'HH') {
189
                    $foal[$i] = ['H', 'H'];
190
                }
191
                
192
                if ($mare[$i] == 'hh') {
193
                    $foal[$i] = ['H', 'h'];
194
                }
195
                
196
                if ($mare[$i] == 'Hh' || $mare[$i] == 'hH')
197
                {
198
                    if ($i > 3) {
199
                        $foal[$i] = ['H', 'h'];
200
                    } else {
201
                        $foal[$i] = ['H', 'H'];
202
                    }
203
                }
204
            }
205
            
206
            // hh + x
207
            if ($stallion[$i] == 'hh')
208
            {
209
                if ($mare[$i] == 'HH') {
210
                    $foal[$i] = ['h', 'H'];
211
                }
212
                
213
                if ($mare[$i] == 'hh') {
214
                    $foal[$i] = ['h', 'h'];
215
                }
216
                
217
                if ($mare[$i] == 'Hh' || $mare[$i] == 'hH')
218
                {
219
                    if ($i > 3) {
220
                        $foal[$i] = ['h', 'h'];
221
                    } else {
222
                        $foal[$i] = ['h', 'H'];
223
                    }
224
                }
225
            }
226
            
227
            // Hh or hH + x
228
            if ($stallion[$i] == 'Hh' || $stallion[$i] == 'hH')
229
            {
230
                if ($mare[$i] == 'HH')
231
                {
232
                    if ($i > 3) {
233
                        $foal[$i] = ['h', 'H'];
234
                    } else {
235
                        $foal[$i] = ['H', 'H'];
236
                    }
237
                }
238
                
239
                if ($mare[$i] == 'hh')
240
                {
241
                    if ($i > 3) {
242
                        $foal[$i] = ['h', 'h'];
243
                    } else {
244
                        $foal[$i] = ['H', 'h'];
245
                    }
246
                }
247
                
248
                if ($mare[$i] == 'Hh' || $mare[$i] == 'hH')
249
                {
250
                    $variants = [['H', 'h'], ['h', 'H']];
251
                    $foal[$i] = $variants[mt_rand(0,1)];
252
                }
253
            }
254
        }
255
        
256
        return $foal;
257
    }
258
    
259
    /**
260
     * Calculates the theoretical foal with the best possible exterieur.
261
     */
262
    private function calculateBest(array $stallion, array $mare) : array
263
    {
264
        $foal = [];
265
        
266
        for ($i = 0; $i < 4; $i++)
267
        {
268
            $left = in_array('H', $stallion[$i]) ? 'H' : 'h';
269
            $right = in_array('H', $mare[$i]) ? 'H' : 'h';
270
            $foal[$i] = [$left, $right];
271
        }
272
        
273
        for ($i = 4; $i < 8; $i++)
274
        {
275
            $left = in_array('h', $stallion[$i]) ? 'h' : 'H';
276
            $right = in_array('h', $mare[$i]) ? 'h' : 'H';
277
            $foal[$i] = [$left, $right];
278
        }
279
        
280
        return $foal;
281
    }
282
    
283
    /**
284
     * Calculates the grade between 1 and 5 by interpreting the given
285
     * genetical code.
286
     */
287
    private function calculateGrade(array $genes) : int
288
    {
289
        $left = 0;
290
        $right = 0;
291
        
292
        // Calculate number of right genes
293
        for ($i = 0; $i < 4; $i++) {
294
            $left += in_array('H', $genes[$i]) ? 1 : 0;
295
        }
296
        
297
        for ($i = 4; $i < 8; $i++) {
298
            $right += in_array('H', $genes[$i]) ? 0 : 1;
299
        }
300
        
301
        $score = ($left < $right) ? $left : $right;
302
        
303
        // Calculate the grade
304
        switch ($score) {
305
            case 4: return 1;
306
            case 3: return 2;
307
            case 2: return 3;
308
            case 1: return 4;
309
            default: return 5;
310
        }
311
    }
312
}