2章 情報の読み取りと条件分岐
入門編の第2部3・4章(ステージ3)に対応します。
CHaserのしくみの要点
- 自分の周りの9マス(自分自身と、上下左右・斜めの8マス)の情報は、自分の番が来たときに
get_ready()が返します。この9マス分の情報を、周辺情報(map_info)と呼びます。 - 周辺情報は、その瞬間の情報です。自分や相手が動けば、状況は変わります。判断のたびに、最新の情報を取得し直すのが基本です(4章)。
- チュートリアルのPython画面では、
map_infoは自動で更新されます。CPUのいないステージなら、開始時点の周辺情報が最初からmap_infoに入っていて、walkなどの行動のあとにも新しくなります(0章)。本番では、map_info = player.get_ready()で自分で受け取ります。 - マスの中身は、
Floor(何もない)・Block(ブロック)・Item(アイテム)・Enemy(相手)の4種類です。
周辺情報から、方角を指定して取り出す
map_infoから、方角を指定して1つのマスの情報を取り出せます。
map_info[Up] # 上のマス → Block (上はブロック)
map_info[Down] # 下のマス → Item (下にアイテムあり)
map_info[Left] # 左のマス → Floor (左は空き)
map_info[DownLeft] # 左下のマス → Enemy (左下に相手)
方角の名前は、次の3×3の並びに対応しています。Centerは、自分自身のいるマスです。
UpLeft |
Up |
UpRight |
Left |
Center |
Right |
DownLeft |
Down |
DownRight |
Blocklyで「周辺情報の、上の方角を選ぶ」ドロップダウンを使っていたところが、Pythonでは[Up]という角かっこの指定に対応します。
条件を式にする
「上がブロックなら」という条件は、==で比較する式にします。
map_info[Up] == Block # 上がブロックなら True、そうでなければ False
map_info[Up] != Block # 上がブロックでないなら True
==(等しい)と!=(等しくない)は、どちらも結果がTrueかFalseになる式です。この式をifの条件に置けば、Blocklyの「もし〔自分の上のマスがBlockなら〕」と同じ判断ができます。
if〜else(ステージ3-1)
ステージ3-1のマップとクリア条件
| クリア条件 | 内容 |
|---|---|
| アイテム | 1個ゲットする |
| ターン数 | 100ターン以内 |
黄色の枠が自分(Cool)のスタート位置です。すべての条件を同時に満たすとクリアです。
while True:
map_info = get_ready()
if map_info[Up] == Block:
walk(Right)
else:
walk(Up)
「上がブロックなら右へ、そうでなければ上へ」進むプログラムです。while True:の中にifが入っている、2段のインデント構造が、入門編の「ずっと繰り返す」ブロックの中に「もし〜なら」ブロックが入っている形に対応します。
if〜elif〜else(ステージ3-2)
ステージ3-2のマップとクリア条件
| クリア条件 | 内容 |
|---|---|
| アイテム | 6個ゲットする |
| ターン数 | 100ターン以内 |
黄色の枠が自分(Cool)のスタート位置です。すべての条件を同時に満たすとクリアです。
条件が3つ以上あるときは、elifを使います。
while True:
map_info = get_ready()
if map_info[Left] == Item:
walk(Left)
elif map_info[Up] == Block:
walk(Right)
else:
walk(Up)
if・elif・elseは、上から順に調べられ、最初に成り立ったところだけが実行されます。だから、優先したい条件ほど上に書きます。たとえば、上の2つの条件を入れ替えると、「左にアイテムがあり、かつ上もブロック」という状況で、左のアイテムではなく、右へ逃げてしまいます。
注意したいこと
- 方角の名前を、クォートで囲む:
map_info["Up"]のように書くとエラーになります。Up・Blockなどは、文字列ではなく、あらかじめ用意された名前です。 - 角かっこと丸かっこを間違える:
map_info[Up]は角かっこ、walk(Up)は丸かっこです。 elifをelse ifやelseifと書く:Pythonでは、elifという1つの単語です。elseに条件を書く:elseは「それ以外すべて」を表すので、else:のように、条件なしでコロンだけを付けます。ifとelif・elseのインデントを揃え忘れる:同じまとまりのif・elif・elseは、同じ深さで揃えます。- 取得した情報を、使い回してしまう:
map_infoは、取得したその瞬間の情報です。ずっと同じmap_infoで判断し続けると、状況が変わっても気づけません(4章)。
演習問題
- 「右にアイテムがあれば右へ、そうでなく下がブロックなら上へ、それ以外は下へ」という判断を、
if〜elif〜elseで書いてみましょう。 - 上の3-2のコードで、1行目の条件と2行目の条件を入れ替えると、どんな場合に結果が変わりますか。