Passed
Push — master ( 7fdb6f...e50614 )
by Midori
01:47
created

Organisms   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Test Coverage

Coverage 98.15%

Importance

Changes 0
Metric Value
dl 0
loc 129
ccs 53
cts 54
cp 0.9815
rs 10
c 0
b 0
f 0
wmc 30

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getNeighborCount() 0 16 3
A iterate() 0 12 3
D checkCell() 0 26 9
A getCells() 0 3 1
C getNeighborIndexes() 0 15 13
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
            if ($neighbors[$this->cells[$i][$j]] == 2 || $neighbors[$this->cells[$i][$j]] == 3) {
93 4
                return $this->cells[$i][$j];
94 4
            } elseif ($neighbors[$this->cells[$i][$j]] < 2) {
95 4
                return 0;
96 4
            } elseif ($neighbors[$this->cells[$i][$j]] >= 4) {
97 4
                return 0;
98
            }
99
        } else {
100 4
            $speciesEqualToTree = [];
101 4
            foreach ($neighbors as $type => $count) {
102 4
                if ($count == 3) {
103 4
                    array_push($speciesEqualToTree, $type);
104
                }
105
            }
106
107 4
            if (!empty($speciesEqualToTree)) {
108 4
                return $speciesEqualToTree[rand(0, sizeof($speciesEqualToTree) - 1)];
109
            } else {
110 4
                return 0;
111
            }
112
        }
113
        return 0;
114
    }
115
116
    /**
117
     * Helper method that returns indexes of neighbors of a Matrix element.
118
     *
119
     * @param $matrix
120
     * @param $i
121
     * @param $j
122
     * @return array
123
     */
124 4
    private static function getNeighborIndexes($matrix, $i, $j)
125
    {
126
127 4
        $indexes = [];
128
129 4
        if ($i > 0 && $j > 0) array_push($indexes, [$i - 1, $j - 1]);
130 4
        if ($i > 0) array_push($indexes, [$i - 1, $j]);
131 4
        if ($i > 0 && $j < sizeof($matrix[0]) - 1) array_push($indexes, [$i - 1, $j + 1]);
132 4
        if ($j > 0) array_push($indexes, [$i, $j - 1]);
133 4
        if ($j < sizeof($matrix[0]) - 1) array_push($indexes, [$i, $j + 1]);
134 4
        if ($i < sizeof($matrix) - 1 && $j > 0) array_push($indexes, [$i + 1, $j - 1]);
135 4
        if ($i < sizeof($matrix) - 1) array_push($indexes, [$i + 1, $j]);
136 4
        if ($i < sizeof($matrix) - 1 && $j < sizeof($matrix[0]) - 1) array_push($indexes, [$i + 1, $j + 1]);
137
138 4
        return $indexes;
139
    }
140
141
}