patternpythonMinor
Texas Hold'em classes
Viewed 0 times
holdclassestexas
Problem
I am working on a simple Texas Hold'Em dealing simulator. I am new to Python and was hoping to get some advice on my use of classes here. I feel like I am not using them as efficiently as possible, especially when dealing out the player cards. Specifically, I feel like the
```
from random import shuffle
class TexasHoldem:
#create deck
def __init__(self):
values = ['Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']
suites = ['Heart', 'Spade', 'Club', 'Diamond']
self.deck = [j + " " + i for j in values for i in suites]
#shuffle deck
def shuffle(self):
shuffle(self.deck)
#deal for players
def deal(self, n_players):
count = 0
#card 1 list (will be shuffled, delt 'around the table' as if a real stack)
playercard1 = list()
while count < n_players:
card1 = self.deck[count]
playercard1.append(card1)
count += 1
#remove cards from deck that were delt
for i in playercard1:
self.deck.remove(i)
count = 0
#card 2 list
playercard2 = list()
while count < n_players:
card2 = self.deck[count]
playercard2.append(card2)
count += 1
#remove cards from deck delt for 2nd card
for i in playercard2:
self.deck.remove(i)
#merge cards of playercard1 and playercard2 into set
self.playerhand = zip(playercard1, playercard2)
#define the flop
def flop(self):
#burn a card
del self.deck[0]
#lay down three
self.flopcards = self.deck[0:3]
#delete flop from deck
for i in self.flopcards:
self.deck.remove(i)
#same as flop for turn and river
def turn(self):
del self
def deal(self, n_players) could be simplified instead of using playercard1 and playercard2, and deleting the items from the "deck".```
from random import shuffle
class TexasHoldem:
#create deck
def __init__(self):
values = ['Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']
suites = ['Heart', 'Spade', 'Club', 'Diamond']
self.deck = [j + " " + i for j in values for i in suites]
#shuffle deck
def shuffle(self):
shuffle(self.deck)
#deal for players
def deal(self, n_players):
count = 0
#card 1 list (will be shuffled, delt 'around the table' as if a real stack)
playercard1 = list()
while count < n_players:
card1 = self.deck[count]
playercard1.append(card1)
count += 1
#remove cards from deck that were delt
for i in playercard1:
self.deck.remove(i)
count = 0
#card 2 list
playercard2 = list()
while count < n_players:
card2 = self.deck[count]
playercard2.append(card2)
count += 1
#remove cards from deck delt for 2nd card
for i in playercard2:
self.deck.remove(i)
#merge cards of playercard1 and playercard2 into set
self.playerhand = zip(playercard1, playercard2)
#define the flop
def flop(self):
#burn a card
del self.deck[0]
#lay down three
self.flopcards = self.deck[0:3]
#delete flop from deck
for i in self.flopcards:
self.deck.remove(i)
#same as flop for turn and river
def turn(self):
del self
Solution
Your code does a few things repetitively:
I'll go through the problems with this:
Instead you could either:
-
Pop the amount of cards you need.
-
Slice the amount of items you need and then delete them.
You should notice that I take from the end of the list, this is as you aren't using a queue and so they will be faster.
The other main code you use is:
This uses the same code as before, but burns one card.
You can then just make two functions to do what most of your code is doing at the moment.
This then makes the rest of your code simple and easy to read and use.
Other than the above I'd:
This results in something like:
count = 0
playercard1 = list()
while count < n_players:
card1 = self.deck[count]
playercard1.append(card1)
count += 1
for i in playercard1:
self.deck.remove(i)I'll go through the problems with this:
- You manually increment
count, this is something that you should do withrange.
- You manually index every item.
- You manually append to a list.
- You manually
removeeach card from the deck, this causes the list to shift, and causes a small search of the list. (\$O(n)\$ complexity)
Instead you could either:
-
Pop the amount of cards you need.
pop = self.deck.pop
playercard1 = [pop() for _ in range(n_players)]-
Slice the amount of items you need and then delete them.
playercard1 = self.deck[-n_players:]
del self.deck[-n_players:]You should notice that I take from the end of the list, this is as you aren't using a queue and so they will be faster.
The other main code you use is:
del self.deck[0]
self.flopcards = self.deck[0:3]
del self.deck[0:3]This uses the same code as before, but burns one card.
You can then just make two functions to do what most of your code is doing at the moment.
def take(self, number_cards):
pop = self.deck.pop
return [pop() for _ in range(number_cards)]
def draw(self, number_cards):
self.deck.pop()
return self.take(number_cards)This then makes the rest of your code simple and easy to read and use.
def deal(self, n_players):
self.playerhand = zip(self.take(n_players), self.take(n_players))
def flop(self):
self.flopcards = self.draw(3)
def turn(self):
self.turncard = self.draw(1)
def river(self):
self.rivercard = self.draw(1)Other than the above I'd:
- Add
shuffleto your__init__so that the cards are pre-shuffled.
- Move the deck creation into
shuffleto allow more than one game, and
- Move values and suites to the global scope as 'constants'.
This results in something like:
VALUES = ['Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']
SUITES = ['Heart', 'Spade', 'Club', 'Diamond']
class TexasHoldem:
def __init__(self):
self.shuffle()
def shuffle(self):
self.deck = [j + " " + i for j in VALUES for i in SUITES]
shuffle(self.deck)Code Snippets
count = 0
playercard1 = list()
while count < n_players:
card1 = self.deck[count]
playercard1.append(card1)
count += 1
for i in playercard1:
self.deck.remove(i)pop = self.deck.pop
playercard1 = [pop() for _ in range(n_players)]playercard1 = self.deck[-n_players:]
del self.deck[-n_players:]del self.deck[0]
self.flopcards = self.deck[0:3]
del self.deck[0:3]def take(self, number_cards):
pop = self.deck.pop
return [pop() for _ in range(number_cards)]
def draw(self, number_cards):
self.deck.pop()
return self.take(number_cards)Context
StackExchange Code Review Q#125589, answer score: 2
Revisions (0)
No revisions yet.