トラック
/
Go
Go
/
演習
/
ロボットシミュレーター
ロボットシミュレーター

ロボットシミュレーター

中級

説明

ロボットシミュレーターを書いてみましょう。

ロボット工場の試験施設では、ロボットの動きを検証するプログラムが必要です。

ロボットにできる動きは3つあります。

  • 右に曲がる
  • 左に曲がる
  • 前進する

ロボットは、無限に広がる仮想のグリッド上に置かれ、{x,y}座標(たとえば{3,8})の位置で、north、east、south、westのいずれかの方向を向いています。座標は北と東に向かって大きくなります。

その後、ロボットはいくつかの命令を受け取り、試験施設はロボットの新しい位置と、向いている方向を検証します。

  • 文字列"RAALAL"は、次の意味です。
    • 右に曲がる
    • 2回前進する
    • 左に曲がる
    • 1回前進する
    • もう一度左に曲がる
  • たとえば、ロボットが{7, 3}でnorthを向いてスタートするとします。この一連の命令を実行すると、ロボットは{9, 4}でwestを向いているはずです。

実装上の注意

テストは3つのステップに分かれています。

すべてのテストを実行するにはgo testを使います。特定のテストだけを実行したい場合は、-tagsオプションを使います。

例:

go test                      # run all tests
go test -tags step1          # run just step 1 tests.
go test -tags 'step1 step2'  # run step1 and step2 tests

テストプログラムが必要とするさまざまなものを定義したソースファイルdefs.goが与えられます。このファイルは、ステップごとに3つのセクションに分かれています。

ステップ1

ステップ1を完了するには、Right、Left、Advance、N、S、E、W、Dirを定義します。ステップ2に進む前に、ステップ1を完了してください。

ステップ2

ステップ1ではロボットの動きを実装しましたが、まだシミュレーションとは言えません。たとえば、ソースコードのどこが「ロボット」なのでしょうか? 「グリッド」はどこにあるのでしょうか? ロボットの行動をグリッド上の位置に変換する計算は、ロボットの中にあるのでしょうか、それともグリッドの中にあるのでしょうか? 現実の世界は、これとは違います。

ステップ2では、「部屋」を導入します。小さな追加のように思えますが、「部屋」「ロボット」「テストプログラム」それぞれの役割をはっきりさせ、シミュレーションの物理を明らかにし始めるために、大きな変更を加えます。

RoomとRobotは関数として定義します。テストプログラムはこれらをゴルーチンとして起動することで「実体化」させます。情報は、Goのチャネルを通じて、テストプログラム、ロボット、部屋の間を行き来します。

Roomは「物理エンジン」だと考えてください。壁とロボットがある物理的な部屋をモデル化し、シミュレーションするものです。部屋の座標空間、ロボットと壁の位置を何らかの形でモデル化し、たとえばロボットが壁を通り抜けないようにする必要があります。Robotは行動を実行するエージェントであってほしいのですが、Roomには整合性の取れた真実を保ってほしいのです。

テストプログラムがチャネルを作成し、RoomとRobotの両方を起動します。次に、テストプログラムがRobotにコマンドを送ります。コマンドを送り終えると、コマンドチャネルを閉じます。Robotはコマンドを受け取り、実行しようとしている行動をRoomに伝えなければなりません。コマンドチャネルが閉じたことを検知すると、自分自身を終了しなければなりません。部屋は、ロボットの行動が物理的にどんな結果をもたらすかを解釈しなければなりません。ロボットが終了したことを検知すると、ロボットの最終的な位置と向きを伝える最終レポートをテストプログラムに送り返します。

ステップ3

ステップ3には3つの大きな変更があります。

  • ロボットは、個々のコマンドに応答するのではなく、スクリプトを実行します。
  • ログチャネルを使うと、ロボットと部屋がメッセージを記録できます。
  • 部屋は、複数のロボットが同時に存在して動作することを可能にします。

Room3から送られる最終的な位置レポートでは、ロボットチャネルから受け取ったのと同じスライスを、位置と向きを更新したうえでそのまま返してかまいません。次の場合には、ログチャネルにメッセージを送る必要があります。

  • 名前のないロボット
  • ロボットの名前の重複
  • 同じ場所に配置されたロボット
  • 部屋の外に配置されたロボット
  • スクリプト内の未定義のコマンド
  • 未知のロボットからの行動
  • 壁に進もうとするロボット
  • 別のロボットに進もうとするロボット

出典

とある有名企業の面接の質問に着想を得たもの。
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Go Exercism

ロボットシミュレーターを始める準備はできましたか?

Exercismに登録すれば、34個のコンセプト165個の演習、そして本物の人間によるメンタリングとともに、Goを学んでマスターできます。すべて無料です。