--- /home/docs/checkouts/readthedocs.org/user_builds/arcade-library/checkouts/latest/doc/tutorials/card_game/solitaire_06.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/arcade-library/checkouts/latest/doc/tutorials/card_game/solitaire_07.py
@@ -45,6 +45,25 @@
CARD_VALUES = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
CARD_SUITS = ["Clubs", "Hearts", "Spades", "Diamonds"]
+# If we fan out cards stacked on each other, how far apart to fan them?
+CARD_VERTICAL_OFFSET = CARD_HEIGHT * CARD_SCALE * 0.3
+
+# Constants that represent "what pile is what" for the game
+PILE_COUNT = 13
+BOTTOM_FACE_DOWN_PILE = 0
+BOTTOM_FACE_UP_PILE = 1
+PLAY_PILE_1 = 2
+PLAY_PILE_2 = 3
+PLAY_PILE_3 = 4
+PLAY_PILE_4 = 5
+PLAY_PILE_5 = 6
+PLAY_PILE_6 = 7
+PLAY_PILE_7 = 8
+TOP_PILE_1 = 9
+TOP_PILE_2 = 10
+TOP_PILE_3 = 11
+TOP_PILE_4 = 12
+
class Card(arcade.Sprite):
""" Card sprite """
@@ -83,6 +102,9 @@
# Sprite list with all the mats tha cards lay on.
self.pile_mat_list = None
+
+ # Create a list of lists, each holds a pile of cards.
+ self.piles = None
def setup(self):
""" Set up the game here. Call this function to restart the game. """
@@ -137,6 +159,13 @@
pos2 = random.randrange(len(self.card_list))
self.card_list.swap(pos1, pos2)
+ # Create a list of lists, each holds a pile of cards.
+ self.piles = [[] for _ in range(PILE_COUNT)]
+
+ # Put all the cards in the bottom face-down pile
+ for card in self.card_list:
+ self.piles[BOTTOM_FACE_DOWN_PILE].append(card)
+
def on_draw(self):
""" Render the screen. """
# Clear the screen
@@ -174,6 +203,24 @@
# Put on top in drawing order
self.pull_to_top(self.held_cards[0])
+ def remove_card_from_pile(self, card):
+ """ Remove card from whatever pile it was in. """
+ for pile in self.piles:
+ if card in pile:
+ pile.remove(card)
+ break
+
+ def get_pile_for_card(self, card):
+ """ What pile is this card in? """
+ for index, pile in enumerate(self.piles):
+ if card in pile:
+ return index
+
+ def move_card_to_new_pile(self, card, pile_index):
+ """ Move the card to a new pile """
+ self.remove_card_from_pile(card)
+ self.piles[pile_index].append(card)
+
def on_mouse_release(self, x: float, y: float, button: int,
modifiers: int):
""" Called when the user presses a mouse button. """
@@ -189,13 +236,46 @@
# See if we are in contact with the closest pile
if arcade.check_for_collision(self.held_cards[0], pile):
- # For each held card, move it to the pile we dropped on
- for i, dropped_card in enumerate(self.held_cards):
- # Move cards to proper position
- dropped_card.position = pile.center_x, pile.center_y
-
- # Success, don't reset position of cards
- reset_position = False
+ # What pile is it?
+ pile_index = self.pile_mat_list.index(pile)
+
+ # Is it the same pile we came from?
+ if pile_index == self.get_pile_for_card(self.held_cards[0]):
+ # If so, who cares. We'll just reset our position.
+ pass
+
+ # Is it on a middle play pile?
+ elif PLAY_PILE_1 <= pile_index <= PLAY_PILE_7:
+ # Are there already cards there?
+ if len(self.piles[pile_index]) > 0:
+ # Move cards to proper position
+ top_card = self.piles[pile_index][-1]
+ for i, dropped_card in enumerate(self.held_cards):
+ dropped_card.position = top_card.center_x, \
+ top_card.center_y - CARD_VERTICAL_OFFSET * (i + 1)
+ else:
+ # Are there no cards in the middle play pile?
+ for i, dropped_card in enumerate(self.held_cards):
+ # Move cards to proper position
+ dropped_card.position = pile.center_x, \
+ pile.center_y - CARD_VERTICAL_OFFSET * i
+
+ for card in self.held_cards:
+ # Cards are in the right position, but we need to move them to the right list
+ self.move_card_to_new_pile(card, pile_index)
+
+ # Success, don't reset position of cards
+ reset_position = False
+
+ # Release on top play pile? And only one card held?
+ elif TOP_PILE_1 <= pile_index <= TOP_PILE_4 and len(self.held_cards) == 1:
+ # Move position of card to pile
+ self.held_cards[0].position = pile.position
+ # Move card to card list
+ for card in self.held_cards:
+ self.move_card_to_new_pile(card, pile_index)
+
+ reset_position = False
if reset_position:
# Where-ever we were dropped, it wasn't valid. Reset the each card's position