Skip to content

Commit c0ab673

Browse files
authored
Create card.py
1 parent bedfa36 commit c0ab673

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

files/card.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import flet as ft
2+
3+
class Card(ft.GestureDetector):
4+
def __init__(self, solitaire, suite, rank):
5+
super().__init__()
6+
self.solitaire = solitaire
7+
self.suite = suite
8+
self.rank = rank
9+
self.face_up = False
10+
self.slot = None
11+
12+
self.mouse_cursor = ft.MouseCursor.MOVE
13+
self.drag_interval = 5
14+
self.on_pan_update = self.drag
15+
self.on_pan_start = self.start_drag
16+
self.on_pan_end = self.drop
17+
self.on_tap = self.click
18+
self.on_double_tap = self.doubleclick
19+
self.content = ft.Container(
20+
width=70,
21+
height=100,
22+
border_radius=ft.border_radius.all(6),
23+
#content=ft.Image(src=f"/images/card_back.svg"),
24+
content=ft.Image(src=self.solitaire.settings.card_back)
25+
)
26+
27+
def turn_face_up(self):
28+
self.face_up = True
29+
self.content.content.src=f"/images/{self.rank.name}_{self.suite.name}.svg"
30+
self.update()
31+
32+
33+
def turn_face_down(self):
34+
self.face_up = False
35+
#self.content.content.src=f"/images/card_back.svg"
36+
self.content.content.src=self.solitaire.settings.card_back
37+
self.update()
38+
39+
def can_be_moved(self):
40+
if self.face_up and self.slot.type != 'waste':
41+
return True
42+
if self.slot.type == 'waste' and len(self.solitaire.waste.pile)-1 == self.solitaire.waste.pile.index(self):
43+
return True
44+
return False
45+
46+
def start_drag(self, e: ft.DragStartEvent):
47+
#if e.control.face_up:
48+
if self.can_be_moved():
49+
cards_to_drag = self.get_cards_to_move()
50+
self.solitaire.move_on_top(cards_to_drag)
51+
# remember card original position to return it back if needed
52+
self.solitaire.current_top = e.control.top
53+
self.solitaire.current_left = e.control.left
54+
# self.page.update()
55+
56+
def drag(self, e: ft.DragUpdateEvent):
57+
if self.can_be_moved():
58+
i = 0
59+
for card in self.get_cards_to_move():
60+
card.top = max(0, self.top + e.delta_y)
61+
if card.slot.type == "tableau":
62+
card.top += i * self.solitaire.card_offset
63+
card.left = max(0, self.left + e.delta_x)
64+
i += 1
65+
card.update()
66+
67+
def drop(self, e: ft.DragEndEvent):
68+
if self.can_be_moved():
69+
cards_to_drag = self.get_cards_to_move()
70+
slots = self.solitaire.tableau + self.solitaire.foundation
71+
# check if card is close to any of the tableau or foundation slots
72+
for slot in slots:
73+
# compare with top and left position of the top card in the slot pile
74+
if (
75+
abs(self.top - slot.upper_card_top()) < 40
76+
and abs(self.left - slot.left) < 40
77+
):
78+
if (
79+
slot.type == "tableau"
80+
and self.solitaire.check_tableau_rules(
81+
self, slot.get_top_card()
82+
)
83+
) or (
84+
slot.type == "foundation"
85+
and len(cards_to_drag) == 1
86+
and self.solitaire.check_foundation_rules(
87+
self, slot.get_top_card()
88+
)
89+
):
90+
91+
old_slot = self.slot
92+
for card in cards_to_drag:
93+
card.place(slot)
94+
# reveal top card in old tableau slot if exists
95+
#if len(old_slot.pile) > 0 and old_slot.type == "tableau":
96+
# old_slot.get_top_card().turn_face_up()
97+
self.solitaire.display_waste()
98+
self.page.update()
99+
100+
return
101+
102+
# return card to original position
103+
self.solitaire.bounce_back(cards_to_drag)
104+
self.page.update()
105+
106+
def doubleclick(self, e):
107+
if self.slot.type in ("waste", "tableau"):
108+
if self.face_up:
109+
#self.move_on_top(self.solitaire.controls, [self])
110+
self.solitaire.move_on_top([self])
111+
old_slot = self.slot
112+
for slot in self.solitaire.foundation:
113+
if self.solitaire.check_foundation_rules(self, slot.get_top_card()):
114+
# if True:
115+
self.place(slot)
116+
#if len(old_slot.pile) > 0:
117+
#old_slot.get_top_card().turn_face_up()
118+
self.solitaire.display_waste()
119+
self.page.update()
120+
return
121+
122+
def click(self, e):
123+
if self.slot.type == "stock":
124+
for i in range(
125+
min(self.solitaire.settings.waste_size, len(self.solitaire.stock.pile))
126+
):
127+
top_card = self.solitaire.stock.pile[-1]
128+
#self.move_on_top(self.solitaire.controls, [top_card])
129+
#self.solitaire.move_on_top([top_card])
130+
top_card.place(self.solitaire.waste)
131+
top_card.turn_face_up()
132+
self.solitaire.display_waste()
133+
self.page.update()
134+
135+
if self.slot.type == "tableau":
136+
if self.face_up == False and len(self.slot.pile)-1 == self.slot.pile.index(self):
137+
self.turn_face_up()
138+
139+
def place(self, slot):
140+
self.top = slot.top
141+
self.left = slot.left
142+
if slot.type == "tableau":
143+
self.top += self.solitaire.card_offset * len(slot.pile)
144+
145+
# remove the card form the old slot's pile if exists
146+
147+
if self.slot is not None:
148+
# if self.slot.type == 'waste':
149+
# self.solitaire.update_waste()
150+
self.slot.pile.remove(self)
151+
152+
# set card's slot as new slot
153+
self.slot = slot
154+
155+
# add the card to the new slot's pile
156+
slot.pile.append(self)
157+
self.solitaire.move_on_top([self])
158+
if self.solitaire.check_if_you_won():
159+
self.solitaire.on_win()
160+
self.update()
161+
162+
def get_cards_to_move(self):
163+
"""returns list of cards that will be dragged together, starting with the current card"""
164+
if self.slot is not None:
165+
return self.slot.pile[self.slot.pile.index(self):]
166+
167+
return [self]

0 commit comments

Comments
 (0)