CHaser解説(Python編)

第2部 Python編

2章 情報の読み取りと条件分岐

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のマップとクリア条件

ステージ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のマップとクリア条件

ステージ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章)。

演習問題

  1. 「右にアイテムがあれば右へ、そうでなく下がブロックなら上へ、それ以外は下へ」という判断を、if〜elif〜elseで書いてみましょう。
  2. 上の3-2のコードで、1行目の条件と2行目の条件を入れ替えると、どんな場合に結果が変わりますか。

YouTubeチャンネル

U-15プロコン舞鶴のYouTubeチャンネルを開設しました。大会の情報などを発信しています。 チャンネルを見る