1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Barryvanveen\CCA; |
6
|
|
|
|
7
|
|
|
use Barryvanveen\CCA\Config\NeighborhoodOptions; |
8
|
|
|
use Barryvanveen\CCA\Config\Options; |
9
|
|
|
use Barryvanveen\CCA\Config\Presets; |
10
|
|
|
use Barryvanveen\CCA\Exceptions\InvalidHueException; |
11
|
|
|
use Barryvanveen\CCA\Exceptions\InvalidNeighborhoodTypeException; |
12
|
|
|
|
13
|
|
|
class Config |
14
|
|
|
{ |
15
|
|
|
protected $config = [ |
16
|
|
|
Options::COLUMNS => 48, |
17
|
|
|
Options::IMAGE_CELL_SIZE => 2, |
18
|
|
|
Options::IMAGE_HUE => null, |
19
|
|
|
Options::NEIGHBORHOOD_TYPE => NeighborhoodOptions::NEIGHBORHOOD_TYPE_MOORE, |
20
|
|
|
Options::NEIGHBORHOOD_SIZE => 1, |
21
|
|
|
Options::ROWS => 48, |
22
|
|
|
Options::SEED => null, |
23
|
|
|
Options::STATES => 3, |
24
|
|
|
Options::THRESHOLD => 3, |
25
|
|
|
]; |
26
|
|
|
|
27
|
3 |
|
public function __construct() |
28
|
|
|
{ |
29
|
3 |
|
$this->config[Options::IMAGE_HUE] = $this->makeHue(); |
30
|
|
|
|
31
|
3 |
|
$this->config[Options::SEED] = $this->makeSeed(); |
32
|
3 |
|
} |
33
|
|
|
|
34
|
|
|
protected function makeHue(): int |
35
|
|
|
{ |
36
|
|
|
return rand(0, 360); |
37
|
|
|
} |
38
|
|
|
|
39
|
3 |
|
protected function makeSeed(): int |
40
|
|
|
{ |
41
|
3 |
|
list($usec, $sec) = explode(' ', microtime()); |
42
|
|
|
|
43
|
3 |
|
return intval($sec + $usec * 1000000); |
44
|
|
|
} |
45
|
|
|
|
46
|
3 |
|
public static function createFromPreset(string $preset): self |
47
|
|
|
{ |
48
|
3 |
|
$presetConfig = Presets::getPresetConfig($preset); |
49
|
|
|
|
50
|
3 |
|
$config = new self(); |
51
|
|
|
|
52
|
3 |
|
foreach ($presetConfig as $option => $value) { |
53
|
3 |
|
$config->{$option}($value); |
54
|
|
|
} |
55
|
|
|
|
56
|
3 |
|
return $config; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* The amount of columns in the grid. |
61
|
|
|
* |
62
|
|
|
* @param int number of columns |
63
|
|
|
* |
64
|
|
|
* @return int |
65
|
|
|
*/ |
66
|
3 |
|
public function columns($columns = null): int |
67
|
|
|
{ |
68
|
3 |
|
if (isset($columns)) { |
69
|
3 |
|
$this->config[Options::COLUMNS] = (int) $columns; |
70
|
|
|
} |
71
|
|
|
|
72
|
3 |
|
return $this->config[Options::COLUMNS]; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Set the size of each cell in the image that is created. |
77
|
|
|
* |
78
|
|
|
* @param int $cellsize |
79
|
|
|
* |
80
|
|
|
* @return int |
81
|
|
|
*/ |
82
|
3 |
|
public function imageCellSize($cellsize = null): int |
83
|
|
|
{ |
84
|
3 |
|
if (isset($cellsize)) { |
85
|
3 |
|
$this->config[Options::IMAGE_CELL_SIZE] = (int) $cellsize; |
86
|
|
|
} |
87
|
|
|
|
88
|
3 |
|
return $this->config[Options::IMAGE_CELL_SIZE]; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
public function imageHue($hue = null): int |
92
|
|
|
{ |
93
|
|
|
if (isset($hue) && $this->isValidHue($hue)) { |
94
|
|
|
$this->config[Options::IMAGE_HUE] = (int) $hue; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
return $this->config[Options::IMAGE_HUE]; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
protected function isValidHue($hue): bool |
101
|
|
|
{ |
102
|
|
|
if (!is_int($hue)) { |
103
|
|
|
throw new InvalidHueException("Hue is not an integer."); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if ($hue < 0 || $hue > 360) { |
107
|
|
|
throw new InvalidHueException("Hue should be an integer between 0 and 360."); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
return true; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Set the size (eg range) of the neighborhood. |
115
|
|
|
* |
116
|
|
|
* @param int $neighborhoodSize size of neighborhood |
117
|
|
|
* |
118
|
|
|
* @return int |
119
|
|
|
*/ |
120
|
3 |
|
public function neighborhoodSize($neighborhoodSize = null): int |
121
|
|
|
{ |
122
|
3 |
|
if (isset($neighborhoodSize)) { |
123
|
3 |
|
$this->config[Options::NEIGHBORHOOD_SIZE] = (int) $neighborhoodSize; |
124
|
|
|
} |
125
|
|
|
|
126
|
3 |
|
return $this->config[Options::NEIGHBORHOOD_SIZE]; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Set the neighborhood function, eg Moore or Neumann |
131
|
|
|
* |
132
|
|
|
* @see NeighborhoodOptions::NEIGHBORHOOD_TYPE_MOORE |
133
|
|
|
* @see NeighborhoodOptions::NEIGHBORHOOD_TYPE_NEUMANN |
134
|
|
|
* |
135
|
|
|
* @param string $neighborhoodType |
136
|
|
|
* |
137
|
|
|
* @return string type of neighborhood |
138
|
|
|
* |
139
|
|
|
* @throws \Barryvanveen\CCA\Exceptions\InvalidNeighborhoodTypeException |
140
|
|
|
*/ |
141
|
6 |
|
public function neighborhoodType($neighborhoodType = null): string |
142
|
|
|
{ |
143
|
6 |
|
if (isset($neighborhoodType)) { |
144
|
6 |
|
if (!in_array($neighborhoodType, NeighborhoodOptions::NEIGHBORHOOD_TYPES)) { |
145
|
3 |
|
throw new InvalidNeighborhoodTypeException(); |
146
|
|
|
} |
147
|
|
|
|
148
|
3 |
|
$this->config[Options::NEIGHBORHOOD_TYPE] = (string) $neighborhoodType; |
149
|
|
|
} |
150
|
|
|
|
151
|
3 |
|
return $this->config[Options::NEIGHBORHOOD_TYPE]; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* The amount of rows in the grid. |
156
|
|
|
* |
157
|
|
|
* @param int number of rows |
158
|
|
|
* |
159
|
|
|
* @return int |
160
|
|
|
*/ |
161
|
3 |
View Code Duplication |
public function rows($rows = null): int |
|
|
|
|
162
|
|
|
{ |
163
|
3 |
|
if (isset($rows)) { |
164
|
3 |
|
$this->config[Options::ROWS] = (int) $rows; |
165
|
|
|
} |
166
|
|
|
|
167
|
3 |
|
return $this->config[Options::ROWS]; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Set a seed for the random number generator. Use this for reproducable of runs. |
172
|
|
|
* |
173
|
|
|
* @param int $seed |
174
|
|
|
* |
175
|
|
|
* @return int |
176
|
|
|
*/ |
177
|
3 |
View Code Duplication |
public function seed($seed = null): int |
|
|
|
|
178
|
|
|
{ |
179
|
3 |
|
if (isset($seed)) { |
180
|
3 |
|
$this->config[Options::SEED] = (int) $seed; |
181
|
|
|
} |
182
|
|
|
|
183
|
3 |
|
return $this->config[Options::SEED]; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* The number of states that each cell cycles through. |
188
|
|
|
* |
189
|
|
|
* @param int number of states |
190
|
|
|
* |
191
|
|
|
* @return int |
192
|
|
|
*/ |
193
|
3 |
|
public function states($states = null): int |
194
|
|
|
{ |
195
|
3 |
|
if (isset($states)) { |
196
|
3 |
|
$this->config[Options::STATES] = (int) $states; |
197
|
|
|
} |
198
|
|
|
|
199
|
3 |
|
return $this->config[Options::STATES]; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* The threshold of the cells. Only when <threshold> or more of a cells' neighbors have |
204
|
|
|
* the successor state will the cell cycle to the successor state itself. |
205
|
|
|
* |
206
|
|
|
* @param int threshold |
207
|
|
|
* |
208
|
|
|
* @return int |
209
|
|
|
*/ |
210
|
3 |
View Code Duplication |
public function threshold($threshold = null): int |
|
|
|
|
211
|
|
|
{ |
212
|
3 |
|
if (isset($threshold)) { |
213
|
3 |
|
$this->config[Options::THRESHOLD] = (int) $threshold; |
214
|
|
|
} |
215
|
|
|
|
216
|
3 |
|
return $this->config[Options::THRESHOLD]; |
217
|
|
|
} |
218
|
|
|
|
219
|
3 |
|
public function toArray(): array |
220
|
|
|
{ |
221
|
3 |
|
return $this->config; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
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.