Ranking::platformPointProvider()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace VideoGamesRecords\CoreBundle\Tools;
6
7
use VideoGamesRecords\CoreBundle\Entity\Player;
8
use VideoGamesRecords\CoreBundle\Entity\PlayerChart;
9
10
class Ranking
11
{
12
    /**
13
     * Order an array
14
     * @param array $array
15
     * @param array $columns array of 'column' => SORT_*
16
     * @return array
17
     */
18
    public static function order(array $array, array $columns): array
19
    {
20
        $arrayMultisortParameters = [];
21
        foreach ($columns as $column => $order) {
22
            $arrayMultisortParameters[] = array_column($array, $column);
23
            $arrayMultisortParameters[] = $order;
24
        }
25
        $arrayMultisortParameters[] = &$array;
26
        array_multisort(...$arrayMultisortParameters);
27
28
        return $array;
29
    }
30
31
    /**
32
     * Add a rank column checking one or more columns to a sorted array
33
     * @param array  $array
34
     * @param string $key
35
     * @param array  $columns
36
     * @param bool   $boolEqual
37
     * @return array
38
     */
39
    public static function addRank(
40
        array $array,
41
        string $key = 'rank',
42
        array $columns = ['pointChart'],
43
        bool $boolEqual = false
44
    ): array {
45
        $rank = 1;
46
        $compteur = 0;
47
        $nbEqual = 1;
48
        $nb = count($array);
49
50
        for ($i = 0; $i <= $nb - 1; $i++) {
51
            if ($i >= 1) {
52
                $row1 = $array[$i - 1];
53
                $row2 = $array[$i];
54
                $isEqual = true;
55
                foreach ($columns as $column) {
56
                    if ($row1[$column] != $row2[$column]) {
57
                        $isEqual = false;
58
                        break;
59
                    }
60
                }
61
                if ($isEqual) {
62
                    $compteur++;
63
                    ++$nbEqual;
64
                } else {
65
                    $rank = $rank + $compteur + 1;
66
                    $compteur = 0;
67
                    unset($nbEqual);
68
                    $nbEqual = 1;
69
                }
70
            }
71
72
            $row = $array[$i];
73
            $row[$key] = $rank;
74
            if ($boolEqual) {
75
                $row['nbEqual'] = &$nbEqual;
76
            }
77
            $array[$i] = $row;
78
        }
79
        unset($nbEqual);
80
81
        return $array;
82
    }
83
84
    /**
85
     * @param array  $array
86
     * @param string $ranking
87
     * @param array  $columns
88
     * @return array
89
     */
90
    public static function addObjectRank(
91
        array $array,
92
        string $ranking = 'rankPointChart',
93
        array $columns = ['pointChart']
94
    ): array {
95
        $setter = 'set' . ucfirst($ranking);
96
        $getters = [];
97
        foreach ($columns as $column) {
98
            $getters[] = 'get' . ucfirst($column);
99
        }
100
101
        $rank = 1;
102
        $compteur = 0;
103
        $nbEqual = 1;
104
        $nb = count($array);
105
106
        for ($i = 0; $i <= $nb - 1; $i++) {
107
            if ($i >= 1) {
108
                $object1 = $array[$i - 1];
109
                $object2 = $array[$i];
110
                $isEqual = true;
111
                foreach ($getters as $getter) {
112
                    if ($object1->$getter() !== $object2->$getter()) {
113
                        $isEqual = false;
114
                        break;
115
                    }
116
                }
117
                if ($isEqual) {
118
                    ++$compteur;
119
                    ++$nbEqual;
120
                } else {
121
                    $rank = $rank + $compteur + 1;
122
                    $compteur = 0;
123
                    $nbEqual = 1;
124
                }
125
            }
126
127
            $object = $array[$i];
128
            $object->$setter($rank);
129
            $array[$i] = $object;
130
        }
131
132
        return $array;
133
    }
134
135
    /**
136
     * Renvoie le tableau des points chart
137
     * @param $iNbPartcipant
138
     * @return array
139
     */
140
    public static function chartPointProvider($iNbPartcipant): array
141
    {
142
        $liste = [];
143
        $pointRecord = 100 * $iNbPartcipant;
144
        $nb = 80; // % différence entre deux positions
145
        $compteur = 0; // compteur de position
146
147
        // 1er
148
        $liste[1] = $pointRecord;
149
150
        for ($i = 2; $i <= $iNbPartcipant; $i++) {
151
            $pointRecord = (int) ($pointRecord * $nb / 100);
152
            $liste[$i] = $pointRecord;
153
            $compteur++;
154
155
            if ($nb < 85) {
156
                if ($compteur === 2) {
157
                    $nb++; // le % augmente donc la différence diminue
158
                    $compteur = 0;
159
                }
160
            } elseif ($nb < 99) {
161
                $nb++;
162
            }
163
        }
164
165
        return $liste;
166
    }
167
168
    /**
169
     * Renvoie le tableau des points platform
170
     * @param $iNbPartcipant
171
     * @return array
172
     */
173
    public static function platformPointProvider($iNbPartcipant): array
174
    {
175
        return self::chartPointProvider($iNbPartcipant);
176
    }
177
178
    /**
179
     * @param array  $aArray
180
     * @param array  $aBaseCol
181
     * @param string $sNameNewCol
182
     * @param string $sColNameToForceZero
183
     * @return array
184
     */
185
    public static function calculateGamePoints(array $aArray, array $aBaseCol, string $sNameNewCol, string $sColNameToForceZero = ''): array
186
    {
187
        if (empty($aArray)) {
188
            return $aArray;
189
        }
190
191
        $nameRankCol = array_shift($aBaseCol);
192
        $nameEqualCol = array_shift($aBaseCol);
193
194
        $nbPlayers = count($aArray);
195
        $nbFirstEquals = 1;
196
        foreach ($aArray as $aRank) {
197
            if ($aRank[$nameRankCol] == 1) {
198
                $nbFirstEquals = $aRank[$nameEqualCol];
199
                break;
200
            }
201
        }
202
203
        //Get formula to first into ranking
204
        $a = (-1 / (100 + $nbPlayers - $nbFirstEquals)) + 0.0101 + (log($nbPlayers) / 15000);
205
        $b = (atan($nbPlayers - 25) + M_PI_2) * (25000 * ($nbPlayers - 25)) / (200 * M_PI);
206
        $f = ceil((10400000 * $a + $b) / ($nbFirstEquals ** (6 / 5)));
207
208
        $aF = [];
209
        $aF[1] = $f;
210
        for ($i = 2; $i <= $nbPlayers; ++$i) {
211
            $g = min(0.99, log($i) / (log(71428.6 * $i + 857142.8)) + 0.7);
212
            $aF[$i] = $aF[$i - 1] * $g;
213
        }
214
215
        for ($i = 0; $i < $nbPlayers; ++$i) {
216
            //If a column name to force the 0 value is defined, force the 0 value of the new column if the related
217
            //column value is 0
218
            if ($sColNameToForceZero !== '' && isset($aArray[$i][$sColNameToForceZero]) && $aArray[$i][$sColNameToForceZero] == 0) {
219
                $aArray[$i][$sNameNewCol] = 0;
220
                continue;
221
            }
222
223
            //If firsts
224
            if ($aArray[$i][$nameRankCol] == 1) {
225
                $aArray[$i][$sNameNewCol] = (int) round($f, 0);
226
                continue;
227
            }
228
            //If non equals
229
            if ($aArray[$i][$nameEqualCol] == 1) {
230
                $aArray[$i][$sNameNewCol] = (int) round($aF[$aArray[$i][$nameRankCol]], 0);
231
                continue;
232
            }
233
            //If equals (do average of players gives if they weren't tied)
234
            $aTiedValues = [];
235
            for ($j = 0; $j < $aArray[$i][$nameEqualCol]; ++$j) {
236
                $aTiedValues[] = $aF[$aArray[$i][$nameRankCol] + $j];
237
            }
238
            $value = round(array_sum($aTiedValues) / count($aTiedValues), 0);
239
            for ($j = $i, $nb = $i + count($aTiedValues); $j < $nb; ++$j) {
240
                $aArray[$i][$sNameNewCol] = (int) $value;
241
                $i++;
242
            }
243
            $i--;
244
        }
245
        return $aArray;
246
    }
247
}
248