Pythonでソリティアのクロンダイク開発Part2

こんにちは、にわこまです。

今回は、場札の列(ColumnDeck)と組札(MarkDeck)を作成します。場札の列と組札はカードの重ね方の条件がことなるため気を付けます。

 

誤字脱字や何かございましたら、ご連絡お願い致します。

 

 

スポンサードサーチ


ソリティアのクロンダイク開発Part2

今回は、場札の列(ColumnDeck)と組札(MarkDeck)を作成します。ゆえに、まずその2つのカードを重ねる条件やできることを確認します。

 

場札の列(ColumnDeck)

場札の列とは、以下のような7つの列です。初期状態として左から1枚、2枚、3枚、4枚 、5枚、6枚、7枚とカードを裏向きで重ねて、1番上のカードは表にします。

場札の列にカードを重ねる場合は2つ条件があります。

1.大きい数字から小さい数字の順
2.マークの色が黒と赤交互

空列にカードを移動させる場合は、1つ条件があります。

1.空列にカードを移動させることができるカードは、13のカードまたは13から始まる続きカード

 

組札(MarkDeck)

組札とは、同一のマークのカードを集めるところです。

組札にカード重ねる場合は、2つ条件があります。

1.同一のマークである。(スペードの組札には、スペードのカードしか重ねられない)
2.小さい数字から大きい数字(1から始まり、13で終わる)

 

 

ColumnDeckの作成

CulomnDeckは、場札の列を表現するためのクラスです。

 

場札の列に必要なデータを考えます。

 

場札の列のデータ

・リスト

場札の列に必要なデータはリストだけと考えました。リストは、カードを格納するために使います。

必要なデータよりも必要な機能が多くあります。

 

ColumnDeckクラスを紹介します。以下のコードをklondike.pyの1番下の行に追記します。

class ColumnDeck:
    # Check! : indexの数字が若いほど山札の上に近い
    def __init__(self):
        self.colDeck = []

    # 初期設定用
    def setInitCard(self, card):
        self.colDeck.append(card)

    # CardをSet出来るか確認
    def confSetCard(self, card, deck=None):
        if(deck == None):
            deck = self.colDeck[:]
        if(len(deck) == 0 and (card.number == 13) and card.fab):
            return True
        elif(len(deck) != 0 and card.fab):
            obj = deck[-1]
            if(obj.color != card.color and (obj.number - card.number) == 1 and obj.fab):
                return True
            else:
                print("色、数字、表裏が正しくありません。")
                print("移動先 : ", obj.getData())
                print("移動元 : ", card.getData())
                return False
        else:
            print("Error : ColumnDeck")
            print(card.getData())
            return False

    # 複数のCardをSetできるか確認
    def confSetCards(self, cards):
        tmpcolDeck = self.colDeck[:]
        for card in cards:
            if(self.confSetCard(card, tmpcolDeck)):
                tmpcolDeck.append(card)
            else:
                return False
        return True

    # 初期設定以外
    def setCard(self, card):
        self.colDeck.append(card)

    def setCards(self, cards):
        for card in cards:
            self.setCard(card)

    def getCards(self, index):
        # index以降のオブジェクトをlistで返却
        if(len(self.colDeck) != 0):
            cards = self.colDeck[index:]
            del self.colDeck[index:]
            if(len(self.colDeck) != 0):
                self.colDeck[-1].fab = True
            return cards
        print("列にカードがないため、選択することができません。(ColumnDeck : getCards)")
        return []

    def getTempCards(self, index):
        if(len(self.colDeck) > index):
            cards = self.colDeck[index:]
            for card in cards:
                if(card.fab == False):
                    return None
            return cards
        print("列にカードがないため、選択することができません。(ColumnDeck : getTempCards)")
        return None

 

コードの解説

3、4行目は「__init__」によって、インスタンス化を行っています。つまり、ColumnDeckにカードを格納するためのリストを設定しています。

 

7、8行目の「setInitCard()」は、初期設定用にカードを格納するための関数です。初期設定用であるため、条件を無視して格納します。

 

11行目~28行目の「setConfCard()」は、一時的に取得したカードを格納できるか確認するための関数です。

引数の「card」は、一時的に取得したカードを代入します。もう1つの引数の「deck」は、確認したいdeck(カードのリスト)を指定します。

引数の「deck」は、デフォルトをNoneとしています。Noneの場合は、self.colDeckで確認を行います。

 

31行目~38行目の「setConfCards()」は、一時的に取得したカードたちを格納できるか確認するための関数です。「serConfCard()」のカード複数枚バージョンです。主に、続きカードを格納できるか確認します。

引数の「cards」は、カードのリストを指定します。

 

41、42行目の「setCard()」は、引数のカードをself.colDeckに格納するための関数です。setConfCardを行った後に実行するため、条件を無視して格納します。

引数の「card」は、1枚のカードを指定します。

 

44行目~46行目の「setCards()」は、引数のカードたちをself.colDeckに格納するための関数です。setConfCardsを行った後に実行するため、条件を無視して格納します。

引数の「cards」は、カードのリストを指定します。

 

48行目~57行目の「getCards()」は、カードを取得するための関数です。self.colDeckから取得するカードを削除し、取得するカードの状態を表(True)にします。

取得するカードは1枚でも、リストの形で返却します。また、取得できるカードが1枚もない場合は、空のリストを返却します。

引数の「index」は、取得したいカードのインデックスを指定します。

 

59行目~67行目の「getTempCards()」は、一時的にカードを取得するための関数です。self.colDeckから取得するカードのコピーを作成し、カードの状態が全て表(True)であるか確認します。

取得するカードが1枚だけであっても、リストの形で返却します。また、取得するカードが1枚もない場合、または取得するカードに裏の状態であるカードが存在する場合は、Noneを返却します。

 

 

スポンサードサーチ


MarkDeckの作成

MarkDeckは、組札を表現するクラスです。

 

組札に必要なデータを考えます。

 

組札のデータ

・リスト
・マーク
・組札の1番上のカード

これら3つのデータが必要であると考えました。

リストは、カードを格納するために使います。マークはどの組札なのか識別するために使います。組札の1番上のカードは、分かりやすくするために必要であると考えたため加えました。組札の1番上のカードがなくても作成できます。

 

MarkDeckクラスを紹介します。以下のコードをklondike.pyの1番下の行に追記します。

class MarkDeck:
    def __init__(self, mark):
        self.markDeck = []
        self.mark = mark
        self.topCard = None

    def confSetCard(self, card):
        if(self.mark == card.mark):
            if( (len(self.markDeck) + 1) == card.number ):
                return True
            else:
                print("数字が異なります。")
                print("組札に移動できる数字 : ", len(self.markDeck)+1)
                print("cardの数字 : ", card.number)
                return False
        else:
            print("マークが異なります。")
            print("組札のマーク : ", self.mark)
            print("cardのマーク : ", card.mark)
            return False

    def setCard(self, card):
        self.markDeck.append(card)
        self.topCard = card

    def getTempCard(self):
        if(len(self.markDeck) != 0):
            card = self.markDeck[-1]
            return card
        return None

    def getCard(self):
        if(len(self.markDeck) != 0):
            card = self.markDeck.pop(-1)
            if(self.topCard.number == 1):
                self.topCard = None
            else:
                self.topCard = self.markDeck[-1]
            return card
        return None

 

コードの解説

2行目~5行目は、「__init__」によってインスタンス化を行っています。リスト(self.markDeck)、マーク(self.mark)、組札の1番上のカード(self.topCard)を設定しています。

 

7行目~20行目の「confSetCard()」は、カードを重ねられるか確認するための関数です。マークが同一か、数字は続いているかを確認しています。

 

22行目~24行目の「setCard()」は、指定したカードをself.markDeckに格納するための関数です。また、self.topCardを更新します。

confSetCard()を行ってから実行するため、条件の判定は行いません。

 

26行目~30行目の「getTempCard()」は、一時的にカードを取得するための関数です。取得するカードは、self.markDeckから削除しません。self.markDeckに存在しない場合は、Noneを返します。

 

32行目~40行目の「getCard()」は、カードを取得するための関数です。取得するカードをself.markDeckから削除します。また、self.topCardを更新します。カードがない場合は、Noneを返します。

 

 

まとめ

今回は、場札の列(ColumnDeck)と組札(MarkDeck)を作成しました。以上で、ソリティアのクロンダイク開発におけるクラスの作成は終了です。

 

次回は、コマンドプロンプトに表示するために必要な関数を作成します。具体的には、山札と組札、場札の列、コマンドを表示するための関数を作成します。

 

まだまだ実際にコードを実行してないため、完成形がイメージできないかもしれませんが、表示関係の関数を作成すれば、完成形が見えてきます。

 

 

最後までお読み頂きありがとうございます。


スポンサードサーチ