状態を数値で表現する

フラグ

ドアが閉まっているか開いているかを数値で表現してみよう。

論理型(bool)を使う場合:例えばTrueなら閉まっている、Falseなら開いている

整数型(int)を使う場合:例えば0なら閉まっている、1なら開いている

論理型のあるプログラミング言語で2つの状態だけを扱いたい場合は論理型が都合がよい。C言語のような古い言語では論理型が無いので、整数値で代用するしかない。浮動小数点型、文字列型などは処理が面倒になる。

ドアが閉まっているか開いているかを表す変数を作ってみよう。

is_close = True #閉まっている場合はTrue

door_status = 0 #閉まっている場合は0、開いている場合は1

Bool型を使う場合、Trueがどちらの状態を表すのかを明確にするために変数名を工夫している。"is (the door) close?"なのでTure(Yes)の場合は閉まっていることになる。逆に、Trueの時は開いていることを表現したいならis_openという変数名にすればよい。

int型を使う場合、is_closeだと値が何の時に閉まっているか判らないし、Bool型と混乱する恐れがあるので、状態を表していることを変数名で表現している。ただし、何の値が何を表しているのかはコメントを見ないと判らない。より多くの状態を表現したい場合、辞書型(dict)を使う方法もある。

このような2つの状態を表す変数をフラグ(flag)変数と呼ぶ。

ドアが閉まっているか開いているかを判定して、それぞれに対応するメッセージを表示するプログラムを書いてみよう。

if is_close: print("ドアは閉まっています") else: print("ドアは開いています")

さらに鍵を持っているか持っていないかを表す変数を追加し、ドアが閉まっていて鍵を持っている場合はドアを開けるようにしよう。また、ドアの状態と鍵の有無の組み合わせに応じて適切なメッセージを表示するようにしよう。

複数の状態

ON/OFFのような2つの状態を扱うにはbool型が便利であるが、3つ以上の状態を扱う場合はint型を使うなどの工夫が必要になる。

じゃんけんの手(グー、チョキ、パー)を表す数値を考えよう。対戦者2人の手を表す変数を作り、手の組み合わせで勝敗を判定するプログラムを書こう。

状態に割り当てる数値は例えば0, 1, 2, ...のように連番にしておくのが定番であるが、数値を工夫することで計算処理が簡単になることもある。が、凝りすぎてプログラムが難解になるよりも、誰が見ても簡単で解りやすいプログラムでよい。

どの値がどの状態かを明確にすること。最低限、コメントで書いておく。Pythonには定数はないが、定数扱いする変数に値を代入しておく方法もある(慣例として大文字とアンダースコアのみの名前にしておく)。タプルや辞書を使う方法もある。

カード

トランプ52枚をランダムな順序で山になっている状態を表現してみよう。

まず、トランプを数値で表現する方法を考えてみよう。

山は、順序のある52枚の並びと見なせる。順序を持つデータの集まりを表現するデータ構造は順序リストと呼ばれる。配列は順序リストの基本的な構造の一つである。

配列(リスト)の順序をランダムにするには、randomモジュールのshuffleメソッドを使えばよい。

import random array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] random.shuffle(array) print(array)

自分で実装するならば「入れ替え先をランダムに選んで入れ替える」という作業を先頭から順番に、最低全体の半分まで繰り返せばよい。半分というのもキリが悪いので最初から最後まで繰り返せば良いだろう。

並び順をランダムにするプログラムを自分で書いてみよう。

ゲーム盤

リバーシ(オセロ)の盤の状態を表現してみよう。

リバーシの盤は8×8のマス目状なので2次元配列を使うのがよいだろう。それぞれのマス目の状態は、空きマス、黒、白の3つがある。

あるマス目にコマを置けるか置けないかを判定する方法を考えてみよう。リバーシのルールでは、空きマスであり、かつ相手のコマを自分のコマで挟める場合にのみ置くことができる。

パラメータ

体力、最大体力、攻撃力、防御力、素早さの5つのパラメータ(ステータス値)を表現する方法を考えよう。

とりあえずパラメータごとに変数を用意すればよい。整数型を使うのが普通だろう。それぞれ、最大値と最小値を想定しておく必要もある。次のコードは適当に初期値を設定した例である。

int max_hp = 12 #最大体力 int hp = max_hp #体力、最初は最大体力と同じにしておく int ak = 8 #攻撃力 int df = 6 #防御力 int sp = 12 #素早さ

扱うキャラクターが1体のみならこれでもよいが、複数扱いたく、その数も決まっていない場合は個別に変数を作るわけにもいかない。

複数キャラを扱うためにはどのような実装がよいか考えよう。

配列を使う方法も考えられるが、Pythonはオブジェクト指向言語なのでクラスを使うのがよいだろう。パラメータを扱う様々な処理もクラスに実装すると都合がよい。

class Character: def __init__(self): self.max_hp = 12 #最大体力 self.hp = max_hp #体力、最初は最大体力と同じにしておく self.at = 8 #攻撃力 self.df = 6 #防御力 self.sp = 12 #素早さ

上の例では各パラメータの初期値を固定にしているが、キャラクターを生成する際に、体力は8〜16、攻撃力、防御力、素早さは6〜12の範囲のランダムな値を設定するようにしてみよう。

体力を指定した値だけ増減させるメソッドを追加してみよう。引数に正の値を指定した場合は体力が増え、負の値を指定した場合は体力が減る。ただし、体力は負の値にはならず、最大体力を超えることはない。