公式説明書（2024年度版）

株式会社ネットワーク応用通信研究所

目次
１．スモウルビー・プログラミング甲子園について･･･P2
２．ゲームの試し方･･･P4
３．スモウルビー甲子園のルール･･･P7
４．スモウルビーの使い方･･･P10(1)スモウルビー・エディタの起動･･･P10(2)スモウルビー・エディタの画面構成･･･P10(3)ブロックの種類と使い方･･･P11(4)プログラムの保存･･･P14(5)プログラムの実行･･･P15
５．AIプログラムの作り方･･･P16(1)最初に覚えておくこと･･･P16(2)テンプレートの使い方･･･P17(3)スモウルビー甲子園メソッドの種類と使い方･･･P18(4)簡単なAIプログラムを作ってみる･･･P26
６．便利なメソッドの紹介･･･P31(1)草薙の剣の座標を調べる･･･P32(2)配列に含まれる座標の数を確認する･･･P33(3)一番近い加点アイテムを目指して移動する･･･P34(4)ターン数を管理する･･･P36(5)ダイナマイトを置く･･･P37
7．作戦の考え方･･･P39(1)やり方1･･･P39(2)やり方2･･･P39(3)優勝者からのアドバイス･･･P39
8．その他の説明･･･P43(1)スモウルビー甲子園の構成･･･P43(2)マップエディタの使い方･･･P43(3)ログの確認方法･･･P45(4)エラーの調べ方･･･P46
9．参考･･･P48

1. スモウルビー・プログラミング甲子園について

スモウルビー・プログラミング甲子園は、学生（20歳以下）のプログラミング競技会。自作のAIプログラム同士がゲームで対戦し、得点を競います。

募集期間 2024年7月1日（月）～2024年12月31日（火）募集作品 スモウルビーで作成した本大会ゲーム用のAIプログラム
参加資格 学生（20歳以下）の個人又はグループ（2004年4月1日以降生まれの方。グループ参加の人数制限なし。）

AIプログラムは、ビジュアル・プログラミングツール「スモウルビー」で作成します。
このAIプログラムがスモウルビー甲子園ゲームのキャラクタを操作します。

2

予選上位24組が決勝大会に出場可能。
決勝大会ではトーナメントで優勝を目指してもらいます。
とき
形式
表彰

2025年3月20日（木・祝）オンライン開催
優 勝：賞状・副賞10万円 準優勝：賞状・副賞5万円
第三位：賞状・副賞1万円 特別賞：賞状・副賞3万円

32． ゲームの試し方
・デスクトップ上のスモウルビー甲子園2024アイコンをダブルクリックしてください。
・ゲームビューアが起動したら、「START」ボタンをクリックしてください。

・ゲームは2ラウンドを行います。（2ラウンドの合計得点で勝敗を決定します。）
・ROUND1が終了したら、もう一度「START」ボタンをクリックしてください。

・ゲーム終了後、再度ゲームを試したい場合は「NEW GAME」ボタンをクリックして
ください。

4

[使用するAIプログラムを変更する場合]
・「CONFIG」ボタンをクリック・変更したいプレイヤーの「選択」ボタンをクリック

・ファイルを選択し、「開く」ボタンをクリック［スモウルビーで作ったプログラムの保存場所］
Cﾄﾞﾗｲﾌﾞ > koshien2024 > smalruby > programsの中［サンプルプログラムの格納場所］
Cﾄﾞﾗｲﾌﾞ > koshien2024 > src > samples > の中※順番に高度な内容になっています。⇒

smpl01
smpl02
smpl03
5

・「ゲームサーバとの通信間隔」を設定（秒数を少なくするとゲームの進行速度が速くなります。）[対戦マップを変更する場合]
・マップディレクトリの「選択」ボタンをクリック

・フォルダを選択し、「OK」ボタンをクリック［マップエディタで作ったプログラムの保存場所］
Cﾄﾞﾗｲﾌﾞ > koshien2024 > map_editor > data の中※間違って編集しないよう保存したファイルはどこか別の場所に移して置きましょう。
（koshien2024 > map_editor > data に新しくフォルダを作って保存しておくと便利です。）［サンプルマップ及び過去の決勝大会のマップ格納場所］
Cﾄﾞﾗｲﾌﾞ > koshien2024 > sample_maps の中以上で設定は完了です。
66

3. スモウルビー甲子園のルール（１）基本ルール
・15マス×15マスのマップ上でゴールを目指すゲーム
・最大50ターンのターン制で進行
・プレイヤーは1ターンに1マスだけ移動可能
・1ターンにAIプログラムを実行できる時間は10秒以内（２）マップ情報について
・ゲーム開始時点で、プレイヤーは、自分の位置とゴールの位置を知っていますが、それ以外のマップ情報（マップ上に何があるか、などの情報）を持っていません。
・マップ情報は、「マップ情報を取得」の命令を実行した5マスｘ5マスの範囲の情報を取得することができます。「マップ情報を取得」の命令を実行していない範囲のマスは「未探索のマス」と認識します。

⇒

・マスには、移動可能な「空間」マス、移動できない「壁」マスなど複数種類あり
種

類

値

内

容

未探索の
マス

-1

マップ情報が不明なマス。最短経路を検索するときは移動可能なマスとみなす。

0

空間（自由に移動可能なマス）

1

壁（移動できないマス）

2

蔵（移動できないマス）

3

ゴール（到着するとラウンドが終了し、通過はできないマス）

4

水たまり（移動命令が1回実行されないマス）

5

壊せる壁（移動できないマス。ただし、ダイナマイトで壊すと空間に変わり移動可能になる）
7

・大会ルールとしてマップは壁または蔵に囲まれているものとします。
・プレイヤー1とプレイヤー2が同時に同じマスに入ることができます。
・早いターン数でゴールすれば高い得点を獲得（ゴールボーナス）
ﾀｰﾝ数

1-10

11-20

21-30

31-40

41-50

未ｺﾞｰﾙ

得点

100点

90点

80点

70点

60点

0点

・マップ上には加点アイテムと減点アイテムが設置されています。アイテムが設置されているマスにプレイヤーが入ると、アイテムを取ったことになり、アイテムの点数が加点または減点されます。
[加点アイテム]
お茶

和菓子

丁銀

ｼﾛｲﾙｶ

草薙剣

値

a

b

c

d

e

得点

10点

20点

30点

40点

60点

種類

・大会ルールとして、草薙剣はマップ上に1個のみ出現するものとします。
(対戦環境のマップ上に草薙剣を2個以上設置することは可能ですので、マップを自作される場合はご注意ください。)[減点アイテム]
毒ｷﾉｺ蛇

ﾄﾗﾊﾞｻﾐ

爆弾

値

A

B

C

D

得点

▲10点

▲20点

▲30点

▲40点

種類

・アイテムが設置されているマスにプレイヤー1とプレイヤー2が同時に入ったときは、アイテム
点数の半分の点数が両方のプレイヤーに加点または減点されます。

[使えるアイテム]
種類

内容

ダイナマイト。
空間または水たまりの上に置いて、隣にある「壊せる壁」を壊すことが出来る。
爆弾。
減点アイテムとして空間におくことができる。

8

・妨害キャラクタ

→（1～40ターン）（41～50ターン）

・1回の接触につき10点減点（何度でも接触します。）
・プレイヤーキャラクタがゴールしたとき、ゴール上に妨害キャラクタがいるときも減点されます。
・1～40ターンはランダムで移動しますが、プレイヤーキャラクタが3マス以内に入ると、プレイヤー
キャラクタへ向かって移動します。
・41～50ターンは最寄りのプレイヤーキャラクタに向かって移動します。プレイヤー1とプレイヤー2が等距離にいる場合は、ラウンド1はプレイヤー1へ、ラウンド2はプレイヤー2 へ向かって移動します。

・妨害キャラクタの撃退
草薙剣を保持した状態で妨害キャラクタに接触すると30点加点。妨害キャラクタは画面からいなく
なります。
・歩行得点
5マス移動するたびに3点が加点されます。
（３）タイムアウトについて
・1ターンの間にAIプログラムを実行することができる時間は10秒以内です。
・10秒を超えると「タイムアウト」になります。
・タイムアウトになると、画面に「タイムアウトしました」と表示され、プレイヤーキャラクタが 画面からいなくなります。
・タイムアウトになった場合の得点は、タイムアウトになるまでに取った加点アイテムの得点、減点アイテ
ムの得点、および歩行得点の合計点です。

9

4. スモウルビーの使い方（１）スモウルビー・エディタの起動
デスクトップ上にあるスモウルビーAI作成のアイコンをダブルクリックするとスモウルビー・エディタが起動します。

（２）スモウルビー・エディタの画面構成
スモウルビー・エディタの画面構成は次の通りです。

プログラムエリア

スモウルビーのプログラムを組み立てるキャンパスとなる領域

ジャンル

プログラムエリアに配置できる各種命令ブロックをグルーピングした領域

ゴミ箱

プログラムエリアで不要になったブロックを廃棄するためのツール（廃棄したい命令ブロックをゴミ箱にドラッグ＆ドロップ）

キャラクターリスト

スモウルビーの実行画面に表示するキャラクタの画面を管理する領域

操作メニュー

作成したプログラムの実行や、保存・読み込みなどの各種操作を行う領域

ブロック

ジャンルより選択した命令ブロックがプログラムエリアに表示

モード切替「スモウルビー」と「Ruby」モードの切り替え画面（「Ruby」モードではRubyのコードに変換されて表示）
10

（３）ブロックの種類と使い方
・ブロックの種類と格納場所
ブロックはジャンルの中に格納されています。
このブロックを組み合わせることにより、プログラムを作ります。

・AIプログラム作成では次のジャンルのブロックをよく使います。
[甲子園]►スモウルビー甲子園専用に用意したブロックを格納

11

[データ]►変数を設定する場合に使用するブロックを格納[制御]►条件分岐で使用するブロックを格納[その他]►コード入力に使用できるブロックを格納・ブロックの組み合わせ
ブロックには、「文ブロック」と「式ブロック」の2種類があります。

12

[文ブロック]►プログラムの処理を構成する主要なブロック►プログラムは、結合された文ブロックを上から下へ処理接続したいブロックを近づけ、もう１方のブロックの接続部が黄色くなると接続できます[式ブロック]►式ブロックは、戻り値を伴うRubyの式を実行するためのブロック►他の文ブロックや式ブロックの中にある「スロット」に組み込んで使用[参考]►文ブロック3つの組み合わせ ⇒ この内容が上から下に実行される►式ブロックは文ブロックに組み込んで使用（緑囲い部分）

13

（４）プログラムの保存・作成したプログラムには名前を付けてから保存します。
※ファイル名の最後に.rbを必ず付けてください。

・ファイルは以下のディレクトリに保存されます。
Cドライブ > koshien2024 > smalruby > programs

・「Ruby」モードに切り替え、同じようにセーブを行います。。

14

（5）プログラムの実行・作成したプログラムは、「実行」ボタンを押すことにより、実際に動かすことができます。
※AIプログラムは「実行」ボタンで動かすことはできません。

・AIプログラムを動かすことはできませんが、デバックに利用することができます。
⇒AIプログラムを実行した場合、必ず2つのエラーが表示されます。
⇒これ以外のエラーが表示された場合はプログラムに問題があります。

15

5.AIプログラムの作り方（１）最初に覚えておくこと・マップにはx軸とy軸があり、0から14までの番号が付いています。

・このx軸、y軸の番号を使って、特定のマスの位置を表すことができます。
マスの位置を座標と言い、[x座標,y座標]で表します。
x座標は、東に行くと増え、西に行くと減ります。（算数・数学と同じ向き） y座標は、北へ行くと減り、南へ行くと増えます（算数・数学と反対向き） マーカー部の座標を表すと下のようになります。
X軸
0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

0
1
2

[2,2]

[7,2]

[12,2]

[2,7]

[7,7]

[12,7][2,12][7,12][12,12]

3
4
5
6
y
軸

7
8
9
10
11
12
13
14

16

・「配列」について
Rubyには「配列」というデータ形式があります。
複数のデータをひとまとまりにして扱うことができる形式です。
Rubyの配列は、データをコンマで区切り、角かっこで囲みます。
例[データ1,データ2,データ3]
実は、スモウルビー甲子園において座標は配列です。
例[7,7]
複数の座標を扱う場合、【座標の配列】で表します。
例[[7,7],[7,8],[7,9]]※座標の取り扱い方座標が配列であること、いろいろな命令の実行結果が【座標の配列】で得られることを覚えてください。

（２）テンプレートの使い方
・AIプログラムは次のテンプレートを使って作成します。

・テンプレートの読み込みスモウルビー・エディタを立ち上げ、「メニュー」―「ロード」「ai_template.rb」を選択し「決めた」をクリック

17

・テンプレートの構成

・テンプレートに含まれるブロックは消さないように気を付けてください。消すと動かなくなります。
消してしまったときは「甲子園」ジャンルの中から取り出して入れてください。
・「ずっと～を繰り返す」の中に命令ブロックを入れていきます。
・「ずっと～を繰り返す」のブロックは、「実行ボタンがクリックされたとき」のブロックの内側に入れたままにしてください。外側に出すと動かなくなります。
・「ずっと～を繰り返す」の内側に「ターンを終了する」入れてください
・ターンが始まって 10 秒以内に「ターンを終了する」を実行しないとタイムアウトになり、そのラウンドの行動は終了する、というルールです。
・「ターンを終了する」が無いと、10秒を過ぎても「ターンを終了する」を実行することができないので、タイムアウトします。
（３）スモウルビー甲子園メソッドの種類と使い方①1マス移動する
1回のみ①③④のいずれか2回まで

ブロック

コード

move to（引数）実行内容・指定した座標にプレイヤーが1マス移動します。
・指定できるのは現在地から東西南北の1マスです。（斜めには移動できません）

引数・移動先の座標を配列または変数で指定します。

解説

・移動できるのは空間と水たまりだけで、壁には移動できません。
・移動できない座標を指定した場合、使用回数はカウントされますが、実行は無視されます。
・水たまりに移動した場合は、次回の移動命令が無視されます。（使用回数はカウントされます。）※1ターンの使用回数に制限のある命令があります。詳細はP25をご覧ください。

18

②最短経路を検索する
ブロック

コード

calc_route（引数）

実行内容・指定した2点間の最短ルートを検索します。
・戻り値として、始点から終点までの座標配列が返されます。

引数・引数としてハッシュを指定します。
・指定できるハッシュは、「始点」「終点」「通らない座標」です。
・それぞれのハッシュは省略も可能です。
［ハッシュを省略した場合の設定］►始点：現在地►終点：ゴール►通らない座標：未設定
・戻り値の座標配列は次の順番に並んでいます。
[[始点],[次の移動先],･･･経路順の座標･･･,[終点]]・戻り値の中の各座標は並び順に0,1,2,3･･･の番号で指定できます。
・指定した条件での経路がない場合は始点の座標が1つだけ返されます。
・マップ情報を取得していない範囲のマス（未探索のマス）は全て移動可能とみなして経路探索するので注意が必要です。ただし、判明している空間マスがあれば、そちらを通る経路を優先します。
・関数ブロックとセットで使用します。

解説・コード入力する場合のハッシュ指定は次のとおりです。
⇒ src（始点）、dst（終点）、except_cells（通らない座標）⇒ 入力例1 全てのハッシュを指定する場合
calc_route(src:[13,9],dst:[7,7],except_cells:[9,9])
入力例2 通らない座標のみを指定する場合
calc_route(execpt_cells[9,9])
入力例3 ハッシュを省略する場合
calc_route19

③５マス×５マスのマップ情報を取得①③④のいずれか2回まで
ブロック

コード

get_map_area（引数）実行内容・指定した範囲（5マス×5マス）のマップ情報を取得します。
・戻り値として、指定した範囲のマップ情報が返されます。

引数

・指定したい範囲の中心座標を配列または変数で指定します。

解説

・取得できるマップ情報は、指定した範囲の以下の情報です。
►マップ構成（空間・壁・水たまり・ゴール・壊せる壁）►加点アイテム、減点アイテムがある場合は、その座標と種類解説►対戦相手が指定範囲内にいる場合はその座標►妨害キャラクタの現ターン開始時点の座標と前ターン開始時点の座標（妨害キャラクタのみは指定範囲内にいなくても情報取得が可能）
・取得した情報はAIライブラリに保存され、後から呼び出すことができます。

④ダイナマイトを置く①③④のいずれか2回まで

ブロック

コード

set_dynamite（引数）

実行内容・ダイナマイトを現在地又は隣接する東西南北のマスに設置します。

引数・ダイナマイトを設置したい座標を配列または変数で指定します。
・引数を省略した場合は現在地にダイナマイトを設置します。

解説・ダイナマイトは、空間または水たまりの上に置くことができます。アイテムがあるマスには設置できません。
・ダイナマイトは１ラウンドに2回まで設置できます。
・無効な座標を指定した場合、設置されませんが、ダイナマイトは1つ消費され、使用回数もカウントされます。
・両プレイヤーが同じ座標に同時にダイナマイトを設置した場合、両プレイ
ヤーとも設置は成功しますが、ダイナマイトは1つだけ設置されたことになります。
・ダイナマイトは設置したターンの終了時に爆発します。
・ダイナマイトが爆発すると、ダイナマイトのマスに隣接する「壊せる壁」は「空間」になり、次のターンから移動可能になります。
・ダイナマイトの爆発は「壊せる壁」以外の地形、プレイヤー、妨害キャラクタ、
アイテムに影響を与えません。ダイナマイトが爆発したマスや隣接したマスにプレイヤーがいても減点されることはありません。
20

⑤指定した座標のマップ情報を呼び出す
ブロック

コード

map（引数）

実行内容

・指定した座標のマップ情報を呼び出します。
・指定した座標のマップ情報が返されます。

引数・呼び出したい座標を配列で指定します。

解説・呼び出せるマップ情報は「③マップ情報の取得」で取得した情報です。
・マップ情報の取得を実行していない座標を指定した場合は、-1が返されます。
・マップエリア外を指定した場合は、nilが返されます。

⑥マップ全体のマップ情報を呼び出す
ブロック

コード

map_all

実行内容

・マップ全体のマップ情報を呼び出します。
・マップ全体のマップ情報が返されます。

引数

-

解説

・呼び出せるマップ情報は「③マップ情報の取得」で取得した情報です。
・マップ情報の取得を実行していない座標は、-1が返されます。

21

⑦指定した範囲に、指定した要素が存在するかどうかを確認する
ブロック

コード

locate_objects（引数）実行内容・指定した範囲に、指定した要素が存在するかどうかを確認します。
・指定した要素がある座標が返されます。

引数・引数としてハッシュを指定します。
・指定できるハッシュは次のとおりです。
►中心座標：指定する範囲の中心座標（省略時は現在地）►範囲：指定する範囲の縦横のマスの長さ（省略時は5）►地形・アイテム：確認したい要素の値（省略時は減点アイテム全種類）
・戻り値は座標の配列で返されます。
・配列の中の各座標はy座標が小さい順に並んでいます。（y座標が同じ場合は x座
標の小さいほうが先になります。）
・マップ情報を取得していない座標の情報は確認できません。
・関数ブロックとセットで使用します。

・マップ全体を範囲指定したい場合は次のようになります。
⇒減点アイテム

解説⇒加点アイテム・コード入力する場合のハッシュ指定は次のとおりです。
⇒ cent:[中心座標]
sq_size:[範囲(数値)]
objects:[“地形・アイテムをあらわす文字”の配列]⇒ 入力例 1 マップ全体の加点アイテムの座標を確認する場合
locate_objects(cent: [7,7],sq_size: 15,objects: [“a”,”b”,”c”,”d”,”e”])⇒ 入力例 2 マップ全体の水たまりの座標を確認する場合
locate_objects(cent: [7,7], sq_size: 15, objects: [4])22

⑧対戦キャラクタのx座標、ｙ座標
ブロック

コード

other_player_x

other_player_y

実行内容

・対戦相手の座標を呼び出します。
・最後にマップ情報の取得で把握した対戦相手の座標（ｘ、ｙ）を返します。

引数

-

解説

・得られる情報は、マップ情報の取得で把握した時点の情報です。
・対戦相手の座標は、マップ情報の取得の範囲に対戦相手がいないと把握できません。
・対戦相手の座標を把握していない場合は nil が返されます。
・マップ情報の取得を繰り返し行っている場合、情報が上書きされていくため、一度把握した対戦相手の座標を見失う場合があります。

⑨妨害キャラクタのx座標、ｙ座標
ブロック

コード

enemy_xenemy_y

実行内容・妨害キャラクタの座標を呼び出します。
・最後にマップ情報の取得で把握した妨害キャラクタの座標（ｘ、ｙ）を返しま
す。

引数

-

解説

・得られる情報は、マップ情報の取得で把握した時点の情報です。
・妨害キャラクタの座標は、マップ情報の取得の範囲に妨害キャラクタがいなくても把握できます。

23

⑩ゴールのx座標、ｙ座標
ブロック

コード

goal_xgoal_y実行内容

・ゴールの座標を呼び出します。
・ゴールの座標が返されます。

引数

-

解説

・ゴールの座標は、マップ情報の取得に関わらず呼び出し可能です。

⑪キャラクタのx座標、ｙ座標
ブロック

コード

player_x

player_y

実行内容

・キャラクタの座標を呼び出します。
・キャラクタの座標が返されます。

引数

-

解説

・キャラクタの座標は、マップ情報の取得に関わらず呼び出し可能です。

24

⑫プレイヤーの名前をつける
ブロック

コード

set_name（プレイヤー名）

実行内容

・プレイヤー名で設定した名前がゲーム時にプレイヤー名として表示されます。

引数

・引数としてプレイヤー名を入力します。

解説・文字列14文字まで入力できます。

⑬ターンを終了する
ブロック

コード

turn_over

実行内容

・現在のターンを終了させ、次のターンを待ちます。

引数

-

解説

・必ずターンの最後に1回実行する必要があります。
（ターン終了を実行しないとタイムアウトでゲームが終了します。）[甲子園メソッドの使用制限]
・次の命令には1ターンでの使用回数に制限があるので、注意してください。
（使用回数を超えた命令は無視されます。）→1ターン1回→次の3つの使用回数はいずれか2回（移動する以外は同じ命令を2回使用することも可能です。）

25

（４）簡単なAIプログラムを作ってみる
・困ったときは・思い通りに動かない・タイムアウトしてしまう
・エラーが出た〇プログラムの実行の記録が「ログファイル」というファイルに書き出されています。それを見ると動かなかった原因がわかるかもしれません。うまくいかないときはログファイルを見てみましょう。
〇プレイヤー１の結果は player1.log というログファイルに記録されています。メモ帳で開いて見ることができます。ログファイルをダブルクリックすると開きます。
・次のプログラムを作ってみましょう

最初にファイル名を変更してください。
ファイル名には、アルファベットか数字を使ってください。
「.rb」を消さないでください。消してしまったときは、半角で入力してください。
変更したらエンターキーを押してください。
次にプレイヤー名を変更してください。
ひらがな、カタカナ、漢字、アルファベット、数字が使えます。
14文字まで（15文字を超えるとエラーが発生します。）「ゴールを目指す」＝ゴールに到着するように移動することです。
キャラクタを移動するには「移動する」というブロックを使います。甲子園ジャンルの中に入っています。

「移動する」のブロックの空欄には、移動先の座標を入れます。
移動先の座標を調べるために「2点間の最短経路」のブロックを使います。

26

ただし、正しい座標を調べるためには、マップ情報を取得していなければなりません。そのために「マップ情報を取得」のブロックを使います。

「マップ情報を取得」を実行したあと、「2点間の最短経路」を実行すると、正しい座標を調べることができます。
「マップ情報の取得」のブロックに、以下のように「キャラクタのx座標」と「キャラクタのy座標」のブロックを組み合わせて実行すると、「今、自分がいる座標を中心として5マス×5マスの範囲」のマップ情報を取得します。

「2点間の最短経路」のブロックは、以下のように「セット」のブロックと組み合わせて使います。

・戻り値は、経路順の座標が返される（0からの番号で指定可能）
・引数を省略した場合は次の設定で経路を検索▶始点：プレイヤーキャラクタの現在地▶終点：ゴール▶通らない座標：設定なし
・未探索エリアは通行可能として経路検索（通れない経路を返す場合がある）
・変数をつけることで後から経路検索の結果の呼び出し可能

この例では、変数「route」の中に、「今、自分がいる座標からゴールまでの経路順の座標の配列」が格納されます。図の座標の場合、以下のような座標の配列が入ります。

[[13,9],[13,8],[13,7],[12,7],[11,7],[11,6],[10,6],[9,6],[8,6],[7,6],[7,7]]
今、自分がいる座標が[13,9]で、移動先の座標は[13,8]です。
route の中身の座標配列から[13,8]を取り出せれば良いということになります。
そのためには route[1] という式を使います。
式ブロックの空欄に「route[1]」と入力し、移動するブロックと組み合わせ、以下のようなブロックを
作ります。

27

ブロックを順番に組み合わせて、以下のように組み立てます。

組み立てができたら右上の「実行」ボタンをクリックします。

プログラムの保存と文法チェックをしてくれます。
以下の2つのエラーは出ても大丈夫です。

対戦環境を起動し、プレイヤー1のAI プログラムを自分のAIプログラムに取り換えて、対戦をスタートしてみてください。ゴールまで進むことを確認してください。

28

・先ほど作ったプログラムを改良します。
ファイル名を変更し、エンターキーを押してください。

29

・指定したマップ要素やアイテムの座標を確認するためのメソッド・取得したマップ情報から情報を呼び出すため、未探索エリアの情報は取得できません。
・引数として以下を指定▶中心座標：呼び出す範囲の中心座標を指定⇒マップ全体の場合は[7,7]▶範 囲：呼び出す範囲のマップサイズ指定⇒マップ全体の場合は15▶地形・アイテム：呼び出す地形・アイテムの値を指定⇒省略した場合は減点アイテムを呼び出す⇒値については別途説明します
・変数をつけることで後からこの情報を呼び出すことが可能

・減点アイテムを避けてゴールする経路がない場合もあり
・このため、経路がなかった場合の行動もプログラムする必要あり⇒ある場合とない場合の2種類の行動が必要
・こうした場合の条件分岐を使用
・条件に合致した場合（真）のみ、ブロックの中のプログラムを実行し、合致しない場合は、このブロックの処理は実行されない

・上のブロックでは変数「route」が2つあり、それぞれ中身が違う・プログラムは上から順番に処理⇒最初にAの内容が変数「route」となる⇒減点アイテムを避ける経路がない場合は、Bが実行され、Bの内容が変数「route」になる⇒減点アイテムを避ける経路がある場合は、Bの内容は実行されないため変数「route」はAのまま・プログラムが完成したら、「実行」ボタンをクリックしてプログラムの保存と文法チェックをします。
・対戦環境を起動し、プレイヤー1のAIプログラムを取り換えます。
・減点アイテムを避けていることが確認できるように、マップを map3に変更します。
・対戦をスタートして、減点アイテムを避けながらゴールまで進むことを確認してください。
30

6. 便利なメソッドの紹介[紹介する内容](1)草薙剣の座標を調べる(2)配列に含まれる座標の数を確認する（例：経路検索した経路があるかを確認する）(3)一番近い加点アイテムを目指して移動する(4)ターン数を管理する(5)ダイナマイトを置く(例:プレイヤーが壊せる壁の隣のマスに来たらダイナマイトを置く)

31

(1)草薙剣の座標を調べる<ブロックの例>

・「範囲内の地形・アイテム」のブロックを使うと、指定したマスの種類（壁や水たまりなど）の座標や、指定したアイテムの座標を取得することができます。

・中心座標[7,7]、範囲15を指定すると、マップ全体から指定したアイテムなどの情報を取得することができます。以下のように式ブロックを利用します。

・草薙剣の座標を確認したい場合は、地形・アイテムのスロットに以下のような式ブロックをあてはめます。

32

・「セット ○○ 宛先 □□」というブロックを用意して、変数名を付けます。変数名は自由に付けることができます。ここでは「kusanagi」とします。宛先に、「範囲内の地形・アイテム」のブロック、中心座標の式ブロック、範囲の式ブロック、草薙剣を表す式ブロックを組み合わせたものを入れます。これで後から「kusanagi」という変数を参照することで、草薙剣の座標を取り出すことができます。

[注意]・マップ探索を実施したエリアの情報のみが確認できます。
（マップ探索をしていないエリアの情報は確認できません。）
・また、確認できる情報はマップ探索を行った時点での情報です。
アイテムを対戦相手が取得してなくなっているなど、情報が古くなっている場合がありますので、注意
してください。

(2)配列に含まれる座標の数を確認する（例：経路検索した経路があるかを確認する）<ブロックの例>

・Rubyのsizeメソッドを使用することにより、配列に含まれる座標の数を確認することができます。
（sizeメソッドでは、指定した配列に含まれる要素の数を返します。）
・例えば、経路検索では、指定した条件の経路がない場合は、始点の座標を 1 つだけ返します。このことから、sizeメソッドを使うことにより、経路のありなしを確認できます。（戻り値が１の場合は経路がないことが分かります。）
また、sizeメソッドを使って、加点アイテムの有無なども確認できます。
[使用例]“減点アイテムを避けてゴールする経路を検索し、もし、この経路がない場合は、ゴールまでの最短経路を検索する”[ブロックの処理内容]
・減点アイテムの座標を確認し、その結果に「traps」と名前を付ける
・始点：現在地、終点：ゴール、通らない座標：減点アイテムで、経路を検索し、その結果に「route」と名前を付ける
・もし、「route」に含まれる座標の数が１であれば（経路がない場合は）、 始点：現在地、終点：ゴール、通らない座標：未設定で経路検索する

33

（3）一番近い加点アイテムを目指して移動する<ブロックの例>

・マップ上の指定した要素（アイテムマップ要素）の座標を確認する方法は(3)でやったとおりですが、今度はマップ上の加点アイテムの座標を確認し、一番近い加点アイテムを終点として移動するブロックを作ります。
・最初に加点アイテムの座標を確認し、この結果に「items」という名前を付けます。

・次に「items」に含まれる座標を現在地から近い順に並べ替えます。
・（「items」に含まれる座標は、y軸の座標数が小さい順に並んでいます。）この処理を「sort_by!」「calc_route」「size」メソッドを使って行います。
{と}で囲まれたコードを使って配列に含まれる要素を並べ替え、配列自身を変更するメソッドです。({と}で囲まれた部分を「ブロック」と呼びます)
配列.sort_by!{|ブロックパラメータ| 繰り返したい処理 }sort by!

ブロックパラメータに、配列に含まれる各要素を入れながら繰り返したい処
理を実行し戻り値を集めます。集めた戻り値を「<=>」演算子で比較して、小さい順に要素を並べ替えます。
例）animals = [“mouse”, “cat”, “elephant”, “lion”]
animals.sort_by! {|animal| animal.size }⇒animails の要素が次のように「文字数の小さい順」に並べ替えられます。
[“cat”, “lion”, “mouse”, “elephant”]※文字列(“と”で囲まれたもの)に対して size メソッドを実行すると、その文字数を返します。
スモウルビー甲子園で用意した 2 点間の最短経路を検索するメソッドです。
（下のブロックと同じ内容です。）

calc_route

引数として始点の座標（src）、終点の座標（dst）、通らない座標の配列（except_cells）を指定できます。
なお、引数を省略した場合は、始点：現在地、終点：ゴール、通らない座標：未
設定で経路検索します。
calc_route(src: [始点の座標], dst: [終点の座標], except_cells: [通らない座標の配列])例）
calc_route(src: [9,9], dst: [7,7], except_cells: [[9,7]])⇒次のような経路順の座標配列が返されます。
[[9, 9], [9, 8], [8, 8], [8, 7], [7, 7]]34配列の要素の数を返すメソッドです。
配列.sizesize

例）route = [[11,8],[11,7],[10,7],[9,7],[8,7],[7,7]] route.size⇒座標の個数6が返されます。

・上で説明した「sort_by!」「calc_route」「size」メソッドを次のように組み合わせます。

[ブロックの処理内容]
・「items」に含まれる加点アイテムの各座標を「item」というブロックパラメータに入れてブロックを繰り返し実行する（加点アイテムの座標が5つであれば5回繰り返す）。
・ブロックの内容は、以下の座標を設定し calc_route を実行すること 始点：現在地
終点：「items」に含まれる各加点アイテムの座標通らない座標：未設定
・calc_route の結果(現在地から各加点アイテムまでの座標の数)の小さい順に「items」の中の座標を並べ替える
・並べ替えの結果、一番近い加点アイテムの座標が「items」の最初の要素にあるので、その要素を取り出して、target という変数に入れます。

first メソッドは、配列の最初の要素を返します。
items.first では、「items」の先頭の座標を返します。
・一番近い加点アイテムを取得すると、次に近い加点アイテムを目指して移動する必要があります。
この処理を正しく行うためには、マップ情報を更新し、「items」の情報を更新していく必要があります
このため、この一連のブロックの先頭にマップ情報の取得ブロックを組み込んでおきます。
⇒これにより、ターンのたびに、まずは現在地周辺のマップ情報を取得し、「items」の情報が更新されます。
⇒ただし、情報が更新されるのは現在地周辺（5マス×5マス）だけのため、この範囲外で対戦相手が加点アイテムを取得した情報は取得できません。

・最後に「target」を終点に設定して移動するブロックを組み込んで完成です。

※「便利なメソッド」の中の「座標を自分に近い順に並べ替える」ブロック
Ruby言語の命令を手入力しなければなりません。打ち間違いが起きやすいので、ゆっくり気を付けながら入力してください。

35

（4）ターン数を管理する<ブロックの例>

・1ターンの行動として、AIプログラムの「◆ずっと を繰り返す」の中のプログラムが１回実行されます。よって、「◆ずっと を繰り返す」の実行回数がターン数と同じ数になります。
このことから、「◆ずっと を繰り返す」が実行された回数を変数に入れることによりターン数を管理することができます。
・最初に「◆ずっと を繰り返す」より前に「turn = 1」を設定します。
（これで最初のプログラム実行は「turn = 1」としてスタートします。）

・次に「ターンを終了する」の前に「turn = turn + 1」を組み込みます。
（ターン終了時に「turn」に1を加えることにより、ターン数が加算されていきます。）

36

・変数「turn」を参照することで現在のターン数がわかりますので、以下のようなブロックを作ることで、ターンごとの行動を変えることができます。

※「便利なメソッド」の中の「ターン数の管理」「もし～ならば」ブロックがたくさん出てきますので、入れ間違えないように注意してください。
最初に紙に書いておくと良いかもしれません。
（5）ダイナマイトを置く(例:プレイヤーが壊せる壁の隣のマスに来たらダイナマイトを置く)<ブロックの例>
・プレイヤーが壊せる壁の西隣のマスに来た場合にダイナマイトを置くブロック例<ブロックの例>
・プレイヤーが壊せる壁の西隣のマスに来た場合にダイナマイトを置くブロック例「プレイヤーが壊せる壁の西隣のマスに来た」という状況は「プレイヤーの東側の隣のマスが壊せる壁になった」という状況であると読みかえることができます。
「プレイヤーの東側の隣のマス」の座標を調べるためには、プレイヤーの座標を調べる必要があります。
「プレイヤーの座標」は[player_x, player_y]と表すことができます。（5.AI プログラムの作り方(3)スモウルビー甲子園メソッドの種類と使い方⑪キャラクタのx座標、y座標 参照）「プレイヤーの東側の隣のマス」の座標は、x座標が1多く、y座標は同じなので、[player_x+1,player_y]と表すことができます。
「プレイヤーの東側の隣のマスが壊せる壁になった」という条件は、「複数ある「壊せる壁」の座標のうち、「プレイヤーの東側の隣のマス」の座標と一致するものがある」と言い換えることができます。
Ruby には、複数のものの中から一致するものを見つけることができる「include?」というメソッドがあります。このメソッドを使います。
変数「kowaseru」を作り、壊せる壁の座標をセットします。

変数「p_east」を作り、プレイヤーの東側の隣のマスの座標をセットします。

37

式ブロックに以下の式を入力します。
kowaseru.include?(p_east)「もし ならば」のブロックに式ブロックを入れます。

これらのブロックを順番につなぎます。

「もし ならば」のブロックの中に「ダイナマイトを置く」のブロックをあてはめたら完成です。

プレイヤーが壊せる壁の北隣や南隣、東隣に来た場合のブロックはどうすれば作れるか、皆さん考えてみてください。

38

7. 作戦の考え方（１）やり方1▶やりたいことを書き出す▶実装するためのプログラムを考える▶ゲームで試す▶改良する
例）
・やりたいこと「加点アイテムを取ってからゴールに向かう」
・実装するためのプログラムを考える「最初に全マップの情報を取得する」「加点アイテムの座標を確認する」「加点アイテムの座標を近い順に並べ替える」「一番近い加点アイテムに向かう」「加点アイテムがなくなったらゴールに向かう」
・ゲームで試す「加点アイテムを全部とっているとゴールできないなあ（50ターン経過してしまう）」
・改良する「草薙剣の獲得を優先しよう！」「30ターン経過したらゴールに向かおう！」 など（2）やり方2▶サンプルプログラムを流用する▶サンプルプログラムでゲームを試す▶改良したい点を考える▶実装方法を考える▶ゲームで試す※サンプルプログラム3は少し難しいプログラムですが、内容を理解し、自分のプログラムに活用することにチャレンジしてみてください。
（３）優勝者からのアドバイス （第1回大会優勝者「高田.exe」さん）※第1回大会からはルールが変わっていますが、全体の考え方を参考にしてください。
・「見る」「考える」「判断する」が重要39

・「見る」＝「調べる」、自分だけでなく相手も見る・「考える」＝「計算する・比較する」「自分と加点アイテムとの距離」「相手と加点アイテムとの距離」⇒相手の方が近い場合は、その加点アイテムは相手がとるだろう！
⇒だったらゴールに向かった方が有利？
⇒ついでにゴール前にトラップアイテムを置いて相手の減点を狙おう！
40

・「判断する」＝「見る」、「考える」の結果に応じて⇒アイテムを妥協⇒目的地を判断⇒爆弾をどこに置くか判断

41

42

8. その他の説明（１）スモウルビー甲子園の構成
・スモウルビー甲子園は、Cドライブ上の「koshien2024」フォルダに保存されています。

（2）マップエディタの使い方
・マップエディタを使って、オリジナルのマップを作ることができます。

43

・マップエディタで使用するファイルは以下に格納されています。
このファイルを game_server 上のファイルと置き換えることで作成したマップでゲームを試せます。

※編集したいマップファイルをここに貼り付けます。
・マップエディタの使用方法は次のとおりです。

①

②

①

①マップ描画エリア②マップチップ選択エリア③アイテム選択エリア②③[操作方法]
・マップチップ選択エリアから配置したいマップチップを選択（右クリック）し、マップ描画上の配置したい
場所に右クリックすると、新しいマップチップが配置されます。
③
・同様にアイテム選択エリアから配置したいアイテムを選択（右クリック）し、マップ描画上の配置したい場
所に右クリックすると、新しいアイテムが配置されます。
[編集したマップの保存方法等]
・Escキーを押すことにより、データが保存され、マップエディタが終了します。
・ファイルは koshien2024 > map_editor > data に保存されています。
・間違って編集しないよう保存したファイルはどこか別の場所に移して置きましょう。
（koshien2024 > map_editor > data に新しくフォルダを作って保存しておくと便利です。）

44

（3）ログの確認方法
・ログファイルを確認することができます。

・また、pメソッドを組み込んでおくことにより、変数の中身を確認することもできます。
（ログファイルに変数の中身も記録されます。）

・ main_debug からゲームを起動することで、コマンドプロンプトを見ながらゲームを試すこともできます。

45

（4）エラーの調べ方(4-1)ログファイルの見方
プレイヤー１の場合は player1.log、プレイヤー２の場合は player2.log を見てください。
その中に「エラーが発生しました」という行があります。その次の行からエラー内容が記録されています。
プログラムのどの部分でエラーが発生したか調べるには、ログの中の「自分が作成した AI プログ
ラムのファイル名」を探し、その右隣の数字を見てください。それが Ruby 画面における行番号を表しています。以下の例では「sample.rb」という AI プログラムの Ruby 画面の 13行目で発生していることが記録されています。Ruby 画面の 13 行目を調べて、ブロック画面のどの位置か確認してください。
（例）E, [2019-11-15T19:42:45.036778 #5204] ERROR -- : エラーが発生しました (NameError)
undefined local variable or method ‘route_target’ for#<Smalruby::Console:0x41973c0> E, [2019-11-15T19:42:45.037762 #5204] ERROR -- :C:/koshien2024/smalruby/programs/ sample.rb:13:in 'block (2 levels) in <main>'(4-2)タイムアウトする（その１）【症状】タイムアウトする【ログファイル】「(NameError) undefined local variable or method ◯◯」と記録されている
E, [2019-11-15T19:42:45.036778 #5204] ERROR -- : エラーが発生しました (NameError)
undefined local variable or method 'route_target' for#<Smalruby::Console:0x41973c0> E, [2019-11-15T19:42:45.037762 #5204] ERROR -- :C:/koshien2024/smalruby/programs/ sample.rb:13:in 'block (2 levels) in <main>’【原因】変数名の入力ミスの可能性があります 。
【対応策】変数名の入力ミスがあれば修正してください。
(4-3)タイムアウトする（その2）【症状】タイムアウトする【ログファイル】「(ArgumentError) wrong number of arguments (0 for 2)」「◯◯ in 'move_to'」と記録されている
E, [2019-11-15T20:41:44.862595 #7988] ERROR -- : エラーが発生しました(ArgumentError) wrong number of arguments (0 for 2)
E, [2019-11-15T20:41:44.862595 #7988] ERROR -- :C:/koshien2024/src/lib/ai_lib.rb:197:in 'move_to' E, [2019-11-15T20:41:44.862595#7988] ERROR -- : C:/koshien2024/src/lib/ai_lib.rb:37:in 'move_to' E, [2019-1115T20:41:44.862595 #7988] ERROR -- : C:/koshien2024/smalruby/programs/
sample.rb:74:in 'block (2 levels) in <main>'【原因】「移動する」の座標が正しくない可能性があります。
【対応策】加点アイテムを取ったあとに発生することが多いです。「マップ情報を取得」がきちんとできているか確認してください。

46

(4-4)キャラクタが動かない【症状】ターンは進行するが、キャラクタが動かない【ログファイル】「移動に失敗しました message=移動できない座標です」と記録されている
D, [2019-11-15T20:36:33.630178 #11400] DEBUG -- : moveTo を実行します 引数=[10, 5]
E, [2019-11-15T20:36:33.643144 #11400] ERROR -- : 移動に失敗しました message=移動できない座標です【原因】移動することができないマス（壁など）に移動しようとしています。
【対応策】「マップ情報を取得」を実行している範囲とそうでない範囲があると、最短経路の検索の結果に壁を通る経路が含まれてしまって発生することがあります。「マップ情報を取得」がきちんとできているか確認してください。
(4-5)AIが停止しました【症状】「AIが停止しました」と表示され START ボタンが表示されない【ログファイル】「AIライブラリを読み込みました」の直後に「エラーが発生しました」が記録されている
I, [2019-11-15T19:34:49.821730 #19652] INFO -- : --- AIライブラリを読み込みました --E, [2019-11-15T19:34:51.422715 #19652] ERROR -- : エラーが発生しました(NoMethodError) undefined method 'set_name' for#<Smalruby::Console:0x3fe7720>【原因】テンプレートに含まれるブロックのどれかが無くなっている可能性があります。
【対応策】無くなっているブロックを追加してください。

47

9. 参考（例題１）
1. 最初ににマップ全体の「マップ情報の取得」を実施
2. マップ探索が終わったら、全ての加点アイテムの座標を調べる
3. 一番近い加点アイテムから順番に取りに行く。（加点アイテムを取ったら次の加点アイテムに向かう）

4. 30ターンになったらゴールに向かう※注意：加点アイテムを取った後に移動先を見失わないように！

（例題2）
1. 最初ににマップ全体の「マップ情報の取得」を実施
2. マップ探索が終わったら、・草薙剣の座標を調べる
・シロイルカの座標を調べる
・爆弾とトラバサミの座標を調べる
3. 爆弾とトラバサミを避けながら草薙剣を取りに行く 。
条件を満たすルートがない場合は避けずに取りに行く。
4. 草薙剣がなくなったら、爆弾とトラバサミを避けながらシロイルカを取りに行く。
条件を満たすルートがない場合は避けずに取りに行く。

5. シロイルカもなくなったら、ゴールに向かう※注意：加点アイテムを取った後に移動先を見失わないように！

48