Passed
Push — master ( e9d049...9c1611 )
by Burak
02:00
created

class.sudoxu.php (23 issues)

1
<?php
2
3
class sudoxu
4
{
5
6
    public  $sudoku,
7
            $result,
8
            $number;
9
    private $limit,
10
            $sq,
11
            $chars,
12
            $stack = array('1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
13
14
    public function __construct()
15
    {
16
        ini_set('memory_limit', -1);
17
        set_time_limit(0);
18
19
        ini_set('display_errors',1);
20
        error_reporting(E_ALL);
21
22
        $this->number = 0;
23
        $this->limit  = 16;
24
        $this->sq     = (int)sqrt($this->limit);
25
26
        self::logic();
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::logic() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

26
        /** @scrutinizer ignore-call */ self::logic();
Loading history...
27
28
        return $this;
29
30
    }
31
32
    public function logic()
33
    {
34
        if(count($this->stack) < $this->limit)
35
        {
36
            echo 'error';
37
            exit;
38
        }
39
    }
40
41
    static function printr($write)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
42
    {
43
        echo "<pre>";
44
        print_r($write);
45
        echo "</pre>";
46
47
    }
48
49
    public function set($number)
50
    {
51
        $this->limit = $number;
52
        $this->sq = (int)sqrt($this->limit);
53
54
        return $this;
55
56
    }
57
58
    private function return_row($cell)
59
    {
60
        return floor($cell / $this->limit);
61
62
    }
63
64
    private function return_col($cell)
65
    {
66
        return $cell % $this->limit;
67
68
    }
69
70
    private function return_block($cell)
71
    {
72
        return floor(self::return_row($cell) / $this->sq) * $this->sq + floor(self::return_col($cell) / $this->sq);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::return_col() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

72
        return floor(self::return_row($cell) / $this->sq) * $this->sq + floor(/** @scrutinizer ignore-call */ self::return_col($cell) / $this->sq);
Loading history...
Bug Best Practice introduced by
The method sudoxu::return_row() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

72
        return floor(/** @scrutinizer ignore-call */ self::return_row($cell) / $this->sq) * $this->sq + floor(self::return_col($cell) / $this->sq);
Loading history...
73
74
    }
75
76 View Code Duplication
    private function is_possible_row($number, $row)
77
    {
78
        $possible = true;
79
        for ($x = 0; $x < $this->limit; $x++)
80
        {
81
            if (isset($this->sudoku[$row * $this->limit + $x]) && $this->sudoku[$row * $this->limit + $x] == $number)
82
            {
83
                $possible = false;
84
            }
85
        }
86
87
        return $possible;
88
    }
89
90 View Code Duplication
    private function is_possible_col($number, $col)
91
    {
92
        $possible = true;
93
        for ($x = 0; $x < $this->limit; $x++)
94
        {
95
            if (isset($this->sudoku[$col + $this->limit * $x]) && $this->sudoku[$col + $this->limit * $x] == $number)
96
            {
97
                $possible = false;
98
            }
99
        }
100
101
        return $possible;
102
    }
103
104
    private function is_possible_block($number, $block)
105
    {
106
        $possible = true;
107
        for ($x = 0; $x < $this->limit; $x++)
108
        {
109
            $index = floor($block / $this->sq) * $this->sq * $this->limit + $x % $this->sq + $this->limit * floor($x / $this->sq) + $this->sq * ($block % $this->sq);
110
            if (isset($this->sudoku[$index]) && $this->sudoku[$index] == $number)
111
            {
112
                $possible = false;
113
            }
114
        }
115
116
        return $possible;
117
    }
118
119
    private function is_possible_number($cell, $number)
120
    {
121
        $row   = self::return_row($cell);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::return_row() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

121
        $row   = /** @scrutinizer ignore-call */ self::return_row($cell);
Loading history...
122
        $col   = self::return_col($cell);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::return_col() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

122
        $col   = /** @scrutinizer ignore-call */ self::return_col($cell);
Loading history...
123
        $block = self::return_block($cell);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::return_block() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

123
        $block = /** @scrutinizer ignore-call */ self::return_block($cell);
Loading history...
124
125
        return (self::is_possible_row($number, $row) && self::is_possible_col($number, $col) && self::is_possible_block($number, $block));
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::is_possible_col() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
        return (self::is_possible_row($number, $row) && /** @scrutinizer ignore-call */ self::is_possible_col($number, $col) && self::is_possible_block($number, $block));
Loading history...
Bug Best Practice introduced by
The method sudoxu::is_possible_row() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
        return (/** @scrutinizer ignore-call */ self::is_possible_row($number, $row) && self::is_possible_col($number, $col) && self::is_possible_block($number, $block));
Loading history...
Bug Best Practice introduced by
The method sudoxu::is_possible_block() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
        return (self::is_possible_row($number, $row) && self::is_possible_col($number, $col) && /** @scrutinizer ignore-call */ self::is_possible_block($number, $block));
Loading history...
126
    }
127
128
    private function is_correct_row($row)
129
    {
130
        $row_temp = array();
131
        for ($x = 0; $x < $this->limit; $x++)
132
        {
133
            if(!isset($this->sudoku[$row * $this->limit + $x]))
134
            {
135
                $this->sudoku[$row * $this->limit + $x] = null;
136
            }
137
            $row_temp[$x] = $this->sudoku[$row * $this->limit + $x];
138
        }
139
140
        return count(array_diff($this->chars, $row_temp)) == 0;
141
    }
142
143
    private function is_correct_col($col)
144
    {
145
        $col_temp = array();
146
        for ($x = 0; $x < $this->limit; $x++)
147
        {
148
            $col_temp[$x] = $this->sudoku[$col + $x * $this->limit];
149
        }
150
        return count(array_diff($this->chars, $col_temp)) == 0;
151
    }
152
153
    private function is_correct_block($block)
154
    {
155
        $block_temp = array();
156
        for ($x = 0; $x < $this->limit; $x++)
157
        {
158
            $lookingfor = floor($block / $this->sq) * ($this->sq * $this->limit) + ($x % $this->sq) + $this->limit * floor($x / $this->sq) + $this->sq * ($block % $this->sq);
159
160
            if (!isset($this->sudoku[$lookingfor]))
161
            {
162
                $this->sudoku[$lookingfor] = null;
163
            }
164
165
            $block_temp[$x] = $this->sudoku[$lookingfor];
166
        }
167
        return count(array_diff($this->chars, $block_temp)) == 0;
168
    }
169
170
    private function is_solved_sudoku()
171
    {
172
        for ($x = 0; $x < $this->limit; $x++)
173
        {
174
            if (!self::is_correct_block($x) or !self::is_correct_row($x) or !self::is_correct_col($x))
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::is_correct_row() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

174
            if (!self::is_correct_block($x) or !/** @scrutinizer ignore-call */ self::is_correct_row($x) or !self::is_correct_col($x))
Loading history...
Bug Best Practice introduced by
The method sudoxu::is_correct_block() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

174
            if (!/** @scrutinizer ignore-call */ self::is_correct_block($x) or !self::is_correct_row($x) or !self::is_correct_col($x))
Loading history...
Bug Best Practice introduced by
The method sudoxu::is_correct_col() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

174
            if (!self::is_correct_block($x) or !self::is_correct_row($x) or !/** @scrutinizer ignore-call */ self::is_correct_col($x))
Loading history...
175
            {
176
                return false;
177
                break;
178
            }
179
        }
180
        return true;
181
    }
182
183
    private function determine_possible_values($cell)
184
    {
185
        $possible = array();
186
        for ($x = 0; $x < $this->limit; $x++)
187
        {
188
            if (self::is_possible_number($cell, $this->chars[$x]))
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::is_possible_number() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

188
            if (/** @scrutinizer ignore-call */ self::is_possible_number($cell, $this->chars[$x]))
Loading history...
189
            {
190
                array_unshift($possible, $this->chars[$x]);
191
            }
192
        }
193
194
        return $possible;
195
    }
196
197
    private function determine_random_possible_value($possible, $cell)
198
    {
199
        return $possible[$cell][rand(0, count($possible[$cell]) - 1)];
200
    }
201
202
    private function scan_sudoku_for_unique()
203
    {
204
        $possible = false;
205
        for ($x = 0; $x < $this->limit * $this->limit; $x++)
206
        {
207
            if (!isset($this->sudoku[$x]))
208
            {
209
                $possible[$x] = self::determine_possible_values($x, $this->sudoku);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::determine_possible_values() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

209
                $possible[$x] = /** @scrutinizer ignore-call */ self::determine_possible_values($x, $this->sudoku);
Loading history...
210
                if (count($possible[$x]) == 0)
211
                {
212
                    return (false);
213
                    break;
214
                }
215
            }
216
        }
217
218
        return $possible;
219
    }
220
221
    private function remove_attempt($attempt_array, $number)
222
    {
223
        $new_array = array();
224
        for ($x = 0; $x < count($attempt_array); $x++)
225
        {
226
            if ($attempt_array[$x] != $number)
227
            {
228
                array_unshift($new_array, $attempt_array[$x]);
229
            }
230
        }
231
        return $new_array;
232
    }
233
234
235
    private function next_random($possible)
236
    {
237
        $max = $this->limit;
238
        for ($x = 0; $x < $this->limit * $this->limit; $x++)
239
        {
240
            if (!isset($possible[$x]))
241
            {
242
                $possible[$x] = null;
243
            }
244
245
            if ((count($possible[$x]) <= $max) && (count($possible[$x]) > 0))
246
            {
247
                $max         = count($possible[$x]);
248
                $min_choices = $x;
249
            }
250
        }
251
        return $min_choices;
252
    }
253
254
255
    private function build()
256
    {
257
        $this->sudoku = array();
258
        $this->chars  = array();
259
260
        for ($i = 0; $i < $this->limit; $i++)
261
        {
262
            $this->chars[] = $this->stack[$i];
263
        }
264
    }
265
266
    public function microtime()
267
    {
268
        return microtime(true);
269
    }
270
271
    public function generate()
272
    {
273
        $start     = self::microtime();
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::microtime() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

273
        $start     = /** @scrutinizer ignore-call */ self::microtime();
Loading history...
274
        self::build();
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::build() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

274
        /** @scrutinizer ignore-call */ self::build();
Loading history...
275
276
        $x         = 0;
277
        $saved     = array();
278
        $saved_sud = array();
279
        while (!self::is_solved_sudoku())
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::is_solved_sudoku() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

279
        while (!/** @scrutinizer ignore-call */ self::is_solved_sudoku())
Loading history...
280
        {
281
            $x++;
282
            $next_move = self::scan_sudoku_for_unique();
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::scan_sudoku_for_unique() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

282
            $next_move = /** @scrutinizer ignore-call */ self::scan_sudoku_for_unique();
Loading history...
283
284
            if ($next_move == false)
285
            {
286
                $next_move    = array_pop($saved);
287
                $this->sudoku = array_pop($saved_sud);
288
            }
289
290
            $what_to_try = self::next_random($next_move);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::next_random() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

290
            $what_to_try = /** @scrutinizer ignore-call */ self::next_random($next_move);
Loading history...
291
            $attempt     = self::determine_random_possible_value($next_move, $what_to_try);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::determine_random_possible_value() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

291
            $attempt     = /** @scrutinizer ignore-call */ self::determine_random_possible_value($next_move, $what_to_try);
Loading history...
292
293
294
            if (count($next_move[$what_to_try]) > 1)
295
            {
296
                $next_move[$what_to_try] = self::remove_attempt($next_move[$what_to_try], $attempt);
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::remove_attempt() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

296
                $next_move[$what_to_try] = /** @scrutinizer ignore-call */ self::remove_attempt($next_move[$what_to_try], $attempt);
Loading history...
297
                array_push($saved, $next_move);
298
                array_push($saved_sud, $this->sudoku);
299
            }
300
            $this->sudoku[$what_to_try] = $attempt;
301
        }
302
303
        $timing       = self::microtime() - $start;
304
        $this->result = array(
305
            'created_in' => round($timing,2),
306
            'difficulty' => 'N/A'
307
        );
308
309
        self::draw();
0 ignored issues
show
Bug Best Practice introduced by
The method sudoxu::draw() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

309
        /** @scrutinizer ignore-call */ self::draw();
Loading history...
310
    }
311
312
313
    public function draw()
314
    {
315
316
317
        echo "<table cellpadding='0' cellspacing='0' style='margin:0 auto;font:30px Arial;border:3px solid black'>";
318
319
        for ($u = 0; $u < $this->limit; $u++)
320
        {
321
322
323
            if (($u + 1) % $this->sq == '0')
324
            {
325
                $border = 3;
326
            } else {
327
                $border = 1;
328
            }
329
330
            echo '<tr>';
331
332
            for ($v = 0; $v < $this->limit; $v++)
333
            {
334
335
336
                if (($v + 1) % $this->sq == '0')
337
                {
338
                    $border2 = 3;
339
                } else {
340
                    $border2 = 1;
341
                }
342
343
                echo '<td
344
                            data-row="'.$u.'"
345
                            data-col="'.$v.'"
346
                            style="border: 1px solid black;border-bottom:' . $border . 'px solid black;border-right:' . $border2 . 'px solid black;line-height: 50px; width: 50px; text-align: center; vertical-align: middle;">';
347
                echo($this->sudoku[$v * $this->limit + $u]);
348
                echo '</td>';
349
350
            }
351
352
            echo '</tr>';
353
354
        }
355
356
        echo "</table>";
357
358
        echo $this->result['created_in'].' seconds';
359
360
    }
361
362
}