チュートリアル
スタートキットを使ってAIプログラムを開発を進めてみましょう。
スタートキットの準備
Section titled “スタートキットの準備”スモウルビー甲子園のスタートキットをまだダウンロードしていない場合は、以下のページよりダウンロードします。
ダウンロードしたZipファイルを解凍すると、以下のファイルが表示されます。
- ai_goto_goal.rb
- battle-map.json
- koshien-project.sb3
このファイルを使ってプログラムの開発を進めていきましょう。
スモウルビーにアクセスします。 “ファイル”メニューの”コンピュータから読み込む”を選択します。
ファイル選択ダイアログでプロジェクトファイル「koshien-project.sb3」を開きます。

プロジェクトファイルの内容が読み込まれ、上の画面が表示されます。
まずはこの状態でAIプログラムを実行します。“スモウルビー甲子園”メニューの”AIを試す”を選択します。

スモウルビー甲子園のゲーム画面が表示され、プレイヤー1にスモウルビーで作成中のAIプログラム(スタートキット戦士)が設定されます。

[START]ボタンをクリックしてプレイヤー1が動作することを確認します。プレイヤー1が動くことが確認できたらOKです。画面左上の「戻る」ボタンをクリックし、スモウルビーの画面に戻ります(ゲーム終了まで待つ必要はありません)。
初期状態では以下のように「ステップ2:探索しながらシンプルにゴールを目指す」というブロックが設定されています。このプロジェクトにはいくつかブロックが配置されていますが、実行時に動作するのはこの部分だけになります(他はいずれもブロック定義を表します。この章の後半で利用します)。
いったんこのブロックを外し、代わりに画面左のブロックの中から「ステップ1:決まった経路を歩く」を選択し、以下のように設定してください。
設定できたら”スモウルビー甲子園”メニューの”AIを試す”を選択してゲーム画面を表示します。今回はスタートキットに同梱されている対戦マップを利用します。[CONFIG]ボタンより設定ダイアログを開き、対戦マップのラジオボタンを「独自マップを設定する」に変更し、「ファイル選択」よりスタートキットに含まれる「battle-map.json」を選択します。[適用する]をクリックして対戦マップが反映されるのを確認します。

[START]ボタンをクリックしゲームを開始します。プレイヤー1がゴールに向かってまっすぐ進む様子が確認できます。 ラウンド1だけ実行したら画面左上の[戻る]ボタンをクリックしてスモウルビーの画面に戻ります。「ステップ1:決まった経路を歩く」の定義を見てみましょう。
上図のようになっています。ひとつずつ移動先の座標を指定して進んでいっているのがわかります。このブロック定義を編集してみましょう。現在指定されている座標はまっすぐゴールに進むだけでしたが、加点アイテムをとり減点アイテムを避けながらゴールに向かうようブロックを追加・編集してみてください。指定できたらAIプログラムを実行し、期待したルートで移動できているか確認してください。
ステップ1では予めスタート位置・ゴール位置が決まっているものとしてプログラムを作成しましたが、このプログラムでは他の対戦マップで動作しません。ステップ2ではどんなスタート位置・ゴール位置でも動作するようなプログラムを作成します。
「ステップ1:決まった経路を歩く」を外し、代わりに「ステップ2:探索しながらシンプルにゴールを目指す」を設定します。「ステップ2:探索しながらシンプルにゴールを目指す」は1ターン分の動作のみが指定されているため、繰り返し実行する必要があります。以下のように「ずっと〜する」ブロックと組み合わせます。
「ステップ2:探索しながらシンプルにゴールを目指す」の定義を見てみましょう。
「座標付近のマップ情報を取得する」「ゴールまでの最短経路をリストに保存する」のブロックが使われているのがわかります。
前者(座標付近のマップ情報を取得する)は指定した座標を中心とした5x5のセルの情報を読み込みます。このブロックを使ってセルの情報を読み込んでいない限り、AIプログラムはどこにどんな地形・アイテムがあるか把握していません。わかっているのは自分の座標とゴールの座標のみです。例えば、地形を把握してない状態で「ゴールまでの最短経路をリストに保存する」を使うと、通れない壁のセルを通過するような間違った経路を取得する可能性があります。そうならないために、ここではあらかじめ自分の周辺のセルの情報を取得した上で最短経路を取得しています。
後者(ゴールまでの最短経路をリストに保存する)は現在の座標からゴールまでの最短経路を取得し、その結果を指定したリストに格納します。リストの先頭が現在位置、リストの2番目が次の移動先、リストの3番目がその次の移動先、、、リストの最後が終点(=ゴール)となります。ここではリストの2番目の座標を取り出し、その座標に移動しています。
実際にAIを動かしてゴールに向かって進んでいく様子を確認してみましょう。ステップ1のAIプログラムではラウンド1のスタート位置でしか動作しませんでしたが、ステップ2のAIプログラムはラウンド1、ラウンド2のいずれのスタート位置でも動作することが確認できます。
ステップ2ではどんな位置からスタートしてもゴールを目指すように改良しました。しかし、マップ上のアイテムを無視してただひたすらにゴールを目指すため得点を伸ばすことはできません。ステップ3ではマップ上にある加点アイテムを取りながらゴールを目指すプログラムを作成します。
「ステップ2:探索しながらシンプルにゴールを目指す」を外し、代わりに「ステップ3:探索しながら途中のアイテムをとりつつゴールを目指す」を設定します。
「ステップ3:探索しながら途中のアイテムをとりつつゴールを目指す」の定義を見てみましょう。
上から2つ目に「範囲内の地形・アイテムをリストに保存する」のブロックが使われています。このブロックは指定した座標を中心とする範囲にある、指定した地形・アイテムの座標をリストに格納します。ここでは、自分を中心とする5x5の範囲にある加点アイテム(a,b,c,d,e)を”近くのアイテム”というリストに保存しています。
続いて条件分岐のブロックが使われています。自分の周囲5x5の範囲にアイテムがある場合とない場合で処理が分かれています。近くにアイテムがある場合そのひとつめのアイテムを目指し、アイテムがなければゴールを目指して最短経路を取得します。最短経路を取得した後は、ステップ2と同様に最短経路の2番目(目的地に向かって現在のセルの次のセル)の座標に移動しています。
実際にAIを動かしてゴールに向かって進んでいく様子を確認してみましょう。ステップ3のAIプログラムでは近くのアイテムを取りながらゴールに向かっていきます。
ステップ3では途中の自分の周囲のアイテムは取りながらゴールに向かう動きを実現できました。ただし、自分から離れた位置にあるアイテムは把握しておらず高得点アイテムを取りこぼすことがありました。ステップ4ではマップ全体を把握した上でもう少し広い範囲のアイテムを取りながら進んでいくプログラムを作成します。
「ステップ3:探索しながら途中のアイテムをとりつつゴールを目指す」を外し、代わりに「ステップ4の1:マップ全体を探索する」「ステップ4の2:マップ全体のアイテムを取りながらゴールへ」を設定します。「ステップ4の1:マップ全体を探索する」はゲームサーバへ接続の直後に、「ステップ4の2:マップ全体のアイテムを取りながらゴールへ」は「ずっと〜する」ブロックと組み合わせます。
まず「ステップ4の1:マップ全体を探索する」の定義を見てみましょう。
「座標付近のマップ情報を取得する」が連続して実行されています。「座標付近のマップ情報を取得する」のブロックは1ターンに2回までしか実行できないため、2回実行した後は「ターンを終了する」ブロックを挟んでいます。マップ全体が17x17の広さとなっていて、「座標付近のマップ情報を取得する」は5x5の範囲しか読み取れないため、全体を読み込むには基準座標をずらしながら合計16回の実行が必要になります(ただし外壁を除くと15x15となるため改良の余地はあるかもしれません)。
つづいて「ステップ4の2:マップ全体のアイテムを取りながらゴールへ」の定義を見てみましょう。
定義の最初と最後は「ステップ3:探索しながら途中のアイテムをとりつつゴールを目指す」と同じものになっていますが、途中に「もし近くのアイテムの長さが0なら」「範囲内の地形・アイテムをリストに保存する」というブロックが4つ挟まっています。4つは中心座標が異なっており、プレイヤー座標からX方向に+5、-5、Y方向に+5、-5ずらした4つの座標でそれぞれ近くのアイテムを抽出しています。もし、どこかのエリアでアイテムが見つかればそのアイテムを目指して進み、どこにもアイテムが見つからない場合はゴール目指して進むものとなっています。
実際にAIを動かして確認してみましょう。ステップ3で作成したAIプログラムは、ラウンド2ではゴールに向かう経路近傍にアイテムがないためまっすぐゴールに向かっていましたが、今回作成したAIプログラムは経路近傍にアイテムがない場合もアイテムを目指して動く様子が確認できます。
ステップ4では広い範囲のアイテムを取りながら進むAIプログラムを作成することができました。 さらなる発展形として次の改良に挑戦してみてください。
- 減点アイテムを取らないようにする
- 妨害キャラクタに接触しないようにする