-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.php
130 lines (120 loc) · 4.01 KB
/
index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
use App\Functions\Builder\CommandBuilder;
use App\Functions\Builder\MarsBuilder;
use App\Functions\Builder\PositionBuilder;
use App\Functions\Builder\RoverBuilder;
use App\Functions\Checker\Checker;
use App\Functions\GamePlay;
use App\Models\Game;
use App\Models\Mars;
use App\Models\Result;
use App\Models\Rover;
use FunctionalPHP\FantasyLand\Functor;
use Widmogrod\Monad\Either;
use function Widmogrod\Functional\bind;
use function Widmogrod\Functional\map;
use function Widmogrod\Functional\pipeline;
use function Widmogrod\Functional\valueOf;
use function Widmogrod\Monad\IO\putStrLn;
require_once 'vendor/autoload.php';
$settings = GamePlay::initGame();
/** @var Either\Either $pipelineResult */
$pipelineResult = pipeline(
static function (array $obstacles): Either\Either {
$obsRight = array_filter(
$obstacles,
static function (Either\Either $obs): bool {
return $obs instanceof Either\Right;
}
);
return count($obsRight) === count($obstacles)
? Either\right(
array_map(
static function (Either\Either $either) {
return valueOf($either);
},
$obsRight
)
)
: Either\left(new RuntimeException('fail parse obstacles'));
},
bind(
static function (array $obstacles) use ($settings): Either\Either {
return MarsBuilder::build(
$settings['width'],
$settings['height'],
$obstacles
);
}
),
bind(
static function (Mars $mars) use ($settings) : Functor {
return RoverBuilder::build(
$settings['x'],
$settings['y'],
$settings['startingDirection']
)->map(
static function (Rover $rover) use ($mars): Game {
return new Game($mars, $rover, null);
});
}
),
bind(
static function (Game $game) use ($settings): Functor {
return Either\right(array_map(
static function (string $in): Either\Either {
return CommandBuilder::build($in);
},
$settings['commands']
))->map(
static function (array $commands) use ($game) {
return new Game($game->getMars(), $game->getRover(), $commands);
}
);
}
),
bind(
static function (Game $game) use ($settings): Functor {
$commandRight = array_filter(
$game->getCommands(),
static function (Either\Either $obstacle): bool {
return $obstacle instanceof Either\Right;
}
);
return count($commandRight) === count($settings['commands'])
? Either\right(
array_map(
static function (Either\Either $command) {
return valueOf($command);
},
$game->getCommands()
)
)->map(
static function ($commands) use ($game) {
return new Game($game->getMars(), $game->getRover(), $commands);
}
)
: Either\left(new RuntimeException('Command input error.'));
}
),
map(
static function (Game $game): Result {
return GamePlay::exec($game);
}
)
)(
array_map(
static function (array $inputData): Either\Either {
return PositionBuilder::build($inputData['x'], $inputData['y']);
},
$settings['obstacles']
)
);
putStrLn($pipelineResult->either(
static function (RuntimeException $exception): string {
return $exception->getMessage();
},
static function (Result $result): string {
return GamePlay::serializeResult($result);
}
))->run();