1

The CPU and User are getting repeated cards. I've used the shuffle function, as well as pop. Is there a way to prevent the user and CPU from getting repeated cards?

Here is an example of execution:

Here are your cards:
1) The 10 of Clubs
2) The 4 of Diamonds
3) The 6 of Diamonds
4) The 7 of Clubs
5) The 10 of Clubs

To play cards, simply type their number one at a time. When done, input blank

2 1 3 4

You played: The 4 of Diamonds The 10 of Clubs The 6 of Diamonds The 7 of Clubs

CPU played: The Jack of Spades The Jack of Spades

As you can see, the User was given the 10 of Clubs twice.

My code:

import random
import math
from collections import Counter
print("Gui-less poker sucks, but it sure is addicting probably")
if 1:
    deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
    random.shuffle(deck)
    hcardss = [""]
    hcardsc = [""]
    hcardsh = [""]
    ccardss = [""]
    ccardsc = [""]
    ccardsh = [""]
    ingame = "true"
    while (ingame == "true"):
        undone = 5
        while (undone > 0):
            card = deck.pop()
            # print(card)
            temp = card / 13
            temp2 = card / 4
            temp = math.floor(temp)
            temp2 = math.floor(temp2)
            temp = temp + 1
            # temp2 = temp2 + 1
            #print(temp)
            #print(temp2)
            # undone -= 1
            hcardss.append(temp)
            hcardsc.append(temp2)
            if (temp == 1):
                temp3 = " of Spades"
            elif (temp == 2):
                temp3 = " of Diamonds"
            elif (temp == 3):
                temp3 = " of Clubs"
            else:
                temp3 = " of Hearts"
            if (temp2 == 10):
                temp4 = "Jack"
            elif (temp2 == 11):
                temp4 = "Queen"
            elif (temp2 == 12):
                temp4 = "King"
            elif (temp2 == 13):
                temp4 = "Ace"
            else:
                temp4 = str(temp2 + 1)
            # print("Your card was the " + temp4 + temp3)
            hcardsh.append("The " + temp4 + temp3)
            undone -= 1
        undone = 5
        random.shuffle(deck)
        while (undone > 0):
            # THIS ONE IS THE COMPUTER
            card = deck.pop()
            # print(card)
            temp = card / 13
            temp2 = card / 4
            temp = math.floor(temp)
            temp2 = math.floor(temp2)
            temp = temp + 1
            # temp2 = temp2 + 1
            #print(temp)
            #print(temp2)
            # undone -= 1
            ccardss.append(temp)
            ccardsc.append(temp2)
            if (temp == 1):
                temp3 = " of Spades"
            elif (temp == 2):
                temp3 = " of Diamonds"
            elif (temp == 3):
                temp3 = " of Clubs"
            else:
                temp3 = " of Hearts"
            if (temp2 == 10):
                temp4 = "Jack"
            elif (temp2 == 11):
                temp4 = "Queen"
            elif (temp2 == 12):
                temp4 = "King"
            elif (temp2 == 13):
                temp4 = "Ace"
                temp4 = str(temp2 + 1)
            # print("Your card was the " + temp4 + temp3)
            ccardsh.append("The " + temp4 + temp3)
            undone -= 1
        print()
        print()
        print()
        print("Here are your cards:")
        print("1) " + hcardsh[1])
        print("2) " + hcardsh[2])
        print("3) " + hcardsh[3])
        print("4) " + hcardsh[4])
        print("5) " + hcardsh[5])
        print("To play cards, simply type their number one at a time. When done, input blank")
        instant = "true"
        doneinput = "false"
        hplay = [""]
        while (doneinput == "false"):
            latestinput = input("> ")
            if (latestinput == ""):
                if (instant == "true"):
                    print("Okay, you fold")
                    ingame = "false"
                    exit()
                doneinput = "true"
            else:
                if (int(latestinput) in hplay):
                    print("You already picked that one!")
                else:
                    hplay.append(int(latestinput))
        # print("The cards you played are " + str(hplay))
        doneinput = "false"
        cplay = [""]
        while (doneinput == "false"):
            latestinput = random.randint(1,5)
            if (latestinput == ""):
                doneinput = "true"
            else:
                if (int(latestinput) in cplay):
                    doneinput = "true"
                else:
                    cplay.append(int(latestinput))
        #print("So you played " + str(hplay))
        #print("And the cpu played " + str(cplay))
        #print("So you played the " + hcardsh[hplay[1]] + hcardsh[hplay[2]]
        times = len(hplay)
        # times = times - 1
        hplayh = [""]
        cplayh = [""]
        sub = 1
        print()
        print()
        print("You played:")
        while (sub < times):
            hplayh.append(hcardsh[hplay[sub]])
            print(hcardsh[hplay[sub]])
            sub += 1
        sub = 1
        times = len(cplay)
        print()
        print()
        print("CPU played:")
        while (sub < times):
            cplayh.append(ccardsh[cplay[sub]])
            print(ccardsh[cplay[sub]])
            sub += 1
        #print(str(hplay)
        #print(str(cplayh))
        hscore = 0
        cscore = 0
        #checker = 1
        #highnumber = 0
        #quantity = [""]
        #quancheck = 0
        htrans = [""]
        temp5 = 1
        while (len(hplay) > temp5):
            htrans.append(int(hcardsc[hplay]))
            temp5 += 1
        ctrans = [""]
        temp5 = 1
        while (len(cplay) > temp5):
            ctrans.append(int(ccardsc[cplay]))
            temp5 += 1

        hoccur = Counter(htrans).most_common()
        coccur = Counter(ctrans).most_common()
        print(hoccur)
        #while (len(hplay) > checker):
         #   if (hcardsc[hplay[checker]] > highnumber):
          #      quancheck += 1
           # quantity.append(quancheck)
            #checker += 1


        ingame = "false"
Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
  • 3
    You can create a `set` (or `list` if you really want) of cards, pick a random element and remove it. Then you can't possibly get the same card next. – byxor Jul 20 '17 at 16:52
  • I think you should move `deck`'s declaration to inside the outer while loop. – cs95 Jul 20 '17 at 16:57
  • Also I'm pretty sure this could happen if it gets two numbers like `14` and `15` as the division of these numbers by `4` and `13` return the same values. – Professor_Joykill Jul 20 '17 at 16:59
  • use a seed for the random function, timestamp will be a good seed – Stack Jul 20 '17 at 17:00
  • `ingame = "true"` .... why don't you use boolean, `ingame=True`? – depperm Jul 20 '17 at 17:04
  • Possible duplicate of [How to prevent repeated random values?](https://stackoverflow.com/questions/45198173/how-to-prevent-repeated-random-values) – Herb Jul 21 '17 at 04:41

2 Answers2

1

The way you generate a card number between 1 and 52 by shuffling the list, and popping values out of it is correct.

The problem lies in the way you generate the suit and value of the card from its number.

For example,

  • floor(26/4) = 7, floor(27/4) = 7
  • floor(26/13) = 2, floor(27/13) = 2

so 26 and 27 will be interpreted as the same card.

Keeping your original idea, you could rather use the quotient and remainder of the division by 13:

q = card_num // 13 # integer division
r = card_num % 13  # modulo operator

or, both at once, using divmod:

q, r = divmod(26, 13)
print(q,r)
# (2, 0)
q, r = divmod(27, 13)
print(q,r)
# (2, 1)

You will have 0 <= q <= 3 and 0 <= r <= 13

As a side note:
You could improve a few things in the code. A simple change:

deck = list(range(1, 53))

will be shorter! ;)

Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
0

this seems like a great opportunity to learn to work with classes... I always think card games make excelent test grounds for classes

first define a card class

class Card(object):
    def __init__(self,value,suite):
        self.value = value
        self.suite = suite
    def __str__(self):
       # override behaviour of printing a card object
       card_names = ["Ace","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King"]
        return card_names[self.value]

    def __repr__(self):
        #override the repr of a card to print the card name and suite
        suites = "Clubs Spades Diamonds Hearts"
        return "%s of %s"%(self,suites[self.suite])

    def __cmp__(self,other_card):
        return cmp(self.value,other_card.value)

then a deck class that contains all of our cards

class Deck(object):
    def __init__(self):
        self.cards = []
        for suite in range(4):
            for value in range(13):
                self.cards.append(Card(value,suite))
    def shuffle(self):
        self.cards.shuffle()
    def deal(self):
        if self.cards:
           return self.cards.pop()
        raise StopIteration("Out Of Cards...")
    def __len__(self):
        return len(self.cards)

now you can create a play method

def play_game():
    deck = Deck()
    player_1 = [deck.deal() for _ in range(5) ] # deal 5 cards to player1
    player_2 = [deck.deal() for _ in range(5) ] # deal 5 cards to player2(cpu)
    game_over = False
    while not game_over:
    for i,card in enumerate(player_1):
        #play a turn
        print("%d. %r"%(i,card))
        player_1.append(deck.deal()
        player_2.append(deck.deal()
     print("Winner is Player 1")

then your main program loop simply is

while still_playing:
     play_game()
     still_playing = check_with_player()
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Small nitpick: You've written `suite` instead of `suit` and have a few other typos in the text. – byxor Jul 24 '17 at 09:53