Thirteenth floor

【Pythonでボードゲームシミュレーション】DOMEMO その4

2020年6月7日21:06, プログラミング

インスタンスとは

前回はオブジェクトとしてDomemoクラスを作成しました。最後にDomemoクラスをインスタンス化して札がシャッフルされることを確認しました。

ではインスタンスとは何でしょうか? 公式ドキュメントの説明を見てみましょう。

インスタンス

インスタンスオブジェクトが理解できる唯一の操作は、属性の参照です。有効な属性名には (データ属性およびメソッドの) 二種類あります。

ボードゲームによる例え

この説明をみなさん大好きなボードゲームで例えてみましょう。

Python ボードゲームとオブジェクト

上図で、ボードゲームと書いてあるのがドメモそのもののことです。お店で売っている箱に入った状態のドメモです。木の札とルールブックがあります。

これは、Pythonオブジェクトと対応させるとクラスオブジェクトになります。domemo.pyに書いたコードですね。クラスオブジェクトはそれがどのようなゲーム(どんなデータを持っていて、どんな操作が出来るか)を表現しています。

対して、ボードゲームを箱から出してプレイヤーたちが遊んでいる、実際のゲームはどのように表現できるのでしょうか。これを記述するためにあるのがインスタンスオブジェクトです。

ボードゲーム(Pythonオブジェクトのクラス)は同じでも、遊ぶ人たちや時間、場所が異なれば違うゲーム(Pythonオブジェクトのインスタンス)になりますよね。

Pythonでも同じです。同じクラスから作成されるインスタンスは、それぞれがクラスの属性を参照します。前回のシャッフル操作をインスタンスが参照すれば、インスタンス毎に異なる結果が得られるでしょう。

インスタンスを使う利点

インスタンスを使えば、シミュレーションをするときに条件を柔軟に変更できます。

例えば、プレイヤーA, B, C, D, Eが参加するドメモの実験とプレイヤーA, B, C, D, Fが参加するドメモの実験をするとします。これをどちらもコード化してしまうと、プレイヤーが変わるたびに新しいコードが必要になります。

インスタンスを使えば、プレイヤーを登録するメソッドをDomemoクラスに実装し、インスタンスがそのメソッド(属性)を参照するようにするだけでいいのです。あとは、登録するプレイヤーをメソッドに渡せばよいのです。

実際のボードゲームでも、プレイヤーが変わったところで、使うコンポーネント(構成物)は変わりませんよね。

変わらないほうが楽です。

STEP1

利点もわかったところで、domemo.pyへDomemoクラスで使いそうなメソッドを実装していきましょう。

前回作成したdomemo.pyに追記していきます。変更点のみ記載しております。



import random


class Domemo:
    def __init__(self):
        ...
        self.players = ["a", "b", "c", "d", "e"]

    def give_card_for_player(self):
        random.shuffle(self.use_cards)

        for number in [0, 1, 2, 3, 4]:
            self.players[number] = self.use_cards[:4]
            del self.use_cards[:4]

    def give_card_for_field(self):
        ...

    def show_cards_on_field(self):
        ...
        print(self.players)


文法の話

give_card_for_playerメソッドでfor文が登場しております。

詳細な話は公式ドキュメントを確認してもらうとして、for文が何をしているのかざっくりと説明します。

for 変数名 in シーケンス型オブジェクト(リストや文字列):と書くことでfor文になります。

最後にコロンをつけて、for文の中に記載する処理は、必ず半角スペース4文字で字下げします。

処理は単純で以下のようになります。

  • シーケンス型オブジェクトの最初の要素(リスト型であれば0番目、文字列であれば最初の文字)を取り出す。
  • forの後に指定した変数へ取り出した要素を代入する。
  • for文の最後(字下げされている最後の行)まで処理を行う。
  • シーケンス型オブジェクトの2番目の要素を取り出す。
  • forの後に指定した変数へ取り出した要素を代入する。
  • for文の最後(字下げされている最後の行)まで処理を行う。

これを繰り返して、要素が取り出せなくなった時にfor文を抜け、その下の処理に入ります。

give_card_for_playerメソッド

このメソッドはプレイヤーへ札を配る操作を表現しています。

まず、random.shuffleで札をシャッフルします。

次にfor文を使用して、5人のプレイヤーへ札を配ります。

inの後ろに書いてある[0, 1, 2, 3, 4]のリストはself.playersのインデックス(何番目の要素か)を表現しています。

self.playersの0番目を取り出したいときは、for文の中でself.players[number]とすればよいわけです。最初は[0, 1, 2, 3, 4]のうちの0番目の要素がnumber変数へ代入されるためです。

同様に、2番目のループ、3番目のループではそれぞれ1、2がnumber変数へ代入されます。そうするとプレイヤーとしてはbcになります。

また、ここでもdelを使用して取り出した分のself.use_cardsを削除することで、異なるカードをプレイヤーへ配っています。

STEP2

では新しく追加したメソッドの結果を確認しましょう。

前回のようにいちいちPyCharmの下にあるPythonコンソールへ書くのは面倒くさいので、こちらもファイルへ記載しましょう。

main.pyというファイルへ以下を記載します。


from domemo import Domemo

domemo = Domemo()
domemo.give_card_for_field()
domemo.give_card_for_player()
domemo.show_cards_on_field()

書いている処理は前回Pythonコンソールへ打ち込んだものと同じですね。Pythonコンソールは手軽に処理結果を確認出来て便利ですが、何度も繰り返し同じ処理を行うのであればファイルへ記載することをお勧めします。

こちらを実行してみましょう。

main.py上で右クリックをして実行をクリックします。

※実行方法はHelloDomemoで説明しています。

こんな感じで出力されたでしょうか。


[7, 5, 6, 6]
[7, 7, 4, 7]
[[3, 6, 5, 7], [2, 6, 7, 2], [7, 1, 5, 3], [4, 6, 4, 5], [6, 5, 3, 4]]

これでプレイヤーにもカードを配れましたね。

次回のお話

次回は別のクラスオブジェクトを作っていきます。

ボードゲームをするのに必要なのはDomemoだけではありませんね。プレイヤーも必要です。

プレイヤーオブジェクトを作成しましょう!

コメント

コメント投稿ページへ