Appendix - Code of Card Game

Appendix - Code of Card Game

Card class (full code)

class Card:
    suits = ["Clubs", "Diamonds", "Hearts", "Spades"]
    ranks = ["narf", "Ace", "2", "3", "4", "5", "6", "7",
             "8", "9", "10", "Jack", "Queen", "King"]

    def __init__(self, suit=0, rank=0):
        self.suit = suit
        self.rank = rank

    def __str__(self):
        return (self.ranks[self.rank] + " of " + self.suits[self.suit])

    def cmp(self, other):
        # Check the suits
        if self.suit > other.suit: return 1
        if self.suit < other.suit: return -1
        # Suits are the same... check ranks
        if self.rank > other.rank: return 1
        if self.rank < other.rank: return -1
        # Ranks are the same... it's a tie
        return 0

    def __eq__(self, other):
        # equality
        return self.cmp(other) == 0

    def __le__(self, other):
        # less than or equal
        return self.cmp(other) <= 0

    def __ge__(self, other):
        # greater than or equal
        return self.cmp(other) >= 0

    def __gt__(self, other):
        # strictly greater than
        return self.cmp(other) > 0

    def __lt__(self, other):
        # strictly less than
        return self.cmp(other) < 0

    def __ne__(self, other):
        # not equal
        return self.cmp(other) != 0

Deck class (full code)

class Deck:

    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1, 14):
                self.cards.append(Card(suit, rank))

    def print_deck(self):
        for card in self.cards:
            print(card)

    def __str__(self):
        s,spaces = "",""
        for c in self.cards:
            s = s + spaces + str(c) + "\n"
            spaces += " "
        return s

    def shuffle(self):
        import random
        rng = random.Random()        # Create a random generator
        num_cards = len(self.cards)
        for i in range(num_cards):
            j = rng.randrange(i, num_cards)
            (self.cards[i], self.cards[j]) = (self.cards[j], self.cards[i])

    def shuffle2(self):
        import random
        rng = random.Random()        # Create a random generator
        rng.shuffle(self.cards)      # Use its shuffle method

    def remove(self, card):
        if card in self.cards:
            self.cards.remove(card)
            return True
        else:
            return False

    def pop(self):
        return self.cards.pop()

    def is_empty(self):
        return self.cards == []

    def deal(self, hands, num_cards=None):
        if num_cards==None :             # if no default value for how many cards
            num_cards = len(self.cards)  # to deal then deal all cards in deck
        num_hands = len(hands)
        for i in range(num_cards):
            if self.is_empty():
                break                    # Break if out of cards
            card = self.pop()            # Take the top card
            hand = hands[i % num_hands]  # Whose turn is next?
            hand.add(card)               # Add the card to the hand

CardGame class (full code)

class CardGame:
    def __init__(self):
        self.deck = Deck()
        self.deck.shuffle()

Hand class (full code)

class Hand(Deck):

    def __init__(self, name=""):
        self.cards = []
        self.name = name

    def __str__(self):
        s = "Hand " + self.name
        if self.is_empty():
            s += " is empty\n"
            return s
        else:
            s += " contains\n"
            return s + super().__str__()    # super call by making use of the super() function (preferred)

    def add(self, card):
        self.cards.append(card)
        return self

OldMaidHand class (full code)

class OldMaidHand(Hand):

    def remove_matches(self):
        count = 0                               # counts number of matches that have been removed
        original_cards = self.cards.copy()      # makes a copy of the original set of cards in your hand
        for card in original_cards:             # iterate over all cards in your hand
            match = Card(3 - card.suit, card.rank)
            if match in self.cards:             # if the matching card is in your hand
                self.cards.remove(card)         # remove the card from your hand
                self.cards.remove(match)        # remove the match from your hand
                count += 1                      # add one to the count of matches that have been removed
                print("Hand {0}: {1} matches {2}".format(self.name, card, match))
        return count                            # return number of matches that have been removed

OldMaidGame class (full code)

class OldMaidGame(CardGame):

    def play(self, names):
        # Remove Queen of Clubs
        queen_clubs = Card(0,12)
        self.deck.remove(queen_clubs)

        # Make a hand for each player
        self.hands = []
        for name in names:
            self.hands.append(OldMaidHand(name))

        # Deal the cards
        self.deck.deal(self.hands)
        print("---------- Cards have been dealt")
        self.print_hands()

        # Remove initial matches
        print("---------- Discarding matches from hands")
        matches = self.remove_all_matches()
        print("---------- Matches have been discarded")
        self.print_hands()

        # Play until all 50 cards are matched
        # in other words, until 25 pairs have been matched
        print("---------- Play begins")
        turn = 0
        num_players = len(names)
        while matches < 25:
            matches += self.play_one_turn(turn)
            turn = (turn + 1) % num_players

        print("---------- Game is Over")
        self.print_hands()

    def print_hands(self):
        for hand in self.hands:
            print(hand)

    def remove_all_matches(self):
        count = 0
        for hand in self.hands:
            count += hand.remove_matches()
        return count

    def play_one_turn(self, i):
        print("Player" + str(i) + ":")
        if self.hands[i].is_empty():
            return 0
        neighbor = self.find_neighbor(i)
        picked_card = self.hands[neighbor].pop()
        self.hands[i].add(picked_card)
        print("Hand", self.hands[i].name, "picked", picked_card)
        count = self.hands[i].remove_matches()
        self.hands[i].shuffle()
        return count

    def find_neighbor(self, i):
        num_hands = len(self.hands)
        for next in range(1,num_hands):
            neighbor = (i + next) % num_hands
            if not self.hands[neighbor].is_empty():
                return neighbor

Sample output of a run of the game

>>> OldMaidGame().play(["kim","charles","siegfried"])
---------- Cards have been dealt
Hand kim contains
5 of Diamonds
 10 of Diamonds
  Ace of Clubs
   Ace of Spades
    Jack of Hearts
     4 of Clubs
      3 of Clubs
       King of Diamonds
        4 of Diamonds
         10 of Clubs
          Ace of Hearts
           5 of Hearts
            Queen of Diamonds
             Jack of Spades
              Jack of Diamonds
               5 of Clubs
                9 of Clubs

Hand charles contains
5 of Spades
 6 of Clubs
  Queen of Spades
   8 of Spades
    2 of Clubs
     6 of Spades
      9 of Hearts
       8 of Hearts
        10 of Hearts
         9 of Diamonds
          7 of Hearts
           10 of Spades
            9 of Spades
             3 of Diamonds
              Jack of Clubs
               7 of Spades
                3 of Hearts

Hand siegfried contains
7 of Clubs
 6 of Diamonds
  3 of Spades
   King of Hearts
    2 of Spades
     2 of Diamonds
      7 of Diamonds
       2 of Hearts
        4 of Hearts
         King of Clubs
          4 of Spades
           8 of Clubs
            King of Spades
             8 of Diamonds
              Queen of Hearts
               6 of Hearts
                Ace of Diamonds

---------- Discarding matches from hands
Hand kim: 5 of Diamonds matches 5 of Hearts
Hand kim: Ace of Clubs matches Ace of Spades
Hand kim: Jack of Hearts matches Jack of Diamonds
Hand charles: 6 of Clubs matches 6 of Spades
Hand charles: 9 of Hearts matches 9 of Diamonds
Hand charles: 3 of Diamonds matches 3 of Hearts
Hand siegfried: 6 of Diamonds matches 6 of Hearts
Hand siegfried: 2 of Diamonds matches 2 of Hearts
Hand siegfried: King of Clubs matches King of Spades
---------- Matches have been discarded
Hand kim contains
10 of Diamonds
 4 of Clubs
  3 of Clubs
   King of Diamonds
    4 of Diamonds
     10 of Clubs
      Ace of Hearts
       Queen of Diamonds
        Jack of Spades
         5 of Clubs
          9 of Clubs

Hand charles contains
5 of Spades
 Queen of Spades
  8 of Spades
   2 of Clubs
    8 of Hearts
     10 of Hearts
      7 of Hearts
       10 of Spades
        9 of Spades
         Jack of Clubs
          7 of Spades

Hand siegfried contains
7 of Clubs
 3 of Spades
  King of Hearts
   2 of Spades
    7 of Diamonds
     4 of Hearts
      4 of Spades
       8 of Clubs
        8 of Diamonds
         Queen of Hearts
          Ace of Diamonds

---------- Play begins
Player0:
Hand kim picked 7 of Spades
Player1:
Hand charles picked Ace of Diamonds
Player2:
Hand siegfried picked 7 of Spades
Hand siegfried: 7 of Clubs matches 7 of Spades
Player0:
Hand kim picked 9 of Spades
Hand kim: 9 of Clubs matches 9 of Spades
Player1:
Hand charles picked 8 of Clubs
Hand charles: 8 of Spades matches 8 of Clubs
Player2:
Hand siegfried picked Jack of Spades
Player0:
Hand kim picked Jack of Clubs
Player1:
Hand charles picked 3 of Spades
Player2:
Hand siegfried picked Ace of Hearts
Player0:
Hand kim picked 10 of Hearts
Hand kim: 10 of Diamonds matches 10 of Hearts
Player1:
Hand charles picked Queen of Hearts
Player2:
Hand siegfried picked 4 of Diamonds
Hand siegfried: 4 of Hearts matches 4 of Diamonds
Player0:
Hand kim picked 3 of Spades
Hand kim: 3 of Clubs matches 3 of Spades
Player1:
Hand charles picked King of Hearts
Player2:
Hand siegfried picked 4 of Clubs
Hand siegfried: 4 of Spades matches 4 of Clubs
Player0:
Hand kim picked King of Hearts
Hand kim: King of Diamonds matches King of Hearts
Player1:
Hand charles picked Jack of Spades
Player2:
Hand siegfried picked 5 of Clubs
Player0:
Hand kim picked 7 of Hearts
Player1:
Hand charles picked Ace of Hearts
Hand charles: Ace of Diamonds matches Ace of Hearts
Player2:
Hand siegfried picked Queen of Diamonds
Player0:
Hand kim picked 8 of Hearts
Player1:
Hand charles picked 5 of Clubs
Hand charles: 5 of Spades matches 5 of Clubs
Player2:
Hand siegfried picked Jack of Clubs
Player0:
Hand kim picked Queen of Spades
Player1:
Hand charles picked 2 of Spades
Hand charles: 2 of Clubs matches 2 of Spades
Player2:
Hand siegfried picked Queen of Spades
Player0:
Hand kim picked Queen of Hearts
Player1:
Hand charles picked Queen of Spades
Player2:
Hand siegfried picked 8 of Hearts
Hand siegfried: 8 of Diamonds matches 8 of Hearts
Player0:
Hand kim picked Queen of Spades
Player1:
Hand charles picked Jack of Clubs
Hand charles: Jack of Spades matches Jack of Clubs
Player2:
Hand siegfried picked Queen of Hearts
Hand siegfried: Queen of Diamonds matches Queen of Hearts
Player0:
Hand kim picked 10 of Spades
Hand kim: 10 of Clubs matches 10 of Spades
Player1:
Player2:
Hand siegfried picked Queen of Spades
Player0:
Hand kim picked 7 of Diamonds
Hand kim: 7 of Hearts matches 7 of Diamonds
---------- Game is Over
Hand kim is empty

Hand charles is empty

Hand siegfried contains
Queen of Spades

Page précédente Page suivante