Completed
Push — master ( e50614...7a6f43 )
by Midori
01:37
created

Organisms::checkCell()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 12
nc 7
nop 2
dl 0
loc 20
ccs 12
cts 12
cp 1
crap 7
rs 8.2222
c 0
b 0
f 0
1
<?php
2
3
namespace MidoriKocak\GameOfLife;
4
5
/**
6
 * Class Organisms
7
 *
8
 * @package MidoriKocak\GameOfLife
9
 */
10
class Organisms
11
{
12
    /**
13
     * Multidimensional array of organisms
14
     *
15
     * @var int[][]
16
     */
17
    private $cells;
18
19
    /**
20
     * Organisms constructor.
21
     * @param int[][] $cells
22
     */
23 9
    public function __construct(array $cells)
24
    {
25 9
        $this->cells = $cells;
26 9
    }
27
28
    /**
29
     * Runs the game.
30
     * Checks each cell for the next iteration.
31
     */
32 4
    public function iterate()
33
    {
34 4
        $next = $this->cells;
35 4
        $rows = sizeof($this->cells);
36 4
        $columns = sizeof($this->cells[0]);
37 4
        for ($i = 0; $i < $rows; $i++) {
38 4
            for ($j = 0; $j < $columns; $j++) {
39 4
                $next[$i][$j] = $this->checkCell($i, $j);
40
            }
41
        }
42
43 4
        $this->cells = $next;
44 4
    }
45
46
    /**
47
     * Returns the array of cells
48
     *
49
     * @return array|\int[][]
50
     */
51 3
    public function getCells()
52
    {
53 3
        return $this->cells;
54
    }
55
56
    /**
57
     * Helper function to get neighbor count of matrix element
58
     *
59
     * @param $i
60
     * @param $j
61
     * @return array
62
     */
63 4
    private function getNeighborCount($i, $j)
64
    {
65 4
        $neighbors = [];
66 4
        $neighbors[$this->cells[$i][$j]] = 0;
67 4
        $indexes = self::getNeighborIndexes($this->cells, $i, $j);
68 4
        foreach ($indexes as $coordinate) {
69 4
            $y = $coordinate[0];
70 4
            $x = $coordinate[1];
71 4
            $type = $this->cells[$y][$x];
72
73 4
            if ($this->cells[$y][$x] > 0) {
74 4
                $neighbors[$type] = $neighbors[$type] ?? 0;
75 4
                $neighbors[$type]++;
76
            }
77
        }
78 4
        return $neighbors;
79
    }
80
81
    /**
82
     * Check the matrix cell if it will survive, die or reproduce.
83
     *
84
     * @param $i
85
     * @param $j
86
     * @return int|mixed
87
     */
88 4
    private function checkCell($i, $j)
89
    {
90 4
        $neighbors = $this->getNeighborCount($i, $j);
91 4
        if ($this->cells[$i][$j] > 0 &&
92 4
            ($neighbors[$this->cells[$i][$j]] == 2 || $neighbors[$this->cells[$i][$j]] == 3)
93
        ) {
94 4
            return $this->cells[$i][$j];
95
        } else {
96 4
            $speciesEqualToTree = [];
97 4
            foreach ($neighbors as $type => $count) {
98 4
                if ($count == 3) {
99 4
                    array_push($speciesEqualToTree, $type);
100
                }
101
            }
102
103 4
            if (!empty($speciesEqualToTree)) {
104 4
                return $speciesEqualToTree[rand(0, sizeof($speciesEqualToTree) - 1)];
105
            }
106
        }
107 4
        return 0;
108
    }
109
110
    /**
111
     * Helper method that returns indexes of neighbors of a Matrix element.
112
     *
113
     * @param $matrix
114
     * @param $i
115
     * @param $j
116
     * @return array
117
     */
118 4
    private static function getNeighborIndexes($matrix, $i, $j)
119
    {
120
121 4
        $indexes = [];
122
123 4
        if ($i > 0 && $j > 0) array_push($indexes, [$i - 1, $j - 1]);
124 4
        if ($i > 0) array_push($indexes, [$i - 1, $j]);
125 4
        if ($i > 0 && $j < sizeof($matrix[0]) - 1) array_push($indexes, [$i - 1, $j + 1]);
126 4
        if ($j > 0) array_push($indexes, [$i, $j - 1]);
127 4
        if ($j < sizeof($matrix[0]) - 1) array_push($indexes, [$i, $j + 1]);
128 4
        if ($i < sizeof($matrix) - 1 && $j > 0) array_push($indexes, [$i + 1, $j - 1]);
129 4
        if ($i < sizeof($matrix) - 1) array_push($indexes, [$i + 1, $j]);
130 4
        if ($i < sizeof($matrix) - 1 && $j < sizeof($matrix[0]) - 1) array_push($indexes, [$i + 1, $j + 1]);
131
132 4
        return $indexes;
133
    }
134
135
}