- A randomized deck is split between two players
- The players draw the top card from their decks and add them to the pot
- If the drawn cards are equal, the game goes into War
- Players each draw three more cards and add them to the pot
- Fourth cards are drawn
- If these are equal, the war continues; these and three other cards go into the pot
- When the cards aren't equal, the player with the highest wins and adds the pot to his deck
- Hoyle also allows for "The first to win 3 wars wins the game"
This is an exercise in using __x__() methods. I heard C++ let you rewrite the meanings of operators and recently found out Python does too. I use it in __gt__(self, other), which allows me to compare one card's rank to another with >. I'm pleased with how Pythonic the code looks for Card, Deck, and Player. They could all be improved, but war() needs the most work.
import random as r
war = False
class Card:
'''Cards have numbers as rank and strings as suits'''
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __gt__(self, other):
return self.rank > other.rank
def __str__(self):
face = ["J","Q","K"]
if self.rank == 1 or self.rank == 14:
rank = "A" # If highA, then ace==14; else, ace==1
elif self.rank < 10:
rank = self.rank
else:
rank = face[self.rank-11]
return str(tuple( (rank, self.suit) ))
class Deck:
'''A deck is any set of cards, owned by players or games''''
def __init__(self, n=0, suits=None, highA=True):
span = range(2,n+2) if highA else range(1,n+1)
self.deck = [Card(i,j) for i in span for j in suits]
# reveal deck, good for debugging but not used in game
def __str__(self):
return ','.join([str(card) for card in self.deck])
# redefine += for easy appending
def __iadd__(self, card):
self.deck.append(card)
return self
def __next__(self):
return self.deck.pop(0)
def __len__(self):
return len(self.deck)
def shuffle(self):
r.shuffle(self.deck)
def deal(self, hands):
self.shuffle()
while self.deck:
for hand in hands:
hand += self.__next__()
# append cardlist to this deck
def gets(self, cardlist):
while cardlist:
self += cardlist.pop(0)
class Player:
'''Player #ID plays cards and wins wars'''
def __init__(self, ID):
self.ID = ID
self.hand = Deck()
self.wars_won = 1
def __len__(self):
return self.wars_won
def wins(self, potlist):
global war
print self.ID, "gets pot"
self.hand.gets(potlist)
# "continued" wars count as one win
if war:
self.wars_won += 1
war = False
def draw(self):
return self.hand.__next__()
def war(war_ante=3, wins=3, highA=True):
global war
pot = Deck()
p1,p2 = Player(1),Player(2)
main = Deck(n=13, suits=['C','S','H','D'], highA=highA)
main.deal([p1.hand,p2.hand])
while len(p1.hand) and len(p2.hand) and len(p1)<wins and len(p2)<wins:
p1card, p2card = p1.draw(), p2.draw()
pot.gets([p1card,p2card])
print "p1 plays", p1card, "\np2 plays", p2card
if p1card > p2card:
p1.wins(pot.deck)
elif p2card > p1card:
p2.wins(pot.deck)
else:
print "WAR"
war = True
for i in range(war_ante):
pot.gets([p1.draw(),p2.draw()])
print "p1=",len(p1.hand),"\np2=",len(p2.hand),"\n"
if len(p1.hand) and len(p2.hand):
print "p1" if len(p1) > len(p2) else "p2", "wins"
else:
print "p1" if len(p1.hand) > 0 else "p2", "wins"
war()