Skip to main content
Fixed indentation, matching code posted on GitHub
Source Link
200_success
  • 145.6k
  • 22
  • 190
  • 479
class AbstractCard:
    """Abstract class for handling comparisons between cards based on rank"""

    def __init__(self, value=None, suit=None, rank=None):
        self.value = value
        self.suit = suit
        self.rank = rank

    def __lt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank < other.rank
        raise TypeError("Cannot compare to non-card types")

    def __le__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank <= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __eq__(self, other):
        if isinstance(other, AbstractCard):
             return self.rank == other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ne__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank != other.rank
        raise TypeError("Cannot compare to non-card types")

    def __gt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank > other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ge__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank >= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __repr__(self):
        data = (self.value, self.suit, self.rank)
        return "(value:{}, suit:{}, rank:{})".format(*data)

    def __str__(self):
        data = (self.value, self.suit)
        return "{} of {}".format(*data)
from AbstractCard import AbstractCard

class AbstractCardFactory:
    """Factory for making AbstractCards"""

    def __init__(self, values=None, suits=None, rank_function=None):
        self.values = values
        self.suits = suits
        self.rank_function = rank_function
    
    def __repr__(self):
        return "Values: {}\nSuits: {}".format(self.values, self.suits)

    def __str__(self):
        return self.__repr__()

    def generate(self):
        if self.rank_function:
            for suit in self.suits:
                for value in self.values:
                    card = AbstractCard(value, suit)
                    card.rank = rank_function(card)
                    yield card
        else:
            for suit in self.suits:
                for value in self.values:
                    yield AbstractCard(value, suit)
from random import *

class AbstractDeck:
    """Abstract class for shuffling and iterating over a collection of cards"""

    def __init__(self, cards=None):
        self.cards = cards

    def __len__(self):
        return len(cards)

    def __iter__(self):
        return iter(self.cards)

    def shuffle(self):
        """Shuffles the deck with the Fisher-Yates shuffle"""
        num_cards = len(self.cards)
        for i in range(0, num_cards):
            j = randint(i, num_cards - 1)
            self.cards[i], self.cards[j] = self.cards[j], self.cards[i]
class AbstractPlayer:
    """Abstract class for containing basic player information"""

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

    def name(self):
        return self.name

    def hand(self):
        """Returns a copy of the player's hand"""
        return self.cards

    def add_card(self, card):
        """Adds the given card to the existing cards"""
        self.cards.append(card)

    def remove_card(self, card):
        """Removes the given card from the player's hand"""
        self.cards.remove(card)

    def __repr__(self):
        return self.name

    def __str__(self):
        return str(self.name)
class AbstractGame:
    """Abstract class for running a card game"""

    def __init__(self, players=[], deck=None):
        self.players = list(players)
        self.deck = deck

    def play_game(self):
        """Override this function for custom game logic"""
        pass
class AbstractCard:
"""Abstract class for handling comparisons between cards based on rank"""

    def __init__(self, value=None, suit=None, rank=None):
        self.value = value
        self.suit = suit
        self.rank = rank

    def __lt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank < other.rank
        raise TypeError("Cannot compare to non-card types")

    def __le__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank <= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __eq__(self, other):
        if isinstance(other, AbstractCard):
             return self.rank == other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ne__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank != other.rank
        raise TypeError("Cannot compare to non-card types")

    def __gt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank > other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ge__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank >= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __repr__(self):
        data = (self.value, self.suit, self.rank)
        return "(value:{}, suit:{}, rank:{})".format(*data)

    def __str__(self):
        data = (self.value, self.suit)
        return "{} of {}".format(*data)
from AbstractCard import AbstractCard

class AbstractCardFactory:
"""Factory for making AbstractCards"""

    def __init__(self, values=None, suits=None, rank_function=None):
        self.values = values
        self.suits = suits
        self.rank_function = rank_function
    
    def __repr__(self):
        return "Values: {}\nSuits: {}".format(self.values, self.suits)

    def __str__(self):
        return self.__repr__()

    def generate(self):
        if self.rank_function:
            for suit in self.suits:
                for value in self.values:
                    card = AbstractCard(value, suit)
                    card.rank = rank_function(card)
                    yield card
        else:
            for suit in self.suits:
                for value in self.values:
                    yield AbstractCard(value, suit)
from random import *

class AbstractDeck:
"""Abstract class for shuffling and iterating over a collection of cards"""

    def __init__(self, cards=None):
        self.cards = cards

    def __len__(self):
        return len(cards)

    def __iter__(self):
        return iter(self.cards)

    def shuffle(self):
        """Shuffles the deck with the Fisher-Yates shuffle"""
        num_cards = len(self.cards)
        for i in range(0, num_cards):
            j = randint(i, num_cards - 1)
            self.cards[i], self.cards[j] = self.cards[j], self.cards[i]
class AbstractPlayer:
"""Abstract class for containing basic player information"""

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

    def name(self):
        return self.name

    def hand(self):
        """Returns a copy of the player's hand"""
        return self.cards

    def add_card(self, card):
        """Adds the given card to the existing cards"""
        self.cards.append(card)

    def remove_card(self, card):
        """Removes the given card from the player's hand"""
        self.cards.remove(card)

    def __repr__(self):
        return self.name

    def __str__(self):
        return str(self.name)
class AbstractGame:
"""Abstract class for running a card game"""

    def __init__(self, players=[], deck=None):
        self.players = list(players)
        self.deck = deck

    def play_game(self):
        """Override this function for custom game logic"""
        pass
class AbstractCard:
    """Abstract class for handling comparisons between cards based on rank"""

    def __init__(self, value=None, suit=None, rank=None):
        self.value = value
        self.suit = suit
        self.rank = rank

    def __lt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank < other.rank
        raise TypeError("Cannot compare to non-card types")

    def __le__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank <= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __eq__(self, other):
        if isinstance(other, AbstractCard):
             return self.rank == other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ne__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank != other.rank
        raise TypeError("Cannot compare to non-card types")

    def __gt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank > other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ge__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank >= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __repr__(self):
        data = (self.value, self.suit, self.rank)
        return "(value:{}, suit:{}, rank:{})".format(*data)

    def __str__(self):
        data = (self.value, self.suit)
        return "{} of {}".format(*data)
from AbstractCard import AbstractCard

class AbstractCardFactory:
    """Factory for making AbstractCards"""

    def __init__(self, values=None, suits=None, rank_function=None):
        self.values = values
        self.suits = suits
        self.rank_function = rank_function
    
    def __repr__(self):
        return "Values: {}\nSuits: {}".format(self.values, self.suits)

    def __str__(self):
        return self.__repr__()

    def generate(self):
        if self.rank_function:
            for suit in self.suits:
                for value in self.values:
                    card = AbstractCard(value, suit)
                    card.rank = rank_function(card)
                    yield card
        else:
            for suit in self.suits:
                for value in self.values:
                    yield AbstractCard(value, suit)
from random import *

class AbstractDeck:
    """Abstract class for shuffling and iterating over a collection of cards"""

    def __init__(self, cards=None):
        self.cards = cards

    def __len__(self):
        return len(cards)

    def __iter__(self):
        return iter(self.cards)

    def shuffle(self):
        """Shuffles the deck with the Fisher-Yates shuffle"""
        num_cards = len(self.cards)
        for i in range(0, num_cards):
            j = randint(i, num_cards - 1)
            self.cards[i], self.cards[j] = self.cards[j], self.cards[i]
class AbstractPlayer:
    """Abstract class for containing basic player information"""

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

    def name(self):
        return self.name

    def hand(self):
        """Returns a copy of the player's hand"""
        return self.cards

    def add_card(self, card):
        """Adds the given card to the existing cards"""
        self.cards.append(card)

    def remove_card(self, card):
        """Removes the given card from the player's hand"""
        self.cards.remove(card)

    def __repr__(self):
        return self.name

    def __str__(self):
        return str(self.name)
class AbstractGame:
    """Abstract class for running a card game"""

    def __init__(self, players=[], deck=None):
        self.players = list(players)
        self.deck = deck

    def play_game(self):
        """Override this function for custom game logic"""
        pass
Added some text how to use this code
Source Link
mleyfman
  • 5.3k
  • 1
  • 25
  • 48

How to use

  1. Construct a deck using a AbstractCardFactory
  2. Extend the AbstractGame class with custom game logic in the play_game() method
  3. Add a if __name__ == "__main__": block with player initialization logic

How to use

  1. Construct a deck using a AbstractCardFactory
  2. Extend the AbstractGame class with custom game logic in the play_game() method
  3. Add a if __name__ == "__main__": block with player initialization logic
Source Link
mleyfman
  • 5.3k
  • 1
  • 25
  • 48

Abstract card game code in Python3

I've written up some generic code for a card-game and would like to hear any and all suggestions for how to improve this code further, in any way shape or form.

The code is on github or pasted directly below:

Card class:

class AbstractCard:
"""Abstract class for handling comparisons between cards based on rank"""

    def __init__(self, value=None, suit=None, rank=None):
        self.value = value
        self.suit = suit
        self.rank = rank

    def __lt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank < other.rank
        raise TypeError("Cannot compare to non-card types")

    def __le__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank <= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __eq__(self, other):
        if isinstance(other, AbstractCard):
             return self.rank == other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ne__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank != other.rank
        raise TypeError("Cannot compare to non-card types")

    def __gt__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank > other.rank
        raise TypeError("Cannot compare to non-card types")

    def __ge__(self, other):
        if isinstance(other, AbstractCard):
            return self.rank >= other.rank
        raise TypeError("Cannot compare to non-card types")

    def __repr__(self):
        data = (self.value, self.suit, self.rank)
        return "(value:{}, suit:{}, rank:{})".format(*data)

    def __str__(self):
        data = (self.value, self.suit)
        return "{} of {}".format(*data)

CardFactory class

from AbstractCard import AbstractCard

class AbstractCardFactory:
"""Factory for making AbstractCards"""

    def __init__(self, values=None, suits=None, rank_function=None):
        self.values = values
        self.suits = suits
        self.rank_function = rank_function
    
    def __repr__(self):
        return "Values: {}\nSuits: {}".format(self.values, self.suits)

    def __str__(self):
        return self.__repr__()

    def generate(self):
        if self.rank_function:
            for suit in self.suits:
                for value in self.values:
                    card = AbstractCard(value, suit)
                    card.rank = rank_function(card)
                    yield card
        else:
            for suit in self.suits:
                for value in self.values:
                    yield AbstractCard(value, suit)

Deck class

from random import *

class AbstractDeck:
"""Abstract class for shuffling and iterating over a collection of cards"""

    def __init__(self, cards=None):
        self.cards = cards

    def __len__(self):
        return len(cards)

    def __iter__(self):
        return iter(self.cards)

    def shuffle(self):
        """Shuffles the deck with the Fisher-Yates shuffle"""
        num_cards = len(self.cards)
        for i in range(0, num_cards):
            j = randint(i, num_cards - 1)
            self.cards[i], self.cards[j] = self.cards[j], self.cards[i]

Player class

class AbstractPlayer:
"""Abstract class for containing basic player information"""

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

    def name(self):
        return self.name

    def hand(self):
        """Returns a copy of the player's hand"""
        return self.cards

    def add_card(self, card):
        """Adds the given card to the existing cards"""
        self.cards.append(card)

    def remove_card(self, card):
        """Removes the given card from the player's hand"""
        self.cards.remove(card)

    def __repr__(self):
        return self.name

    def __str__(self):
        return str(self.name)

Game class

class AbstractGame:
"""Abstract class for running a card game"""

    def __init__(self, players=[], deck=None):
        self.players = list(players)
        self.deck = deck

    def play_game(self):
        """Override this function for custom game logic"""
        pass