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)を作成しました。以上で、ソリティアのクロンダイク開発におけるクラスの作成は終了です。
次回は、コマンドプロンプトに表示するために必要な関数を作成します。具体的には、山札と組札、場札の列、コマンドを表示するための関数を作成します。
まだまだ実際にコードを実行してないため、完成形がイメージできないかもしれませんが、表示関係の関数を作成すれば、完成形が見えてきます。
最後までお読み頂きありがとうございます。
スポンサードサーチ