-3

I'm trying to make a simplified version of the card game War. In this game, there are two players. Each starts with half of a deck. The players each deal the top card from their decks and whoever has the higher card wins the other player's cards and adds them to the bottom of his deck. If there is a tie, the two cards are eliminated from play. The game ends when one player runs out of cards.

However, I'm having an issue with the pop argument, in that it gives me an error with "pop from empty list".

How can I fix that?

import random

class Card:
    def __init__(self, value, suit):
        self.value = value
        self.suit = suit
    def __str__(self):
        names = ['Jack', 'Queen', 'King', 'Ace']
        if self.value <= 10:
            return '{} of {}'.format(self.value, self.suit)
        else:
            return '{} of {}'.format(names[self.value-11], self.suit)

class CardGroup:
    def __init__(self, cards = []):
        self.cards = cards
    def shuffle(self):
        random.shuffle(self.cards)

class StandardDeck(CardGroup):
    def __init__(self):
        self.cards = []
        for s in ['Hearts', 'Diamonds', 'Clubs', 'Spades']:
            for v in range(2,15):
                self.cards.append(Card(v, s))
    def deal_out(self, num_cards, num_players):
        deal = [[0 for x in range(num_cards)] for y in range(num_players)]
        for i in range(num_cards):
            for k in range(num_players):
                deal[k][i] = self.cards.pop()
        self.deal = deal

deck = StandardDeck()
deck.shuffle()
print("\n===== shuffled deck =====\n")

player1_list = []
player2_list = []
for i in range(26):
    p1_temp = deck.deal_out(26, 2)
    player1_list.append(p1_temp)
    p2_temp = deck.deal_out(26, 2)
    if (p2_temp.__init__() == 1):
        player1_list.append(p2_temp)
        player2_list.append(player1_list.pop(0))
    else:
        player2_list.append(p2_temp)


# Card dealt to Player #1
player1_card = player1_list.pop(0)
print("===== player #1 =====")
print("Card dealt to player #1: \n", player1_card)
print(player1_list)
    
#Card dealt to Player #2
player2_card = player2_list.pop(0)
print("\n===== player #2 =====")
print("Card dealt to player #2: \n", player2_card)
print(player2_list)

# Compare the two cards using overloaded operators
if player1_card == player2_card:
    print("Tie: ", player1_card, "and", player2_card,\
          "are of equal rank")
elif player1_card > player2_card:
    print("Player #1 wins: ", player1_card, \
          "is of higher rank than", player2_card)
else:
    print("Player #2 wins: ", player2_card, \
        "is of higher rank than", player1_card)
    print()
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • https://stackoverflow.com/questions/31216428/python-pop-from-empty-list – Tom McLean Jun 16 '21 at 16:16
  • 3
    It maybe a bug in your code, try to debug it – Trần Gia Bảo Jun 16 '21 at 16:18
  • 4
    You are calling `deck.deal_out` twice, but each time you call it, it empties your deck. – Mark Jun 16 '21 at 16:19
  • 1
    Have a look as [least-astonishment-and-the-mutable-default-argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) and fix the `def __init__(self, cards = []):` before you stumble into that pitfall – Patrick Artner Jun 16 '21 at 17:58

1 Answers1

1

Rather than self.deal = deal in deal_out() you likely want to return the deal.

If you do, some code related to for i in range(26): can be removed as your player hands get populated from deal_out(). You also have some issues of comparing cards when you want to compare card values.

Here are some slight modifications to get you going again:

import random

class Card:
    def __init__(self, value, suit):
        self.value = value
        self.suit = suit
    def __str__(self):
        names = ['Jack', 'Queen', 'King', 'Ace']
        if self.value <= 10:
            return '{} of {}'.format(self.value, self.suit)
        else:
            return '{} of {}'.format(names[self.value-11], self.suit)

class CardGroup:
    def __init__(self, cards = []):
        self.cards = cards
    def shuffle(self):
        random.shuffle(self.cards)

class StandardDeck(CardGroup):
    def __init__(self):
        self.cards = []
        for s in ['Hearts', 'Diamonds', 'Clubs', 'Spades']:
            for v in range(2,15):
                self.cards.append(Card(v, s))
    def deal_out(self, num_cards, num_players):
        deal = [[0 for x in range(num_cards)] for y in range(num_players)]
        for i in range(num_cards):
            for k in range(num_players):
                deal[k][i] = self.cards.pop()
        ## self.deal = deal
        return deal

deck = StandardDeck()
deck.shuffle()
print("\n===== shuffled deck =====\n")

'''
player1_list = []
player2_list = []
for i in range(26):
    p1_temp = deck.deal_out(26, 2)
    player1_list.append(p1_temp)
    p2_temp = deck.deal_out(26, 2)
    if (p2_temp.__init__() == 1):
        player1_list.append(p2_temp)
        player2_list.append(player1_list.pop(0))
    else:
        player2_list.append(p2_temp)
'''
player1_list, player2_list = deck.deal_out(26, 2)

# Card dealt to Player #1
player1_card = player1_list.pop(0)
print("===== player #1 =====")
print("Card dealt to player #1: \n", player1_card)
#print(player1_list)
    
#Card dealt to Player #2
player2_card = player2_list.pop(0)
print("\n===== player #2 =====")
print("Card dealt to player #2: \n", player2_card)
#print(player2_list)

# Compare the two cards using overloaded operators
if player1_card.value == player2_card.value:
    print("Tie: ", player1_card, "and", player2_card,\
          "are of equal rank")
elif player1_card.value > player2_card.value:
    print("Player #1 wins: ", player1_card, \
          "is of higher rank than", player2_card)
else:
    print("Player #2 wins: ", player2_card, \
        "is of higher rank than", player1_card)
    print()
JonSG
  • 10,542
  • 2
  • 25
  • 36
  • 1
    You should probably also fix the `def __init__(self, cards = []):` to be `def __init__(self, cards = None): self.cards = cards or []` to avoid [least-astonishment-and-the-mutable-default-argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – Patrick Artner Jun 16 '21 at 17:57
  • Yes, I agree that would be prudent – JonSG Jun 16 '21 at 18:02