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

Pythonでソリティアのクロンダイク開発Part3のサムネイル

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

今回は、コマンドプロンプトに表示するための関数を紹介します。今までは「作成」だけでしたが、表示関係の関数であるため動きをみることができます。完成形をイメージすることができるのではないでしょうか。

 

誤字脱字など何かございましたら、ご連絡お願い致します。 TwitterのDMでも承ります。

 

 

スポンサードサーチ


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

今回は、コマンドプロンプトに表示する関数を作成します。具体的には、山札、組札、場札の列、コマンドです。

 

完成形を以下に示します。

今回開発する表示関係の関数の実行画像。完成形の画像

 

また、上記の関数以外にいくつか作成します。具体的には、選択されたカードを表示する関数、座標の判定を行う関数、勝利判定を行う関数です。

 

 

山札と組札を表示する関数の作成

山札と組札を表示する関数(printDeck)を作成します。この関数は大きく分けて、山札や組札の名前を表示する部分と、実際のデータを表示する部分に分けられます。

 

関数printDeckのソースコードです。klondike.pyの1番下の行に追記します。

# DeckとMarkDeckの表示設定
def printDeck(deck, markDecks):
    # kinds of decks
    print("")
    print(" +------+             +------+------+------+------+")
    print(" | Deck |             |   S  |   H  |   C  |   D  |")
    print(" +------+             +------+------+------+------+")
    print(" | ", end="")
    man = " "*4
    if(type(deck.frontCard) == Card):
        man = deck.frontCard.getMAN()
    print("{0} |             ".format(man), end="")
    #print("| ---- |             | ---- | ---- | ---- | ---- |")
    print("| ", end="")
    for markDeck in markDecks.values():
        man = " "*4
        card = markDeck.topCard
        if(type(card) == Card):
            man = card.getMAN()
        print("{0} | ".format(man), end="")
    print("")
    #print("| ---- |             | ---- | ---- | ---- | ---- |")
    print(" +------+             +------+------+------+------+")
    print("")

 

コードの解説

引数は、山札(Deck)と組札の辞書(markDecks)です。辞書は、スペード、ハート、クラブ、ダイヤの順番で固定します。

 

5、6、7行目が、山札と組札の名前を表示する処理を行っています。

 

8行目~24行目が、実際のデータを表示する処理を行っています。表示をきれいにするための空白などの説明は省きます。

10、11、12行目で、山札の実際のデータを表示する処理を行っています。

山札(Deckクラス)の引いたカード(self.frontCard)があるかないかの確認を行い、ある場合はマークと数字を指定の形式で変数に代入します。ない場合は、半角の空白を4つ代入します。

 

15行目~20行目で、組札の実際のデータを表示する処理を行っています。

組札(MarkDeckクラス)の1番上のカード(self.topCard)があるかないかの確認を行い、ある場合はマークと数字を指定の形式で変数に代入します。ない場合は、半角の空白を4つ代入します。

 

 

動作確認

正しく表示されるか確認するため、動作確認を行います。コマンドプロンプトを開き、「python」と入力し、エンターを押してください。「>>>」が出力されれば、起動しています。

C:\Users\Name\python3\blog_python\solitaire>python
Python 3.7.0b3 (v3.7.0b3:4e7efa9c6f, Mar 29 2018, 18:42:04) [MSC v.1913 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

 

次に、klondikeから必要なクラスと関数をインポートします。

>>> from klondike import Card, Deck, MarkDeck
>>> from klondike import printDeck
>>>

 

さらに、山札と組札のオブジェクトを作成します。markDeckDictは、必ず以下の順番で代入します。

>>> mydeck = Deck()
>>> SDeck = MarkDeck("Spade")
>>> HDeck = MarkDeck("Heart")
>>> CDeck = MarkDeck("Club")
>>> DDeck = MarkDeck("Diamond")
>>> markDeckDict = {"Spade":SDeck, "Heart":HDeck, "Club":CDeck, "Diamond":DDeck}
>>>

 

実際に表示させてみます。以下のように表示されます。

>>> printDeck(mydeck, markDeckDict)

 +------+             +------+------+------+------+
 | Deck |             |   S  |   H  |   C  |   D  |
 +------+             +------+------+------+------+
 |      |             |      |      |      |      |
 +------+             +------+------+------+------+

>>>

 

DeckクラスのturnCardや、数字が1のカードオブジェクトを作成して動作を確認してみます。

>>> mydeck.turnCard()
>>> printDeck(mydeck, markDeckDict)

 +------+             +------+------+------+------+
 | Deck |             |   S  |   H  |   C  |   D  |
 +------+             +------+------+------+------+
 | S_13 |             |      |      |      |      |
 +------+             +------+------+------+------+

>>>
>>> s_01 = Card("Spade", 1)
>>> SDeck.setCard(s_01)
>>> printDeck(mydeck, markDeckDict)

 +------+             +------+------+------+------+
 | Deck |             |   S  |   H  |   C  |   D  |
 +------+             +------+------+------+------+
 | S_13 |             | S__1 |      |      |      |
 +------+             +------+------+------+------+

>>>

 

以上で動作確認は完了です。

 

 

スポンサードサーチ


場札の列を表示する関数の作成

場札の列を表示する関数(printHeader、printColDeck)を作成します。この関数は、大きく分けて「Col1」、「Col2」など、何列目かを示す名前と実際の場札の列のカードを表示する部分に分けられます。

 

関数printHeaderと関数printColDeckのソースコードです。以下コードをklondike.pyの1番下の行に追記します。

# カラム見出しの表示設定
def printHeader():
    # header
    colList = ["Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7"]
    print(" +------+------+------+------+------+------+------+")
    print(" | ", end="")
    for col in colList:
        print(col, "| ", end="")
    print("")
    print(" ==================================================")

# 出力(場札)
def printColDeck(decklist):
    printHeader()
    # data
    leng = 0
    for obj in decklist:
        if(leng < len(obj.colDeck)):
            leng = len(obj.colDeck)
    #print(leng)
    #        1   2   3   4   5   6   7   8   9   10
    llist = [[], [], [], [], [], [], [], [], [], [],
             [], [], [], [], [], [], [], [], []]
    for obj in decklist:
        objleng = len(obj.colDeck)
        for i in range(objleng):
            card = obj.colDeck[i]
            if(card.fab):
                s = card.mark[0] + "_" + str(card.number)
                if(card.number <= 9):
                    s = card.mark[0] + "_" + "_" + str(card.number)
                llist[i].append(s)
            else:
                llist[i].append("Back")
        for i in range(objleng, leng):
            llist[i].append('    ')

    for i in range(leng):
        print(" | ", end="")
        for card in llist[i]:
            print(card, "| ", end="")
        if(i <= 9):
            print("  {0} ".format(i+1))
        else:
            print(" {0} ".format(i+1))
        print(" +------+------+------+------+------+------+------+")
    print("")

 

コードの解説

2行目~10行目の「printHeader()」は、何行目かを示す名前を表示するための関数です。

4行目の「colList」は、7列分の名前が代入されているリストです。

7、8行目で実際に名前を表示しています。

 

13行目~47行目の「printColDeck()」は、実際の場札の列のカードを表示するための関数です。

引数の「decklist」は、1列目から7列目の順で代入します。

14行目の「printHeader()」は、先ほど定義した関数です。カードを表示する前に表示したいため、ここで使用します。

 

16行目~19行目の「leng」は、最大の行数を確認するための変数です。この変数は、余分な行を表示させないために使います。

 

22、23行目の「llist」は、リストの中のリストが1行を表しています。最大で19行分のリストが代入されています。

 

24行目~36行目はllistの中のリストに、表示する文字列を追加しています。

・カードがあり、表の状態である場合はマークと数字を指定の形式で追加します。

・カードがあり、裏の状態である場合は「Back」という文字列を追加します。

・カードがない場合は、半角空白4つを追加します。

 

38行目~47行目は、実際にカードとカード指定用の数字を表示しています。

 

 

動作確認

正しく表示されるか確認するため、動作確認を行います。コマンドプロンプトを開き、「python」と入力し、エンターを押してください。「>>>」が出力されれば、起動しています。

C:\Users\Name\python3\blog_python\solitaire>python
Python 3.7.0b3 (v3.7.0b3:4e7efa9c6f, Mar 29 2018, 18:42:04) [MSC v.1913 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

 

次に、klondikeから必要なクラスと関数をインポートします。

>>> from klondike import Card, Deck, ColumnDeck
>>> from klondike import printHeader, printColDeck
>>>

 

さらに、山札と場札の列のオブジェクトを作成します。

>>> mydeck = Deck()
>>> col1 = ColumnDeck()
>>> col2 = ColumnDeck()
>>> col3 = ColumnDeck()
>>> col4 = ColumnDeck()
>>> col5 = ColumnDeck()
>>> col6 = ColumnDeck()
>>> col7 = ColumnDeck()
>>> decklist = [col1, col2, col3, col4, col5, col6, col7]
>>>

 

実際に表示させてみます。ColumnDeckにカードをセットしていないため、以下のように表示されます。

>>> printColDeck(decklist)
 +------+------+------+------+------+------+------+
 | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 |
 ==================================================

>>>

 

初期状態のようにカードをセットして、表示させます。

>>> mydeck.shuffleCards()
>>> for i in range(7):
...     coldeck = decklist[i]
...     for _ in range(i+1):
...             coldeck.setInitCard(mydeck.getInitCard())
...
>>> for coldeck in decklist:
...     coldeck.colDeck[-1].fab = True
...
>>> printColDeck(decklist)
 +------+------+------+------+------+------+------+
 | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 |
 ==================================================
 | S__6 | Back | Back | Back | Back | Back | Back |   1
 +------+------+------+------+------+------+------+
 |      | S__7 | Back | Back | Back | Back | Back |   2
 +------+------+------+------+------+------+------+
 |      |      | C__2 | Back | Back | Back | Back |   3
 +------+------+------+------+------+------+------+
 |      |      |      | H_13 | Back | Back | Back |   4
 +------+------+------+------+------+------+------+
 |      |      |      |      | C_13 | Back | Back |   5
 +------+------+------+------+------+------+------+
 |      |      |      |      |      | D__9 | Back |   6
 +------+------+------+------+------+------+------+
 |      |      |      |      |      |      | S__3 |   7
 +------+------+------+------+------+------+------+

>>>

 

以上で動作確認は完了です。

 

 

コマンドを表示する関数の作成

コマンドを表示する関数(printCmd)を作成します。文字列の長さ同一にして表示します。

 

関数printCmdのソースコードです。以下のコードをklondike.pyの1番下の行に代入します。

# コマンド表示設定
def printCmd():
    cmddict = {
        "山札を見る":"Turn",
        "山札のカードを指定する":"Deck",
        "列のカードを指定する":"Row, Column",
        "組札のカードを指定する":"Spade or Heart or Club or Diamond",
    }
    print(" +" + "-"*24 + "+" + "-"*35 + "+")
    header = ["行動", "コマンド"]
    print(" | " + header[0].center(11, " ") + " | " + header[1].center(29, " ") + " |")
    print(" " + "="*62)
    for k, v in cmddict.items():
        print(" | " + k.ljust(11, ' ') + " | " + v.ljust(33, " ") + " |")
        print(" +" + "-"*24 + "+" + "-"*35 + "+")

 

コードの解説

3行目~8行目の「cmdict」は、コマンドの辞書です。行動内容をkey、コマンドををvalue としています。

・カードを引く場合は、「Turn」と入力します。

・山札のカードを移動するカードとして指定する場合は、「Deck」と入力します。

・場札の列のカードを指定する場合は、「行, 列」という形で入力します。

・組札のカードを指定する場合は、「Spade」、「Heart」、「Club」、「Diamond」の中から指定のマークを入力します。

 

10、11行目は、行動とコマンドというカラム名を表示しています。

 

13行目~15行目は、cmddictの行動内容とコマンドを表示しています。

 

所々ある数字は、微調整の結果です。気にしないでください。

 

 

動作確認

コマンドが正しく表示されるか確認するため、動作確認を行います。コマンドプロンプトを開き、「python」と入力し、エンターを押してください。「>>>」が出力されれば、起動しています。

C:\Users\Name\python3\blog_python\solitaire>python
Python 3.7.0b3 (v3.7.0b3:4e7efa9c6f, Mar 29 2018, 18:42:04) [MSC v.1913 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

 

次に、klondikeから必要な関数をインポートします。

>>> from klondike import printCmd
>>>

 

実際に表示させてみます。以下のように表示されます。

>>> printCmd()
 +------------------------+-----------------------------------+
 |      行動       |              コマンド             |
 ==============================================================
 | 山札を見る         | Turn                              |
 +------------------------+-----------------------------------+
 | 山札のカードを指定する   | Deck                              |
 +------------------------+-----------------------------------+
 | 列のカードを指定する    | Row, Column                       |
 +------------------------+-----------------------------------+
 | 組札のカードを指定する   | Spade or Heart or Club or Diamond |
 +------------------------+-----------------------------------+
>>>

 

以上で動作確認は完了です。

 

 

スポンサードサーチ


その他の関数の作成

その他の関数(printCards、confRowCol、CheckEnd)を作成します。

「printCards」は、選択したカードの一覧を表示するための関数です。

「confRowCol」は、場札の列のカードを数字で指定したときに、エラーが起こらないように確認するための関数です。

「CheckEnd」は、ゲームの勝利(成功)を判定するため関数です。

 

その他の関数のソースコードです。以下のコードをklondike.pyの1番下の行に追記します。

# 選択されたカード一覧
def printCards(cards):
    if(type(cards) in [list, Card]):
        print("Card : ", end="")
        if(type(cards) == list):
            for card in cards:
                print(card.getMAN(), ",", end="")
            print("")
        elif(type(cards) == Card):
            print(cards.getMAN())
    pass

# cmd : row, col判定
def confRowCol(cmd):
    if("," in cmd):
        cmdlist = cmd.split(",")
        confRow = True if cmdlist[0] in rowNumList else False
        confCol = True if cmdlist[1] in colNumList else False
        if(confRow and confCol):
            return True
    return False

# 勝利条件の確認
def CheckEnd(mdd):
    # mdd = markDeckDict
    for v in mdd.values():
        if(len(v.markDeck) == 13): pass
        else: return False
    return True

 

コードの解説

2行目~11行目の「printCards()」は、プレイヤーが選択したカードのマークと数字を指定の形式で表示するための関数です。

引数の「cards」は、カード単体またはカードが複数枚代入されているリストを指定します。そのため3行目のif文では、list型またはCard型であるcardsを処理の対象とします。

さらに、そのifの中でlist型とCard型の処理を分けています。

引数の「cards」が、list型またはCard型でないときは何もしません。

 

14行目~21行目の「confRowCol()」は、場札の列のカードを正しく指定できているかを確認するための関数です。

引数の「cmd」は、先述したコマンドです。

場札の列は、「行, 列」という形で指定します。この形で指定されたかを確認します。

 

24行目~29行目の「CheckEnd()」は、勝利を判定するための関数です。引数の「mdd」は、組札の辞書です。 全ての組札において、1から13があるか確認しています。

 

 

まとめ

今回は、表示関係の関数とその他の関数を作成しました。

表示関係の関数については、動作確認を行ったためこの開発の完成がイメージできたのではないかと思います。

その他の関数については、理解しづらかったもしれませんが、次回使う関数であるため無理に理解しなくて大丈夫です。

 

次回は、実行関数(main)を作成します。完成まで開発を行います。お楽しみに!

 

 

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

何か作って欲しいというリクエストがあれば、TwitterのDMで承ります。


スポンサードサーチ