Test Failed
Push — master ( 7d2376...38002a )
by Johan
04:04
created

Scoring   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 297
Duplicated Lines 39.06 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 8.64%

Importance

Changes 0
Metric Value
wmc 57
lcom 1
cbo 1
dl 116
loc 297
ccs 14
cts 162
cp 0.0864
rs 5.04
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setPointsSessions() 0 24 1
B checkFullRow() 43 43 7
B checkFullColumn() 40 40 7
A sortHand() 0 37 4
B scoreSameSuit() 0 27 7
A checkValueOccurrence() 0 19 6
A fourOfAKind() 11 11 3
A fullHouse() 11 11 4
A threeOfAKind() 11 11 4
B twoPairsOrPair() 0 27 9
A straightOrNothing() 0 18 4
A setNotScoredYetBackToFalse() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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 Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Scoring 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 Scoring, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
// Folder \Controllers containing classes
6
namespace Joki20\Http\Controllers;
7
8
// use Joki20\Http\Controllers\PokerSquares;
9
use Joki20\Http\Controllers\Setup;
10
11
/**
12
 * Class Scoring;
13
 */
14
15
16
class Scoring extends Setup
17
{
18
    private $currentSession = '';
19
    private $suitsRow = [];
20
    private $valuesRow = [];
21
    private $suitsColumn = [];
22
    private $valuesColumn = [];
23
    private $scoreSession = [];
24
    private $sortedValues = [];
25
    private $consecutiveArray = false;
26
    private $times;
27
    private $occurrencesValues = [];
28
    private $notScoredYet;
29
30 1
    public function setPointsSessions(): void
31
    {
32
        // row data (suits array and values array)
33 1
        session()->put('dataRow0', []);
34 1
        session()->put('dataRow1', []);
35 1
        session()->put('dataRow2', []);
36 1
        session()->put('dataRow3', []);
37 1
        session()->put('dataRow4', []);
38
        // column data (suits array and values array)
39 1
        session()->put('dataColumn0', []);
40 1
        session()->put('dataColumn1', []);
41 1
        session()->put('dataColumn2', []);
42 1
        session()->put('dataColumn3', []);
43 1
        session()->put('dataColumn4', []);
44
        // counting times of each result for highscore list
45
        // has to reset to 0 each time score is calculated, and not null according to database
46 1
        session()->put('count', [
47 1
            'nothing' => 0, 'pair' => 0,
48
            'twoPairs' => 0, 'threeofakind' => 0,
49
            'straight' => 0, 'flush' => 0,
50
            'fullhouse' => 0, 'fourofakind' => 0,
51
            'straightflush' => 0, 'royalstraightflush' => 0
52
        ]);
53 1
    }
54
55 View Code Duplication
    public function checkFullRow(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
56
    {
57
        // LOOP FOR EACH ROW
58
        for ($row = 0; $row < 5; $row++) {
59
            for ($column = 0; $column < 5; $column++) {
60
                $this->notScoredYet = true;
61
                // initial length is 0, if not then session contians card
62
                // ROW SUITS AND VALUES
63
                // if a card is existing (form length has 235)
64
                $this->currentSession = session('grid.' . $row . $column);
65
                if (strlen($this->currentSession) != 235) {
66
                    // collect suit HDSC and value 02-14 for row
67
                    array_push($this->suitsRow, substr($this->currentSession, 23, 1));
68
                    array_push($this->valuesRow, substr($this->currentSession, 21, 2));
69
                }
70
                // ROW SAVE AND SCORE DATA
71
                // if five cards (five suits), push suits and values arrays
72
                if ($column == 4 && count($this->suitsRow) == 5) {
73
                    // session('dataRow00', [[H,D,C,S,D],[03,05,01,13,10]])
74
                    session()->push('dataRow' . $row, $this->suitsRow);
75
                    session()->push('dataRow' . $row, $this->valuesRow);
76
                    // send array of suits and values for row to score function
77
                    $this->sortHand('Row' . $row);
78
                    // when match is found, $this->notScoredYet = false and rest of functions will not proceed
79
                    $this->scoreSameSuit('Row' . $row);
80
                    $this->checkValueOccurrence('Row' . $row);
0 ignored issues
show
Unused Code introduced by
The call to Scoring::checkValueOccurrence() has too many arguments starting with 'Row' . $row.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
81
                    $this->fourOfaKind('Row' . $row);
82
                    $this->fullHouse('Row' . $row);
83
                    $this->threeOfAKind('Row' . $row);
84
                    $this->twoPairsOrPair('Row' . $row);
85
                    $this->straightOrNothing('Row' . $row);
86
87
                    // before next loop, reset to false
88
                    $this->setNotScoredYetBackToFalse();
89
                }
90
                // reset suits and values before next column
91
                if ($column == 4) {
92
                    $this->suitsRow = [];
93
                    $this->valuesRow = [];
94
                }
95
            }
96
        }
97
    }
98
99 View Code Duplication
    public function checkFullColumn(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
100
    {
101
        // LOOP FOR EACH COLUMN
102
        for ($column = 0; $column < 5; $column++) {
103
            for ($row = 0; $row < 5; $row++) {
104
                $this->notScoredYet = true;
105
                // ROW SUITS AND VALUES
106
                // if a card is existing (form length has 233)
107
                $this->currentSession = session('grid.' . $row . $column);
108
                if (strlen($this->currentSession) != 235) {
109
                    // collect suit HDSC and value 02-14 for column
110
                    array_push($this->suitsColumn, substr($this->currentSession, 23, 1));
111
                    array_push($this->valuesColumn, substr($this->currentSession, 21, 2));
112
                }
113
                // COLUMN SAVE AND SCORE DATA
114
                if ($row == 4 && count($this->suitsColumn) == 5) {
115
                    session()->push('dataColumn' . $column, $this->suitsColumn);
116
                    session()->push('dataColumn' . $column, $this->valuesColumn);
117
118
                    //begin with sorting hand and set
119
                    $this->sortHand('Column' . $column);
120
                    // when match is found, $this->notScoredYet = false and rest of functions will not proceed
121
                    $this->scoreSameSuit('Column' . $column);
122
                    $this->checkValueOccurrence('Column' . $column);
0 ignored issues
show
Unused Code introduced by
The call to Scoring::checkValueOccurrence() has too many arguments starting with 'Column' . $column.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
123
                    $this->fourOfaKind('Column' . $column);
124
                    $this->fullHouse('Column' . $column);
125
                    $this->threeOfAKind('Column' . $column);
126
                    $this->twoPairsOrPair('Column' . $column);
127
                    $this->straightOrNothing('Column' . $column);
128
                    // before next loop, reset to false
129
                    $this->setNotScoredYetBackToFalse();
130
                }
131
                // reset suits and values before next column
132
                if ($row == 4) {
133
                    $this->suitsColumn = [];
134
                    $this->valuesColumn = [];
135
                }
136
            }
137
        }
138
    }
139
140
    public function sortHand($type)
141
    {
142
        // set initial value to 0, increment with ++ when a hand fulfills
143
        $this->countNothing = 0;
0 ignored issues
show
Bug introduced by
The property countNothing does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
144
        $this->countPair = 0;
0 ignored issues
show
Bug introduced by
The property countPair does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
145
        $this->countTwopairs = 0;
0 ignored issues
show
Bug introduced by
The property countTwopairs does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
146
        $this->countThreeofakind = 0;
0 ignored issues
show
Bug introduced by
The property countThreeofakind does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
147
        $this->countStraight = 0;
0 ignored issues
show
Bug introduced by
The property countStraight does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
148
        $this->countFlush = 0;
0 ignored issues
show
Bug introduced by
The property countFlush does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
149
        $this->countFullhouse = 0;
0 ignored issues
show
Bug introduced by
The property countFullhouse does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
150
        $this->countFourofakind = 0;
0 ignored issues
show
Bug introduced by
The property countFourofakind does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
151
        $this->countStraightflush = 0;
0 ignored issues
show
Bug introduced by
The property countStraightflush does not seem to exist. Did you mean countStraight?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
152
        $this->countRoyalstraightflush = 0;
0 ignored issues
show
Bug introduced by
The property countRoyalstraightflush does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
153
        $this->consecutiveArray = false;
154
155
       // type is string dataRowX/dataColumnX array with suits. Used with session()->put()
156
       // scoreSession[0] is suits, scoreSession[1] is values
157
        $this->scoreSession = session('data' . $type); // i e dataRow21
0 ignored issues
show
Documentation Bug introduced by
It seems like session('data' . $type) of type * is incompatible with the declared type array of property $scoreSession.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
158
       // set consecutive to true
159
        $this->consecutiveArray = true;
160
        // CREATE COPY ARRAY AND SORT VALUES
161
        $this->sortedValues = $this->scoreSession[1];
162
        sort($this->sortedValues);
163
       // check if consecutive numbers
164
        for ($i = 0; $i < 4; $i++) {
165
            if (intval($this->sortedValues[$i + 1]) != intval($this->sortedValues[$i]) + 1) {
166
                $this->consecutiveArray = false;
167
            }
168
        }
169
170
        if ($this->sortedValues === ["14", "01", "02", "03", "04"]) {
171
            $this->consecutiveArray = true;
172
        }
173
174
        return $this->sortedValues;
175
       // END OF SORT
176
    }
177
178
    public function scoreSameSuit($type)
179
    {
180
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
181
            // ///////////// SAME SUIT /////////////
182
            // how many different suits. 1 means all are same
183
            if (count(array_count_values($this->scoreSession[0])) == 1) {
184
                // if straight
185
                if ($this->consecutiveArray == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
186
                    // ROYAL STRAIGHT FLUSH 10-A
187
                    if ($this->sortedValues[0] == "10") {
188
                        session()->put('score' . $type, ['score' => 100, 'feedback' => 'ROYAL STRAIGHT FLUSH']);
189
                        session()->put('count.royalstraightflush', session('count.royalstraightflush') + 1);
190
                        $this->notScoredYet = false;
191
                    // STRAIGHT FLUSH
192
                    } elseif (($this->sortedValues[0] != "10")) {
193
                        session()->put('score' . $type, ['score' => 75, 'feedback' => 'STRAIGHT FLUSH']);
194
                        session()->put('count.straightflush', session('count.straightflush') + 1);
195
                        $this->notScoredYet = false;
196
                    } // FLUSH
197
                } elseif ($this->consecutiveArray == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
198
                    session()->put('score' . $type, ['score' => 20, 'feedback' => 'FLUSH']);
199
                    session()->put('count.flush', session('count.flush') + 1);
200
                    $this->notScoredYet = false;
201
                }
202
            }
203
        }
204
    }
205
206
    public function checkValueOccurrence(): void
207
    {
208
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
209
            if (count(array_count_values($this->scoreSession[1])) > 1) {
210
                $this->occurrencesValues = [];
211
                // count occurrences of each value, insert into $occurrences array
212
                $this->times = 0;
213
                for ($val = 0; $val < 5; $val++) {
214
                    for ($match = 0; $match < 5; $match++) {
215
                        if ($this->scoreSession[1][$val] == $this->scoreSession[1][$match]) {
216
                            $this->times++;
217
                        }
218
                    }
219
                    array_push($this->occurrencesValues, $this->times);
220
                    $this->times = 0;
221
                }
222
            }
223
        }
224
    }
225
226 View Code Duplication
    public function fourOfAKind($type): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
227
    {
228
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
229
            // 4 OF A KIND
230
            if (in_array(4, $this->occurrencesValues)) {
231
                session()->put('score' . $type, ['score' => 50, 'feedback' => 'FOUR OF A KIND']);
232
                session()->put('count.fourofakind', session('count.fourofakind') + 1);
233
                $this->notScoredYet = false;
234
            }
235
        }
236
    }
237 View Code Duplication
    public function fullHouse($type): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
238
    {
239
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
240
            // FULL HOUSE
241
            if (in_array(3, $this->occurrencesValues) && in_array(2, $this->occurrencesValues)) {
242
                session()->put('score' . $type, ['score' => 25, 'feedback' => 'FULL HOUSE']);
243
                session()->put('count.fullhouse', session('count.fullhouse') + 1);
244
                $this->notScoredYet = false;
245
            }
246
        }
247
    }
248
249 View Code Duplication
    public function threeOfAKind($type): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
250
    {
251
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
252
            // 3 OF A KIND
253
            if (in_array(3, $this->occurrencesValues) && in_array(1, $this->occurrencesValues)) {
254
                session()->put('score' . $type, ['score' => 10, 'feedback' => 'THREE OF A KIND']);
255
                session()->put('count.threeofakind', session('count.threeofakind') + 1);
256
                $this->notScoredYet = false;
257
            }
258
        }
259
    }
260
261
    public function twoPairsOrPair($type): void
262
    {
263
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
264
            // 2 PAIRS OR 1 PAIR
265
            if (in_array(2, $this->occurrencesValues) && in_array(1, $this->occurrencesValues)) {
266
                // 2 PAIRS
267
                if (array_count_values($this->occurrencesValues)[2] == 4) {
268
                    session()->put('score' . $type, ['score' => 5, 'feedback' => 'TWO PAIRS']);
269
                    session()->put('count.twopairs', session('count.twopairs') + 1);
270
                    $this->notScoredYet = false;
271
                }
272
            }
273
        }
274
275
        // PAIR
276
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
277
            // 2 PAIRS OR 1 PAIR
278
            if (in_array(2, $this->occurrencesValues) && in_array(1, $this->occurrencesValues)) {
279
                // 1 PAIR
280
                if (array_count_values($this->occurrencesValues)[2] == 2) {
281
                    session()->put('score' . $type, ['score' => 2, 'feedback' => 'PAIR']);
282
                    session()->put('count.pair', session('count.pair') + 1);
283
                    $this->notScoredYet = false;
284
                }
285
            }
286
        }
287
    }
288
289
    public function straightOrNothing($type): void
290
    {
291
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
292
            // CHECK FOR STRAIGHT
293
            if ($this->consecutiveArray == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
294
                session()->put('score' . $type, ['score' => 15, 'feedback' => 'STRAIGHT']);
295
                session()->put('count.straight', session('count.straight') + 1);
296
                $this->notScoredYet = false;
297
            }
298
        }
299
300
        if ($this->notScoredYet == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
301
            // NO POINTS
302
            session()->put('score' . $type, ['score' => 0, 'feedback' => 'NOTHING']);
303
            session()->put('count.nothing', session('count.nothing') + 1);
304
            $this->notScoredYet = false;
305
        }
306
    }
307
308
    public function setNotScoredYetBackToFalse(): void
309
    {
310
        $this->notScoredYet = true;
311
    }
312
}
313