ルンバをぼーっと眺めていてどんなアルゴリズム書けば効率よく掃除できるのか気になったので、簡単なシミュレータを作った。
ぶつかったときの動きと、ぶつからずに一定の距離を進んだときの動きを書いて読み込ませると何回の行動で綺麗にできたか結果を出力する。
使い方
composerでインストールして使う。
{
"require" : {
"sat8bit/roombasim" : "dev-master",
"symfony/console" : "3.0.*@dev"
},
"repositories": [
{
"type":"vcs",
"url": "git://github.com/sat8bit/roombasim.git"
}
]
}
で、コマンド実行。残念な感じでRoombaの動きを表示する。
$ vendor/bin/roombasim roombasim 'sat8bit\RoombaSim\Roomba\RoombaAISample' --disp
R(7), C(5.3900627682607, 3.8575910007494), D(240)
| |
| . . . . . . . . . . . . . .|
| . . . .() . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
| . . . . . . . . . . . . . . . . . . . .|
Arguments
コマンド名。入れなくてよくしたい。
roombasim
AIクラス。作り方は後述。
'sat8bit\RoombaSim\Roomba\RoombaAISample'
Options
部屋を変更する。デフォルトは15x15の部屋(RectangleRoom15x15)。
--room "RectangleDirtyRoom15x15"
最大行動回数を変更する。
--step 20
途中経過を可視化する。
--disp
Roombaの作り方
前提条件
- Roombaは、左上のマスを右向きでスタートする。
- Roombaは、最初は壁に当たるまで走り続ける。
実装
RoombaAIInterface
下記のinterfaceを実装したクラスを作成する。
<?php
namespace sat8bit\RoombaSim\Roomba;
interface RoombaAIInterface
{
/**
* when hit.
* hitメソッドは壁や障害物に当たったときの動きを返す。
*
* @param int $distance
* @return Motion
*/
public function hit($distance);
/**
* when ran.
* ranメソッドは壁や障害物に当たるより先に指定の距離を走ったときの動きを返す。
*
* @param int $distance
* @return Motion
*/
public function ran($distance);
}
Motion
クラスは回転角度(時計回り)と走行距離を引数に作成する。
Sample
<?php
class RoombaAISample implements RoombaAIInterface
{
/**
* when hit.
*
* @param int $distance
* @return Motion
*/
public function hit($distance)
{
// 壁にあたったらランダム(0~360度)で回転し、1000進む
return new Motion(mt_rand(0, 360), 1000);
}
/**
* when ran.
*
* @param int $distance
* @return Motion
*/
public function ran($distance)
{
// 回転せずに1000進む。つまり壁に当たるまでまっすぐ走り続ける
return new Motion(0, 1000);
}
}
実行
autoloadできる場所において引数で渡す。
vendor/bin/roombasim roombasim 'RoombaAISample' --disp
デフォルトで用意されているRoom一覧
変更する場合はroomオプションでクラス名を指定します。自分で部屋を作ることもできます。
クラス名 | 説明 |
---|---|
RectangleRoom15x15 | 長方形の部屋 |
RectangleDirtyRoom15x15 | RectangleRoom15x15より汚れが激しい長方形の部屋 |
LivingRoom20x15 | (想像を働かせて)L字型のソファとローテーブル、テレビ台が障害物となっている部屋 |