Skip to content

Instantly share code, notes, and snippets.

@shivendrasoni
Last active August 27, 2018 10:14
Show Gist options
  • Save shivendrasoni/706094301695b84322bc3ee5699b4885 to your computer and use it in GitHub Desktop.
Save shivendrasoni/706094301695b84322bc3ee5699b4885 to your computer and use it in GitHub Desktop.
An object oriented implementation of a card deck (configurable to different kinds of cards) and a card game simulation
import random
class Card(object):
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank[0]
self.name = rank[1]
def __str__(self):
return '%s of %s' % (self.name,
self.suit)
class Deck(object):
def __init__(self, suits=[], ranks=[]):
self.cards = []
for suit in suits:
for rank in ranks:
card = Card(suit, rank)
self.cards.append(card)
def __str__(self):
res = []
for card in self.cards:
res.append(str(card))
return '\n'.join(res)
def add_card(self, card):
self.cards.append(card)
def remove_card(self, card):
self.cards.pop(card)
def pop_card(self, i=-1):
return self.cards.pop(i)
def shuffle(self):
random.shuffle(self.cards)
def sort(self):
self.cards.sort()
def get_deck(self):
return self.cards
class Hand(Deck):
def __init__(self, suit='',highest_rank = 0):
self.cards = Deck()
self.players = []
self.suit = suit
self.highest_rank = highest_rank
def add_player(self, player_id):
self.players.append(player_id)
def get_winner(self):
#FIX
return random.randint(0,3)
class LeaderBoard(object):
def __init__(self, player_count):
self.scores = [0]*player_count
class Game(object):
def __init__(self, deck):
self.deck = deck
self.deck.shuffle()
self.players = []
self.trump = None
def add_players(self, players):
self.players.extend(players)
def print_deck(self):
self.deck.remove_card(self.deck.get_deck()[2])
for i in self.deck.get_deck():
print(i.suit, i.rank)
def distribute_card(self):
no_of_players = len(self.players)
i =0
cards = self.deck.get_deck()
while(len(cards)):
player_id = i%no_of_players
players[player_id].deck.add_card(cards.pop())
i+=1
def decide_trump(self, suits_count):
self.trump = random.randint(0,suits_count-1)
self.trump = 'Clubs'
def start_game(self):
#change below for random
player = 0
no_of_players = len(self.players)
self.leader_board = LeaderBoard(no_of_players)
hand = Hand()
trump = self.trump
played_card, cards_remaining_with_player, player_name = self.players[player].play_card(hand, trump)
hand.cards.add_card(played_card)
for i in range(player+1,52+player):
current_player = i%no_of_players
played_card, cards_remaining_with_player, player_name = self.players[current_player].play_card(hand, trump)
hand.cards.add_card(played_card)
hand.add_player(current_player)
if i%no_of_players == 0:
winner = hand.get_winner()
self.leader_board.scores[winner] +=1
hand = Hand()
player +=1
class Player(object):
def __init__(self, id, name):
self.id = id
self.name = name
self.deck = Deck()
def play_card(self, hand, trump):
current_suit = hand.suit
highest_card = hand.highest_rank
cards = self.deck.get_deck()
return cards.pop(), len(cards), self.name
current_suit_highest = 0
current_suit_highest_index = -1
trump_lowest = 14
trump_lowest_index = len(cards)
lowest_rank = 14
lowest_rank_index = len(cards)
for i,card in enumerate(cards):
if(card.suit == current_suit):
if(card.rank > current_suit_highest):
current_suit_highest_index = i
current_suit_highest = card.rank
elif(card.suit == trump):
if(card.rank < trump_lowest):
trump_lowest_index = i
trump_lowest = card.rank
else:
if(card.rank < lowest_rank):
lowest_rank_index = i
lowest_rank = card.rank
if current_suit_highest:
c = cards.pop(cards[current_suit_highest_index])
return c,len(cards), self.name
if(trump_lowest !=14):
c = cards.pop(cards[trump_lowest_index])
return c,len(cards), self.name
if(lowest_rank !=14):
c = cards.pop(cards[lowest_rank_index])
return c,len(cards), self.name
if __name__ == '__main__':
suits = ["Clubs", "Diamonds", "Hearts", "Spades"]
cards = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"]
for i in range(len(cards)):
cards[i] = (i+1, cards[i])
total_no_cards = len(cards)*len(suits)
players = []
players.append(Player(1,'A'))
players.append(Player(2,'B'))
players.append(Player(3,'C'))
players.append(Player(4,'D'))
if(total_no_cards % len(players)):
print("Equal distribution not possible, exiting")
exit()
deck = Deck(suits, cards)
new_game = Game(deck)
new_game.decide_trump(len(suits)-1)
new_game.add_players(players)
new_game.distribute_card()
new_game.start_game()
@shivendrasoni
Copy link
Author

Few things I want to improve here.

  1. Have a base card class. Then extend it in special cards class (say you want cricket or football cards with more than one stat). And generate them through a factory.

  2. Have an base strategy class and children strategy class, which would be implemented for different strategies of players. This way, each player would have a custom game play.

  3. Possibly, have a Rules class, which defines rules for a game, and is used by Game class.
    Implementations for a hand winning, losing tie, tie-breaker would be in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment