By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,818 Members | 1,223 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,818 IT Pros & Developers. It's quick & easy.

Calling an object from a list

P: 14
I don't know how clear my title is, but I can't think of how to title this problem. I am writing a single card game of War. It is very simple. Every round the deck is populated and shuffled. A single card is dealt to each of two players. The card with the higher value wins, and the player gets a point. If there is a tie, nobody earns the point, and a new round begins. I am reusing code from a blackjack program provided in the book I am working out of. It uses a list to organize each of the players that would be in the blackjack game. I kept the list around so I could use the functions associated with it. However, in the Blackjack game, it compared each players hand value to a dealer. In my program, I want to compare the value of the card the player holds to each other's hand.

the player object is defined like this:

Expand|Select|Wrap|Line Numbers
  1. class War_Player(War_Hand):
  2.     """ A War Player. """
  3.     wins = int(0)
  4.  
  5.     def lose(self):
  6.         print self.name, "loses."
  7.  
  8.     def win(self):
  9.         print self.name, "wins."
  10.         wins += 1
  11.  
  12.     def tie(self):
  13.         print self.name, "ties."
  14.  
and then there is a War_Game object with this code:

Expand|Select|Wrap|Line Numbers
  1. class War_Game(object):
  2.     """ A War Game. """
  3.     def __init__(self, names):      
  4.         self.players = []
  5.         for name in names:
  6.             player = War_Player(name)
  7.             self.players.append(player)
  8.  
  9.         self.dealer = War_Dealer("Dealer")
  10.  
  11.         self.deck = War_Deck()
  12.         self.deck.populate()
  13.         self.deck.shuffle()
  14.  
  15.     def play(self):
  16.         # Make sure deck is populated.
  17.         self.deck.clear(self)
  18.         self.deck.populate(self)
  19.         self.deck.shuffle(self)
  20.         # deal card to everyone
  21.         self.deck.deal(self.players, per_hand = 1)
  22.         for player in self.players:
  23.             print player
  24.  
  25.         # compare each player still playing to each other
  26.         for player in self.players
  27.             if player.total > self.dealer.total:
  28.                 player.win()
  29.             elif player.total < self.dealer.total:
  30.                 player.lose()
  31.             else:
  32.                 player.push()
  33.  
  34.         # remove everyone's cards
  35.         for player in self.players:
  36.             player.clear()
  37.         self.dealer.clear()
  38.  
the bold, italicized, underlined portions are the remnants of the Blackjack code that I can't figure out how to change to fit this. I need to change it to compare each players hand to the other players hand rather than the dealer(which i have removed from the program completely). If you could explain to me how to do it, and why it works that way, that would be great! I am frustrated that I can't seem to figure this out. Thanks in advance for any help you can give!
May 24 '07 #1
Share this Question
Share on Google+
9 Replies


bartonc
Expert 5K+
P: 6,596
Ok. We can do this, but you left out the parent class of War_Player() which is where some of this is going to take place (it looks like). Presumably, one thing that War_Hand() does is
Expand|Select|Wrap|Line Numbers
  1. def __init__(maybeName, whatEver):
  2.     self.name = maybyName
  3.     # etc.
In the sub-class there is one problem that I can see right off:
Expand|Select|Wrap|Line Numbers
  1. class War_Player(War_Hand):
  2.     """ A War Player. """
  3.     ### This is a "class variable, shared by all instances ###
  4.     wins = int(0)
  5.     ### To keep track of this players wins, you need:
  6.     self.wins = 0
  7.     ### do the same thing for losses and ties
  8.  
  9.     def lose(self):
  10.         print self.name, "loses."
  11.  
  12.     def win(self):
  13.         print self.name, "wins."
  14.         ### Change here, too
  15.         self.wins += 1
  16.  
  17.     def tie(self):
  18.         print self.name, "ties."
  19.  
I don't know how clear my title is, but I can't think of how to title this problem. I am writing a single card game of War. It is very simple. Every round the deck is populated and shuffled. A single card is dealt to each of two players. The card with the higher value wins, and the player gets a point. If there is a tie, nobody earns the point, and a new round begins. I am reusing code from a blackjack program provided in the book I am working out of. It uses a list to organize each of the players that would be in the blackjack game. I kept the list around so I could use the functions associated with it. However, in the Blackjack game, it compared each players hand value to a dealer. In my program, I want to compare the value of the card the player holds to each other's hand.

the player object is defined like this:

Expand|Select|Wrap|Line Numbers
  1. class War_Player(War_Hand):
  2.     """ A War Player. """
  3.     wins = int(0)
  4.  
  5.     def lose(self):
  6.         print self.name, "loses."
  7.  
  8.     def win(self):
  9.         print self.name, "wins."
  10.         wins += 1
  11.  
  12.     def tie(self):
  13.         print self.name, "ties."
  14.  
and then there is a War_Game object with this code:

Expand|Select|Wrap|Line Numbers
  1. class War_Game(object):
  2.     """ A War Game. """
  3.     def __init__(self, names):      
  4.         self.players = []
  5.         for name in names:
  6.             player = War_Player(name)
  7.             self.players.append(player)
  8.  
  9.         self.dealer = War_Dealer("Dealer")
  10.  
  11.         self.deck = War_Deck()
  12.         self.deck.populate()
  13.         self.deck.shuffle()
  14.  
  15.     def play(self):
  16.         # Make sure deck is populated.
  17.         self.deck.clear(self)
  18.         self.deck.populate(self)
  19.         self.deck.shuffle(self)
  20.         # deal card to everyone
  21.         self.deck.deal(self.players, per_hand = 1)
  22.         for player in self.players:
  23.             print player
  24.  
  25.         # compare each player still playing to each other
  26.         for player in self.players
  27.             if player.total > self.dealer.total:
  28.                 player.win()
  29.             elif player.total < self.dealer.total:
  30.                 player.lose()
  31.             else:
  32.                 player.push()
  33.  
  34.         # remove everyone's cards
  35.         for player in self.players:
  36.             player.clear()
  37.         self.dealer.clear()
  38.  
the bold, italicized, underlined portions are the remnants of the Blackjack code that I can't figure out how to change to fit this. I need to change it to compare each players hand to the other players hand rather than the dealer(which i have removed from the program completely). If you could explain to me how to do it, and why it works that way, that would be great! I am frustrated that I can't seem to figure this out. Thanks in advance for any help you can give![/quote]
May 24 '07 #2

P: 14
I'm sorry it's taken me so long to get back on here about this problem, but with school coming to a close, things have been crazy!

Earlier I posted too little code, and now I fear that I'm going to post too much. I think, though, that I'd rather post too much and get a complete answer than post too little and leave feeling confused. Here is the entirety of the program, followed by the two modules that I import.

Expand|Select|Wrap|Line Numbers
  1. # Blackjack
  2. # From 1 to 7 players compete against a dealer
  3.  
  4. import cards, games     
  5.  
  6. class War_Card(cards.Card):
  7.     """ A War Card. """
  8.     ACE_VALUE = 11
  9.  
  10.     def get_value(self):
  11.         value = War_Card.RANKS.index(self.rank) + 1
  12.         if value > 10:
  13.             value = 10
  14.         else:
  15.             value = None
  16.         return value
  17.  
  18.     value = property(get_value)
  19.  
  20.  
  21. class War_Deck(cards.Deck):
  22.     """ A War Deck. """
  23.     def populate(self):
  24.         for suit in War_Card.SUITS: 
  25.             for rank in War_Card.RANKS: 
  26.                 self.cards.append(War_Card(rank, suit))
  27.  
  28.  
  29. class War_Hand(cards.Hand):
  30.     """ A War Hand. """
  31.     def __init__(self, name):
  32.         super(War_Hand, self).__init__()
  33.         self.name = name
  34.  
  35.     def __str__(self):
  36.         rep = self.name + ":\t" + super(War_Hand, self).__str__()  
  37.         if self.total:
  38.             rep += "(" + str(self.total) + ")"        
  39.         return rep
  40.  
  41.     def get_total(self):
  42.         # if a card in the hand has value of None, then total is None
  43.         for card in self.cards:
  44.             if not card.value:
  45.                 return None
  46.  
  47.         # add up card values, treat each Ace as 1
  48.         total = 0
  49.         for card in self.cards:
  50.               total += card.value
  51.  
  52.         return total
  53.  
  54.     total = property(get_total)
  55.  
  56. class War_Player(War_Hand):
  57.     """ A War Player. """
  58.     def _init__(self, wins = int(0)):
  59.         wins = 0
  60.  
  61.     def lose(self):
  62.         print self.name, "loses."
  63.  
  64.     def win(self):
  65.         print self.name, "wins."
  66.         self.wins = self.wins + 1
  67.  
  68. class War_Game(object):
  69.     """ A War Game. """
  70.     def __init__(self, names):      
  71.         self.players = []
  72.         for name in names:
  73.             player = War_Player(name)
  74.             self.players.append(player)
  75.  
  76.         self.deck = War_Deck()
  77.         self.deck.populate()
  78.         self.deck.shuffle()
  79.  
  80.     def play(self, game):
  81.         # Make sure deck is populated.
  82.         self.deck.clear()
  83.         self.deck.populate()
  84.         self.deck.shuffle()
  85.         # deal card to everyone
  86.         self.deck.deal(self.players, per_hand = 1)
  87.         for player in self.players:
  88.             print player
  89.  
  90.         # compare each player playing to each other
  91.             if ?????.value > ?????.value:
  92.                 ?????.win()
  93.                 ?????.lose()
  94.             elif ?????.value < ?????.value:
  95.                 ?????.win()
  96.                 ?????.lose()
  97.             else:
  98.                 print "That was a tie. Nobody get's a point."
  99.  
  100.  
  101.         # remove everyone's cards
  102.         for player in self.players:
  103.             player.clear()
  104.         self.dealer.clear()
  105.  
  106.  
  107. def main():
  108.     print "\t\tWelcome to War!\n"
  109.     print
  110.     """\n\n\tThere are two players. Each player recieves a card.
  111.     print "The player with the highest card value wins and gets a point.
  112.     In the event of a tie, neither player wins, and no points are awarded."
  113.     """
  114.  
  115.     names = []
  116.     number = 2
  117.     for i in range(number):
  118.         name = raw_input("Enter player name: ")
  119.         names.append(name)
  120.     print
  121.  
  122.     game = War_Game(names)
  123.  
  124.     again = None
  125.     while again != "n":
  126.         game.play(game)
  127.         again = games.ask_yes_no("\nDo you want to play again?: ")
  128.  
  129.  
  130. main()
  131. raw_input("\n\nPress the enter key to exit.")
  132.  
Here is the cards module:
Expand|Select|Wrap|Line Numbers
  1. # Cards Module
  2. # Basic classes for a game with playing cards
  3.  
  4. class Card(object):
  5.     """ A playing card. """
  6.     RANKS = ["A", "2", "3", "4", "5", "6", "7",
  7.              "8", "9", "10", "J", "Q", "K"]
  8.     SUITS = ["c", "d", "h", "s"]
  9.  
  10.     def __init__(self, rank, suit, face_up = True):
  11.         self.rank = rank
  12.         self.suit = suit
  13.         self.is_face_up = face_up
  14.  
  15.     def __str__(self):
  16.         if self.is_face_up:
  17.             rep = self.rank + self.suit
  18.         else:
  19.             rep = "XX"
  20.         return rep
  21.  
  22.     def flip(self):
  23.         self.is_face_up = not self.is_face_up
  24.  
  25.  
  26. class Hand(object):
  27.     """ A hand of playing cards. """
  28.     def __init__(self):
  29.         self.cards = []
  30.  
  31.     def __str__(self):
  32.         if self.cards:
  33.            rep = ""
  34.            for card in self.cards:
  35.                rep += str(card) + "\t"
  36.         else:
  37.             rep = "<empty>"
  38.         return rep
  39.  
  40.     def clear(self):
  41.         self.cards = []
  42.  
  43.     def add(self, card):
  44.         self.cards.append(card)
  45.  
  46.     def give(self, card, other_hand):
  47.         self.cards.remove(card)
  48.         other_hand.add(card)
  49.  
  50.  
  51. class Deck(Hand):
  52.     """ A deck of playing cards. """
  53.     def populate(self):
  54.         for suit in Card.SUITS:
  55.             for rank in Card.RANKS: 
  56.                 self.add(Card(rank, suit))
  57.  
  58.     def shuffle(self):
  59.         import random
  60.         random.shuffle(self.cards)
  61.  
  62.     def deal(self, hands, per_hand = 1):
  63.         for rounds in range(per_hand):
  64.             for hand in hands:
  65.                 if self.cards:
  66.                     top_card = self.cards[0]
  67.                     self.give(top_card, hand)
  68.                 else:
  69.                     print "Can't continue deal. Out of cards!"
  70.  
  71.  
  72.  
  73. if __name__ == "__main__":
  74.     print "This is a module with classes for playing cards."
  75.     raw_input("\n\nPress the enter key to exit.")
  76.  
and finally, here is the games module:

Expand|Select|Wrap|Line Numbers
  1. # Games
  2. # Demonstrates module creation
  3.  
  4. class Player(object):
  5.     """ A player for a game. """
  6.     def __init__(self, name, score = 0):
  7.         self.name = name
  8.         self.score = score
  9.  
  10.     def __str__(self):
  11.         rep = self.name + ":\t" + str(self.score)
  12.         return rep
  13.  
  14.  
  15. def ask_yes_no(question):
  16.     """Ask a yes or no question."""
  17.     response = None
  18.     while response not in ("y", "n"):
  19.         response = raw_input(question).lower()
  20.     return response
  21.  
  22.  
  23. def ask_number(question, low, high):
  24.     """Ask for a number within a range."""
  25.     response = None
  26.     while response not in range(low, high):
  27.         response = int(raw_input(question))
  28.     return response
  29.  
  30.  
  31. if __name__ == "__main__":
  32.     print "You ran this module directly (and did not 'import' it)."
  33.     raw_input("\n\nPress the enter key to exit.")
  34.  

I'm sorry if I'm breaking forum etiquitte by posting too much code in here. My main problem with this, at least as far as I can notice, is that I can't figure out how to compare the two hands and then call the win and lose functions of the winner and loser. I have a series of ????? placed in that portion of the code. If anybody could please tell me how this works I would finall be able to get this done! Unless there's some other critical bug in this program...x_X

Thanks!
May 29 '07 #3

bartonc
Expert 5K+
P: 6,596
Not too much code for the forum. Just too much for me at the moment (not enough coffee). Back soon.
May 29 '07 #4

bvdet
Expert Mod 2.5K+
P: 2,851
Add a __cmp__ method to Player to enable sorting a list of Players on the Players' scores:
Expand|Select|Wrap|Line Numbers
  1. class Player(object):
  2.     """ A player for a game. """
  3.     def __init__(self, name, score = 0):
  4.         self.name = name
  5.         self.score = score
  6.  
  7.     def __str__(self):
  8.         rep = self.name + ":\t" + str(self.score)
  9.         return rep
  10.  
  11.     def __cmp__(self, other):
  12.         return cmp(self.score, other.score)
You will have to update each Players' 'score' attribute based on the rank of the cards dealt. Sort self.players in War_Game.play():
Expand|Select|Wrap|Line Numbers
  1. self.players.sort()
If the last player's score (self.players[-1].score) is equal to the next to last player's score, there is a tie and no one wins. Otherwise, the last player wins and everyone else loses. I have not tested this, but I think it will work.
May 29 '07 #5

P: 14
wow. Thanks! I'm not at a machine with python on it, so I cannot test that out, but it sounds like it could work. I am not familiar with the _cmp_ method, though, and I don't know what that is doing. If you could explain that to me, that would be nice!
May 29 '07 #6

bvdet
Expert Mod 2.5K+
P: 2,851
wow. Thanks! I'm not at a machine with python on it, so I cannot test that out, but it sounds like it could work. I am not familiar with the _cmp_ method, though, and I don't know what that is doing. If you could explain that to me, that would be nice!
'__cmp__' is a special method used by the comparison operators to compare two objects (self, other). If undefined, objects are compared by identity. Alternatively, rich comparison operations can be defined such as '__lt__', '__le__', '__eq__', etc.
May 29 '07 #7

P: 14
'__cmp__' is a special method used by the comparison operators to compare two objects (self, other). If undefined, objects are compared by identity. Alternatively, rich comparison operations can be defined such as '__lt__', '__le__', '__eq__', etc.
Thanks alot. I'm actually trying to teach myself python out of a book, and I'm familiar with __str__ and __init__, but the __cmp__ special method is new to me.

Expand|Select|Wrap|Line Numbers
  1. def __cmp__(self, other):
  2.         return cmp(self.score, other.score)
  3.  
When I use this, and say the self.score is 10 while the other.score is 8, what would the returned value be?
May 29 '07 #8

bvdet
Expert Mod 2.5K+
P: 2,851
Thanks alot. I'm actually trying to teach myself python out of a book, and I'm familiar with __str__ and __init__, but the __cmp__ special method is new to me.

Expand|Select|Wrap|Line Numbers
  1. def __cmp__(self, other):
  2.         return cmp(self.score, other.score)
  3.  
When I use this, and say the self.score is 10 while the other.score is 8, what would the returned value be?
-1, 0, 1 if <, ==, > respectively. The list sort method interprets the return value transparently. If you want it to sort in reverse order, simply negate the return value.
May 29 '07 #9

P: 14
Thanks. That's really neat. I'll let you know how it works out for me!
May 30 '07 #10

Post your reply

Sign in to post your reply or Sign up for a free account.