Robots Musterlösung: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
(Die Seite wurde neu angelegt: „= Links = * Robots = Zielsetzung = Dies ist eine funktionierende Lösung der Robotersimulaltion. <syntaxhighlight lang="php"> <?php define('BLACK', '*'); define('DEFAULT_COLOR', "\t"); define('WHITE', ' '); →* * Implements a sheet area with ascii sheet.: class Sheet { public array $lines; public int $width; public int $height; public function __construct(int $width = 80, int $height = 40) { $this->width = $width;…“) |
|||
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 11: | Zeile 11: | ||
define('DEFAULT_COLOR', "\t"); | define('DEFAULT_COLOR', "\t"); | ||
define('WHITE', ' '); | define('WHITE', ' '); | ||
class Sheet | class Sheet | ||
Zeile 140: | Zeile 136: | ||
$this->yDirection = -1; | $this->yDirection = -1; | ||
} | } | ||
} | } | ||
public function move(Sheet &$sheet): bool | public function move(Sheet &$sheet): bool | ||
Zeile 150: | Zeile 145: | ||
// $sheet->setRandomPosition($this->target, $sheet); | // $sheet->setRandomPosition($this->target, $sheet); | ||
} else { | } else { | ||
$this->target->draw($sheet); | |||
$x = $this->x; | $x = $this->x; | ||
$y = $this->y; | $y = $this->y; | ||
Zeile 158: | Zeile 154: | ||
$y = $this->target->y < $y ? $y - 1 : $y + 1; | $y = $this->target->y < $y ? $y - 1 : $y + 1; | ||
} | } | ||
$this->checkDirection($sheet); | |||
$this-> | if ($sheet->isOccupied($x, $y)) { | ||
$x = $this->x + $this->xDirection; | |||
$y = $this->y; | |||
if ($sheet->isOccupied($x, $y)) { | if ($sheet->isOccupied($x, $y)) { | ||
$x = $this->x | $x = $this->x; | ||
$y = $this->y + $this->yDirection; | |||
} | } | ||
} | |||
if (!$sheet->isOccupied($x, $y)) { | |||
// Remove current point: | |||
$this->draw($sheet, WHITE); | |||
$this->x = $x; | |||
$this->y = $y; | |||
$this->draw($sheet); | |||
$rc = true; | |||
} | } | ||
} | } | ||
return $rc; | return $rc; | ||
} | } | ||
public function setTarget(Sheet &$sheet){ | public function setTarget(Sheet &$sheet){ | ||
if ($this->target == null){ | if ($this->target == null){ | ||
Zeile 254: | Zeile 246: | ||
$simulator->buildRobots(5); | $simulator->buildRobots(5); | ||
$simulator->show(); | $simulator->show(); | ||
$rounds = 0; | $rounds = 0; | ||
while ($simulator->step()){ | while ($simulator->step()){ | ||
Zeile 261: | Zeile 252: | ||
sleep(1); | sleep(1); | ||
} | } | ||
echo "== ready after $rounds rounds\n"; | echo "== ready after $rounds rounds\n";</syntaxhighlight> | ||
</syntaxhighlight> |
Aktuelle Version vom 3. Dezember 2023, 17:39 Uhr
Links
Zielsetzung
Dies ist eine funktionierende Lösung der Robotersimulaltion.
<?php
define('BLACK', '*');
define('DEFAULT_COLOR', "\t");
define('WHITE', ' ');
class Sheet
{
public array $lines;
public int $width;
public int $height;
public function __construct(int $width = 80, int $height = 40)
{
$this->width = $width;
$this->height = $height;
$this->clearSheet();
}
public function clearTerminal()
{
echo "\x1b\x5b\x48\x1b\x5b\x32\x4a\xc";
}
public function clearSheet()
{
$this->lines = [];
for ($y = 0; $y < $this->height; $y++) {
array_push($this->lines, str_repeat(' ', $this->width));
}
}
public function setRandomPosition(&$point)
{
do {
$x = rand(0, $this->width - 1);
$y = rand(0, $this->height - 1);
} while ($this->isOccupied($x, $y));
$point->x = $x;
$point->y = $y;
}
public function showDrawing()
{
$this->clearTerminal();
echo str_repeat('-', $this->width + 2), "\n";
for ($y = $this->height - 1; $y >= 0; $y--) {
echo '|', $this->lines[$y], "|\n";
}
echo str_repeat('-', $this->width + 2), "\n";
}
public function setPoint(int $x, int $y, string $color = BLACK)
{
if ($x >= 0 && $x < $this->width && $y >= 0 && $y < $this->height) {
$this->lines[$y][$x] = $color;
}
}
public function isOccupied(int $x, int $y): bool
{
$color = $this->lines[$y][$x];
return $color !== WHITE && $color < "a";
}
}
class Point
{
public int $x;
public int $y;
public string $color;
public function __construct(int $x, int $y, string $color)
{
$this->x = $x;
$this->y = $y;
$this->color = $color;
}
public function draw(Sheet &$sheet, string $color = DEFAULT_COLOR)
{
if ($color == DEFAULT_COLOR){
$color = $this->color;
}
$sheet->setPoint($this->x, $this->y, $color);
}
}
class Rectangle extends Point
{
public $width;
public $height;
public function __construct(int $x, int $y, int $width, int $height, string $color = BLACK)
{
parent::__construct($x, $y, $color);
$this->width = $width;
$this->height = $height;
}
public function draw(Sheet &$sheet, string $color = DEFAULT_COLOR)
{
if ($color === DEFAULT_COLOR){
$color = $this->color;
}
for ($x = $this->x; $x < $this->x + $this->width; $x++) {
for ($y = $this->y; $y <= $this->y + $this->height; $y++) {
$sheet->setPoint($x, $y, $color);
}
}
}
}
class Robot extends Point
{
public $target;
public string $color;
public string $colorTarget;
public int $xDirection = 1;
public int $yDirection = 1;
public function __construct(string $color, Sheet &$sheet)
{
parent::__construct(0, 0, $color);
$this->target = null;
$this->color = $color;
$this->colorTarget = strtolower($color);
$sheet->setRandomPosition($this);
$this->setTarget($sheet);
}
public function checkDirection(Sheet &$sheet)
{
if ($this->x <= 0) {
$this->xDirection = 1;
} elseif ($this->x >= $sheet->width - 1) {
$this->xDirection = -1;
}
if ($this->y <= 0) {
$this->yDirection = 1;
} elseif ($this->y >= $sheet->height - 1) {
$this->yDirection = -1;
}
}
public function move(Sheet &$sheet): bool
{
$rc = false;
$x = -1;
$y = -1;
if ($this->target->x == $this->x && $this->target->y == $this->y) {
// $sheet->setRandomPosition($this->target, $sheet);
} else {
$this->target->draw($sheet);
$x = $this->x;
$y = $this->y;
if ($this->target !== $x) {
$x = $this->target->x < $x ? $x - 1 : $x + 1;
}
if ($this->target->y !== $y) {
$y = $this->target->y < $y ? $y - 1 : $y + 1;
}
$this->checkDirection($sheet);
if ($sheet->isOccupied($x, $y)) {
$x = $this->x + $this->xDirection;
$y = $this->y;
if ($sheet->isOccupied($x, $y)) {
$x = $this->x;
$y = $this->y + $this->yDirection;
}
}
if (!$sheet->isOccupied($x, $y)) {
// Remove current point:
$this->draw($sheet, WHITE);
$this->x = $x;
$this->y = $y;
$this->draw($sheet);
$rc = true;
}
}
return $rc;
}
public function setTarget(Sheet &$sheet){
if ($this->target == null){
$this->target = new Point(0, 0, $this->colorTarget);
} else {
$sheet->setPoint($this->target->x, $this->target->y, WHITE);
}
$sheet->setRandomPosition($this->target);
$sheet->setPoint($this->target->x, $this->target->y, $this->colorTarget);
}
}
class Simulator
{
public array $statics = [];
public array $mobiles = [];
public Sheet $sheet;
public function __construct(Sheet &$sheet)
{
$this->sheet = $sheet;
}
public function add($item, bool $isStatic)
{
if ($isStatic) {
array_push($this->statics, $item);
$item->draw($this->sheet);
} else {
array_push($this->mobiles, $item);
$item->draw($this->sheet);
}
}
public function buildHouses(int $rows = 5, int $cols = 5)
{
$width = ($this->sheet->width - 1) / $rows / 2;
$height = ($this->sheet->height - 1) / $cols / 2;
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
$x = $width / 2 + $row * 2 * $width;
$y = $height / 2 + $col * 2 * $height;
$item = new Rectangle($x, $y, $width, $height);
$this->add($item, true);
}
}
}
public function buildRobots(int $count)
{
$names = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($ix = 0; $ix < $count; $ix++) {
$car = new Robot($names[$ix], $this->sheet);
$this->add($car, false);
}
}
public function show()
{
$this->sheet->clearTerminal();
$this->sheet->showDrawing();
}
public function step()
{
$moves = 0;
foreach ($this->mobiles as $car) {
if ($car->move($this->sheet)){
$moves++;
};
}
return $moves > 0;
}
}
$sheet = new Sheet(40, 40);
$simulator = new Simulator($sheet);
$simulator->buildHouses(3, 3);
$simulator->buildRobots(5);
$simulator->show();
$rounds = 0;
while ($simulator->step()){
$rounds++;
$simulator->show();
sleep(1);
}
echo "== ready after $rounds rounds\n";