3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare (strict_types=1); final class Position { private $row; private $column; public function __construct(int $row, int $column) { $this->row = $row; $this->column = $column; } public function is(Position $position) : bool { return $this->row === $position->row && $this->column === $position->column; } } final class Tile { private $position; private $clicked; public function __construct(Position $position) { $this->position = $position; $this->clicked = false; } public static function clicked(Position $position) : self { $tile = new self($position); $tile->clicked = true; return $tile; } public function position() : Position { return $this->position; } public function click() : self { if ($this->isClicked()) { throw new \RuntimeException('Tile can\'t be clicked twice'); } var_dump(self::clicked($this->position)); return self::clicked($this->position); } public function isClicked() : bool { return $this->clicked; } } final class Tiles { /** * @var Tile[] */ private $tiles; public function __construct(Tile ...$tiles) { $this->tiles = $tiles; } public function count() : int { return \count($this->tiles); } public function hasMoreThan(Position $position, int $expectedLimit) : bool { return $this->find( function(Tile $tile) use ($position) { return $tile->position()->is($position); } )->count() > $expectedLimit; } public function each(callable $callback) : void { array_map($callback, $this->tiles); } public function find(callable $callback) : Tiles { return new Tiles(...array_filter( $this->tiles, $callback )); } public function map(callable $callback) : array { return array_map($callback, $this->tiles); } public function has(Position $position) : bool { return (bool) $this->find( function(Tile $tile) use ($position) { return $tile->position()->is($position); } )->count(); } public function clickedCount() : int { return (int) array_reduce( $this->tiles, function(int $clicked, Tile $nextTile) { return $nextTile->isClicked() ? $clicked + 1 : $clicked; }, 0 ); } } final class Board { /** * @var Tiles */ private $tiles; public function __construct(Tiles $tiles) { $tiles->each(function(Tile $tile) use ($tiles) { if ($tiles->hasMoreThan($tile->position(), 1)) { throw new \RuntimeException('Board can have only tile at each position'); } }); $this->tiles = $tiles; } public function click(Position $position) : void { if (!$this->tiles->has($position)) { throw new \RuntimeException('Tile does not exists'); } $this->tiles = new Tiles(...$this->tiles->map(function(Tile $tile) use ($position) { return $tile->position()->is($position) ? $tile->click() : $tile; })); } public function score() : int { return $this->tiles->clickedCount(); } } $board = new Board(new Tiles( new Tile(new Position(0, 0)), new Tile(new Position(0, 1)), new Tile(new Position(0, 2)), new Tile(new Position(0, 3)), new Tile(new Position(0, 4)), new Tile(new Position(0, 5)) )); $board->click(new Position(0, 0)); $board->click(new Position(0, 1)); $board->click(new Position(0, 2)); $board->click(new Position(0, 3)); $board->click(new Position(0, 4)); $board->click(new Position(0, 5)); print "\n"; Board::clicked(new Position(0, 0)); var_dump($board->score());
Output for 7.1.0 - 7.1.33, 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
object(Tile)#18 (2) { ["position":"Tile":private]=> object(Position)#4 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(0) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#16 (2) { ["position":"Tile":private]=> object(Position)#6 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(1) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#2 (2) { ["position":"Tile":private]=> object(Position)#8 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(2) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#17 (2) { ["position":"Tile":private]=> object(Position)#10 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(3) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#3 (2) { ["position":"Tile":private]=> object(Position)#12 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(4) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#5 (2) { ["position":"Tile":private]=> object(Position)#14 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(5) } ["clicked":"Tile":private]=> bool(true) } Fatal error: Uncaught Error: Call to undefined method Board::clicked() in /in/iY5Qu:182 Stack trace: #0 {main} thrown in /in/iY5Qu on line 182
Process exited with code 255.
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 object(Tile)#18 (2) { ["position":"Tile":private]=> object(Position)#4 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(0) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#16 (2) { ["position":"Tile":private]=> object(Position)#6 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(1) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#2 (2) { ["position":"Tile":private]=> object(Position)#8 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(2) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#17 (2) { ["position":"Tile":private]=> object(Position)#10 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(3) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#3 (2) { ["position":"Tile":private]=> object(Position)#12 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(4) } ["clicked":"Tile":private]=> bool(true) } object(Tile)#5 (2) { ["position":"Tile":private]=> object(Position)#14 (2) { ["row":"Position":private]=> int(0) ["column":"Position":private]=> int(5) } ["clicked":"Tile":private]=> bool(true) } Fatal error: Uncaught Error: Call to undefined method Board::clicked() in /in/iY5Qu:182 Stack trace: #0 {main} thrown in /in/iY5Qu on line 182
Process exited with code 255.
Output for 7.0.0 - 7.0.33
Fatal error: Uncaught TypeError: Return value of Tiles::each() must be an instance of void, none returned in /in/iY5Qu:91 Stack trace: #0 /in/iY5Qu(140): Tiles->each(Object(Closure)) #1 /in/iY5Qu(170): Board->__construct(Object(Tiles)) #2 {main} thrown in /in/iY5Qu on line 91
Process exited with code 255.
Output for 5.6.0 - 5.6.40
Warning: Unsupported declare 'strict_types' in /in/iY5Qu on line 3 Parse error: syntax error, unexpected ':', expecting ';' or '{' in /in/iY5Qu on line 16
Process exited with code 255.

preferences:
231.44 ms | 401 KiB | 287 Q