Calling an object from a list

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Cjllewey369
    New Member
    • Mar 2007
    • 14

    Calling an object from a list

    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:

    [CODE=python]
    class War_Player(War_ Hand):
    """ A War Player. """
    wins = int(0)

    def lose(self):
    print self.name, "loses."

    def win(self):
    print self.name, "wins."
    wins += 1

    def tie(self):
    print self.name, "ties."
    [/CODE]

    and then there is a War_Game object with this code:

    [CODE=python]
    class War_Game(object ):
    """ A War Game. """
    def __init__(self, names):
    self.players = []
    for name in names:
    player = War_Player(name )
    self.players.ap pend(player)

    self.dealer = War_Dealer("Dea ler")

    self.deck = War_Deck()
    self.deck.popul ate()
    self.deck.shuff le()

    def play(self):
    # Make sure deck is populated.
    self.deck.clear (self)
    self.deck.popul ate(self)
    self.deck.shuff le(self)
    # deal card to everyone
    self.deck.deal( self.players, per_hand = 1)
    for player in self.players:
    print player

    # compare each player still playing to each other
    for player in self.players
    if player.total > self.dealer.tot al:
    player.win()
    elif player.total < self.dealer.tot al:
    player.lose()
    else:
    player.push()

    # remove everyone's cards
    for player in self.players:
    player.clear()
    self.dealer.cle ar()
    [/CODE]

    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!
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    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
    Code:
    def __init__(maybeName, whatEver):
        self.name = maybyName
        # etc.
    In the sub-class there is one problem that I can see right off:
    Code:
    class War_Player(War_Hand):
        """ A War Player. """
        ### This is a "class variable, shared by all instances ###
        wins = int(0)
        ### To keep track of this players wins, you need:
        self.wins = 0
        ### do the same thing for losses and ties
     
        def lose(self):
            print self.name, "loses."
     
        def win(self):
            print self.name, "wins."
            ### Change here, too
            self.wins += 1
     
        def tie(self):
            print self.name, "ties."
    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:

    [CODE=python]
    class War_Player(War_ Hand):
    """ A War Player. """
    wins = int(0)

    def lose(self):
    print self.name, "loses."

    def win(self):
    print self.name, "wins."
    wins += 1

    def tie(self):
    print self.name, "ties."
    [/CODE]

    and then there is a War_Game object with this code:

    [CODE=python]
    class War_Game(object ):
    """ A War Game. """
    def __init__(self, names):
    self.players = []
    for name in names:
    player = War_Player(name )
    self.players.ap pend(player)

    self.dealer = War_Dealer("Dea ler")

    self.deck = War_Deck()
    self.deck.popul ate()
    self.deck.shuff le()

    def play(self):
    # Make sure deck is populated.
    self.deck.clear (self)
    self.deck.popul ate(self)
    self.deck.shuff le(self)
    # deal card to everyone
    self.deck.deal( self.players, per_hand = 1)
    for player in self.players:
    print player

    # compare each player still playing to each other
    for player in self.players
    if player.total > self.dealer.tot al:
    player.win()
    elif player.total < self.dealer.tot al:
    player.lose()
    else:
    player.push()

    # remove everyone's cards
    for player in self.players:
    player.clear()
    self.dealer.cle ar()
    [/CODE]

    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]

    Comment

    • Cjllewey369
      New Member
      • Mar 2007
      • 14

      #3
      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.

      [CODE=python]
      # Blackjack
      # From 1 to 7 players compete against a dealer

      import cards, games

      class War_Card(cards. Card):
      """ A War Card. """
      ACE_VALUE = 11

      def get_value(self) :
      value = War_Card.RANKS. index(self.rank ) + 1
      if value > 10:
      value = 10
      else:
      value = None
      return value

      value = property(get_va lue)


      class War_Deck(cards. Deck):
      """ A War Deck. """
      def populate(self):
      for suit in War_Card.SUITS:
      for rank in War_Card.RANKS:
      self.cards.appe nd(War_Card(ran k, suit))


      class War_Hand(cards. Hand):
      """ A War Hand. """
      def __init__(self, name):
      super(War_Hand, self).__init__( )
      self.name = name

      def __str__(self):
      rep = self.name + ":\t" + super(War_Hand, self).__str__()
      if self.total:
      rep += "(" + str(self.total) + ")"
      return rep

      def get_total(self) :
      # if a card in the hand has value of None, then total is None
      for card in self.cards:
      if not card.value:
      return None

      # add up card values, treat each Ace as 1
      total = 0
      for card in self.cards:
      total += card.value

      return total

      total = property(get_to tal)

      class War_Player(War_ Hand):
      """ A War Player. """
      def _init__(self, wins = int(0)):
      wins = 0

      def lose(self):
      print self.name, "loses."

      def win(self):
      print self.name, "wins."
      self.wins = self.wins + 1

      class War_Game(object ):
      """ A War Game. """
      def __init__(self, names):
      self.players = []
      for name in names:
      player = War_Player(name )
      self.players.ap pend(player)

      self.deck = War_Deck()
      self.deck.popul ate()
      self.deck.shuff le()

      def play(self, game):
      # Make sure deck is populated.
      self.deck.clear ()
      self.deck.popul ate()
      self.deck.shuff le()
      # deal card to everyone
      self.deck.deal( self.players, per_hand = 1)
      for player in self.players:
      print player

      # compare each player playing to each other
      if ?????.value > ?????.value:
      ?????.win()
      ?????.lose()
      elif ?????.value < ?????.value:
      ?????.win()
      ?????.lose()
      else:
      print "That was a tie. Nobody get's a point."


      # remove everyone's cards
      for player in self.players:
      player.clear()
      self.dealer.cle ar()


      def main():
      print "\t\tWelcom e to War!\n"
      print
      """\n\n\tTh ere are two players. Each player recieves a card.
      print "The player with the highest card value wins and gets a point.
      In the event of a tie, neither player wins, and no points are awarded."
      """

      names = []
      number = 2
      for i in range(number):
      name = raw_input("Ente r player name: ")
      names.append(na me)
      print

      game = War_Game(names)

      again = None
      while again != "n":
      game.play(game)
      again = games.ask_yes_n o("\nDo you want to play again?: ")


      main()
      raw_input("\n\n Press the enter key to exit.")
      [/CODE]

      Here is the cards module:
      [CODE=python]
      # Cards Module
      # Basic classes for a game with playing cards

      class Card(object):
      """ A playing card. """
      RANKS = ["A", "2", "3", "4", "5", "6", "7",
      "8", "9", "10", "J", "Q", "K"]
      SUITS = ["c", "d", "h", "s"]

      def __init__(self, rank, suit, face_up = True):
      self.rank = rank
      self.suit = suit
      self.is_face_up = face_up

      def __str__(self):
      if self.is_face_up :
      rep = self.rank + self.suit
      else:
      rep = "XX"
      return rep

      def flip(self):
      self.is_face_up = not self.is_face_up


      class Hand(object):
      """ A hand of playing cards. """
      def __init__(self):
      self.cards = []

      def __str__(self):
      if self.cards:
      rep = ""
      for card in self.cards:
      rep += str(card) + "\t"
      else:
      rep = "<empty>"
      return rep

      def clear(self):
      self.cards = []

      def add(self, card):
      self.cards.appe nd(card)

      def give(self, card, other_hand):
      self.cards.remo ve(card)
      other_hand.add( card)


      class Deck(Hand):
      """ A deck of playing cards. """
      def populate(self):
      for suit in Card.SUITS:
      for rank in Card.RANKS:
      self.add(Card(r ank, suit))

      def shuffle(self):
      import random
      random.shuffle( self.cards)

      def deal(self, hands, per_hand = 1):
      for rounds in range(per_hand) :
      for hand in hands:
      if self.cards:
      top_card = self.cards[0]
      self.give(top_c ard, hand)
      else:
      print "Can't continue deal. Out of cards!"



      if __name__ == "__main__":
      print "This is a module with classes for playing cards."
      raw_input("\n\n Press the enter key to exit.")
      [/CODE]

      and finally, here is the games module:

      [CODE=python]
      # Games
      # Demonstrates module creation

      class Player(object):
      """ A player for a game. """
      def __init__(self, name, score = 0):
      self.name = name
      self.score = score

      def __str__(self):
      rep = self.name + ":\t" + str(self.score)
      return rep


      def ask_yes_no(ques tion):
      """Ask a yes or no question."""
      response = None
      while response not in ("y", "n"):
      response = raw_input(quest ion).lower()
      return response


      def ask_number(ques tion, low, high):
      """Ask for a number within a range."""
      response = None
      while response not in range(low, high):
      response = int(raw_input(q uestion))
      return response


      if __name__ == "__main__":
      print "You ran this module directly (and did not 'import' it)."
      raw_input("\n\n Press the enter key to exit.")
      [/CODE]


      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!

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        Not too much code for the forum. Just too much for me at the moment (not enough coffee). Back soon.

        Comment

        • bvdet
          Recognized Expert Specialist
          • Oct 2006
          • 2851

          #5
          Add a __cmp__ method to Player to enable sorting a list of Players on the Players' scores:[code=Python]class Player(object):
          """ A player for a game. """
          def __init__(self, name, score = 0):
          self.name = name
          self.score = score

          def __str__(self):
          rep = self.name + ":\t" + str(self.score)
          return rep

          def __cmp__(self, other):
          return cmp(self.score, other.score)[/code]You will have to update each Players' 'score' attribute based on the rank of the cards dealt. Sort self.players in War_Game.play() :[code=Python]self.players.so rt()[/code]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.

          Comment

          • Cjllewey369
            New Member
            • Mar 2007
            • 14

            #6
            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!

            Comment

            • bvdet
              Recognized Expert Specialist
              • Oct 2006
              • 2851

              #7
              Originally posted by Cjllewey369
              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.

              Comment

              • Cjllewey369
                New Member
                • Mar 2007
                • 14

                #8
                Originally posted by bvdet
                '__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.

                [CODE=python]
                def __cmp__(self, other):
                return cmp(self.score, other.score)
                [/CODE]

                When I use this, and say the self.score is 10 while the other.score is 8, what would the returned value be?

                Comment

                • bvdet
                  Recognized Expert Specialist
                  • Oct 2006
                  • 2851

                  #9
                  Originally posted by Cjllewey369
                  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.

                  [CODE=python]
                  def __cmp__(self, other):
                  return cmp(self.score, other.score)
                  [/CODE]

                  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.

                  Comment

                  • Cjllewey369
                    New Member
                    • Mar 2007
                    • 14

                    #10
                    Thanks. That's really neat. I'll let you know how it works out for me!

                    Comment

                    Working...