Skip to content

Instantly share code, notes, and snippets.

@damianesteban
Created October 9, 2013 04:14
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save damianesteban/6896120 to your computer and use it in GitHub Desktop.
Save damianesteban/6896120 to your computer and use it in GitHub Desktop.
python war card game oop
import random
################################################################################
def main():
table = Table(['Matthew', 'Mark', 'Luke', 'John'])
table.deal_cards()
table.play_all()
def print_underline(string, line):
print('\n{}\n{}'.format(string, line * len(string)))
################################################################################
class Table:
def __init__(self, players):
self.players = [Player(name, Hand()) for name in players]
self.deck = Deck()
self.rounds = 0
def deal_cards(self):
self.deck.shuffle()
self.deck.setup_hands(self.players)
for player in self.players:
player.show_hand()
def play_once(self, tied=None):
if tied is None:
self.count_round()
collection = Pot()
for player in (self.players if tied is None else tied):
player.drop_card(collection)
if tied:
player.drop_bonus(collection, 3)
winner = collection.winner
if winner is not None:
collection.reward(winner)
else:
winner = self.play_once(collection.tied)
collection.reward(winner)
return winner
def count_round(self):
self.rounds += 1
print_underline('Starting round {}'.format(self.rounds), '=')
def play_all(self):
while not self.finished:
self.play_once()
self.show_winner()
def show_winner(self):
for player in self.players:
if player.hand.has_cards:
print()
print(player.name, 'wins!')
break
@property
def finished(self):
return sum(bool(player.hand.cards) for player in self.players) == 1
################################################################################
class Player:
def __init__(self, name, hand):
self.name, self.hand = name, hand
def drop_card(self, collection):
if self.hand.has_cards:
collection.add_card(self.hand.take_top(), self)
def drop_bonus(self, collection, count):
collection.add_bonus(self.hand.cards[:count])
self.hand.cards = self.hand.cards[count:]
def give_cards(self, cards):
self.hand.add_all(cards)
def show_hand(self):
print(self.name, 'has', self.hand)
################################################################################
class Hand:
def __init__(self):
self.cards = []
def __str__(self):
return ', '.join(map(str, self.cards))
def add_card(self, card):
self.cards.append(card)
def take_top(self):
return self.cards.pop(0)
def add_all(self, cards):
self.cards.extend(cards)
@property
def has_cards(self):
return bool(self.cards)
################################################################################
class Deck:
def __init__(self):
self.cards = [Card(s, r) for s in Card.SUITE for r in Card.RANKS]
def shuffle(self):
random.shuffle(self.cards)
def setup_hands(self, players):
hands = [player.hand for player in players]
while len(self.cards) >= len(players):
for hand in hands:
hand.add_card(self.cards.pop())
return hands
################################################################################
class Card:
SUITE = 'H D S C'.split()
RANKS = '2 3 4 5 6 7 8 9 10 J Q K A'.split()
def __init__(self, suite, rank):
self.suite, self.rank = suite, rank
def __str__(self):
return '{}-{}'.format(self.rank, self.suite)
@property
def value(self):
return self.RANKS.index(self.rank)
################################################################################
class Pot:
def __init__(self):
self.cards = []
self.players = []
self.bonus = []
def add_card(self, card, player):
self.cards.append(card)
self.players.append(player)
def add_bonus(self, cards):
self.bonus.extend(cards)
@property
def winner(self):
self.show_pot()
values = [card.value for card in self.cards]
self.best = max(values)
if values.count(self.best) == 1:
return self.players[values.index(self.best)]
def show_pot(self):
for player, card in zip(self.players, self.cards):
print('{} laid down a {}.'.format(player.name, card))
def reward(self, player):
player.give_cards(self.cards)
player.give_cards(self.bonus)
@property
def tied(self):
for card, player in zip(self.cards, self.players):
if card.value == self.best:
yield player
################################################################################
if __name__ == '__main__':
main()
@qiy2019
Copy link

qiy2019 commented Oct 6, 2021

Awesome!! You made this all out of OOP(Object Oriented Programming)! I didn't know you can do this!

So far I've learned this:

Try:
            # Stuff Here

 Except:
            # Stuff Here

Finally:
            # Stuff Here 

And:

class myfunc():

      def __init__(self, #Stuff here if wanted. ):

              # Code Here
     # more functions if wanted
 

@jdabassett
Copy link

Thank you for sharing this. I am starting my OOP journey and appreciate the ability to dissect and learn from your code. Thank You

@dancanyego
Copy link

Awersome

@damianesteban
Copy link
Author

I'm glad this code has helped. If you have any more questions about OOP in general feel free to reach out.

@dancanyego
Copy link

Awersome

Whats Your best way to aquire The programming logic

@nayakkrmanish
Copy link

Hey there, can't reckon more that your OOPs code is contagious. I have learned many things so far, how are you doing all this bro? Your logic building is meticulous surreally 👏🏻🤩 Any tips and resource could you suggest me?

@damianesteban
Copy link
Author

Hey there, can't reckon more that your OOPs code is contagious. I have learned many things so far, how are you doing all this bro? Your logic building is meticulous surreally 👏🏻🤩 Any tips and resource could you suggest me?

I'm glad it has helped you. What's funny is that I nowadays I wrote a lot more functional code that object-oriented.

In terms of resources, I stick to the traditional Gang of Four OOP Design Patterns. Here is a repo with example in Python:

https://github.com/tuvo1106/python_design_patterns

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