Last active
August 27, 2018 10:14
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Few things I want to improve here.
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.
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.
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.