この記事は広告を含みます。
本日は、上記のリンクの続きになります。
では、さっそく、、、写経の続きを。
Solitaire setup
Create card deck
solitaire.pyにSuite とRankを追加
class Suite: def __init__(self, suite_name, suite_color): self.name = suite_name self.color = suite_color class Rank: def __init__(self, card_name, card_value): self.name = card_name self.value = card_value
Cardクラスにsuiteとrankを追加
class Card(ft.GestureDetector): def __init__(self, solitaire, suite, rank): super().__init__() self.mouse_cursor=ft.MouseCursor.MOVE self.drag_interval=5 self.on_pan_start=self.start_drag self.on_pan_update=self.drag self.on_pan_end=self.drop self.suite=suite self.rank=rank self.face_up=False self.top=None self.left=None self.solitaire = solitaire self.slot = None self.content=ft.Container( width=CARD_WIDTH, height=CARD_HEIGTH, border_radius = ft.border_radius.all(6), content=ft.Image(src="/images/card_back.png"))
card_back.pngはGitHubからダウンロードしました。
数字とマーク設定ですね。
def create_card_deck(self): suites = [ Suite("hearts", "RED"), Suite("diamonds", "RED"), Suite("clubs", "BLACK"), Suite("spades", "BLACK"), ] ranks = [ Rank("Ace", 1), Rank("2", 2), Rank("3", 3), Rank("4", 4), Rank("5", 5), Rank("6", 6), Rank("7", 7), Rank("8", 8), Rank("9", 9), Rank("10", 10), Rank("Jack", 11), Rank("Queen", 12), Rank("King", 13), ] self.cards = [] for suite in suites: for rank in ranks: self.cards.append(Card(solitaire=self, suite=suite, rank=rank))
スロットの作成
本家の公式ページから引用。
レイアウトはこのようです。
def create_slots(self): self.stock = Slot(top=0, left=0, border=ft.border.all(1)) self.waste = Slot(top=0, left=100, border=None) self.foundations = [] x = 300 for i in range(4): self.foundations.append(Slot(top=0, left=x, border=ft.border.all(1, "outline"))) x += 100 self.tableau = [] x = 0 for i in range(7): self.tableau.append(Slot(top=150, left=x, border=None)) x += 100 self.controls.append(self.stock) self.controls.append(self.waste) self.controls.extend(self.foundations) self.controls.extend(self.tableau) self.update()
ディール
上部にrandomをimportを忘れずに。。。
def deal_cards(self): random.shuffle(self.cards) self.controls.extend(self.cards) # deal to tableau first_slot = 0 remaining_cards = self.cards while first_slot < len(self.tableau): for slot in self.tableau[first_slot:]: top_card = remaining_cards[0] top_card.place(slot) remaining_cards.remove(top_card) first_slot +=1 # place remaining cards to stock pile for card in remaining_cards: card.place(self.stock) self.update()
Slotクラスのコンストラクタでのborderを書き忘れてて、このあとエラーでつまずきました。。。
こんなかんじですね。
カードクラスのplaceメソッドを修正
def place(self, slot): """Place draggable pile to the slot""" if slot in self.solitaire.tableau: self.top = slot.top + len(slot.pile) * CARD_OFFSET else: self.top = slot.top self.left = slot.left
CARD_OFFSETが定数ですね。ここも公式とは違うのでひっかかりました。。。
次はドロップ機能
def drop(self, e: ft.DragEndEvent): for slot in self.solitaire.tableau: if ( abs(self.top - (slot.top + len(slot.pile) * CARD_OFFSET)) < DROP_PROXIMITY and abs(self.left - slot.left) < DROP_PROXIMITY ): self.place(slot) self.solitaire.update() return for slot in self.solitaire.foundations: if ( abs(self.top - slot.top) < DROP_PROXIMITY and abs(self.left - slot.left) < DROP_PROXIMITY ): self.place(slot) self.solitaire.update() return self.bounce_back()
カードクラスに
def turn_face_up(self): """Reveals card""" self.face_up = True self.content.content.src = f"/images/{self.rank.name}_{self.suite.name}.svg" self.solitaire.update()
ソリティアクラスに以下を追加
for slot in self.tableau: slot.get_top_card().turn_face_up() self.update()
実行!!!
今日はそれっぽくなったので、ここまでにします。