I've been trying to make a poker game bot for IRC, but I can't seem to get my head around dealing the cards.
I know this algorithm is quite inefficient, but it's the best I could come up with using my current Python skills. Any improvements are welcome!
players is a dictionary where the key is a player's nickname, and the value is the amount of money they have.
When the code is run, if there is only 1 player, it gives 5 cards, as it should. But if there are 2 players, it generates anywhere from 4 to 6 cards each. I haven't tested with more players yet.
Some of the variables initialised beforehand:
numberOfPlayers = 0 #The numerical value of the amount of players in the game
players = {} #The nickname of each player and the amount of money they have
bets = {} #How much each player has bet
decks = 1 #The number of decks in play
suits = ["C","D","H","S"] #All the possible suits (Clubs, Diamonds, Hearts, Spades)
ranks = ["2","3","4","5","4","6","7","8","9","J","Q","K","A"] #All the possible ranks (Excluding jokers)
cardsGiven = {} #The cards that have been dealt from the deck, and the amount of times they have been given. If one deck is in play, the max is 1, if two decks are in play, the max is 2 and so on...
hands = {} #Each players cards
The code:
def deal(channel, msgnick):
try:
s.send("PRIVMSG " + channel + " :Dealing...\n")
for k, v in players.iteritems():
for c in range(0, 5):
suit = random.randrange(1, 4)
rank = random.randrange(0,12)
suit = suits[suit]
rank = ranks[rank]
card = rank + suit
print(card)
if card in cardsGiven:
if cardsGiven[card] < decks:
if c == 5:
hands[k] = hands[k] + card
cardsGiven[card] += 1
else:
hands[k] = hands[k] + card + ", "
cardsGiven[card] += 1
else:
c -= 1
else:
if c == 5:
hands[k] = hands[k] + card
cardsGiven[card] = 1
else:
hands[k] = hands[k] + card + ", "
cardsGiven[card] = 1
s.send("NOTICE " + k + " :Your hand: " + hands[k] + "\n")
except Exception:
excHandler(s, channel)
If any examples or further explanations are needed, please ask :)
I would use itertools.product
to get the possible value of cards into a list, then shuffle that and take of 5 cards at a time for each player you want.
from itertools import product
from random import shuffle
suits = ["C","D","H","S"]
ranks = ["2","3","4","5","4","6","7","8","9","J","Q","K","A"]
cards = list(r + s for r, s in product(ranks, suits))
shuffle(cards)
print cards[:5], cards[5:10] # change this into a suitable for loop to slice
['4D', 'KC', '5H', '9H', '7D'] ['2D', '4S', '8D', '8S', '4C']
And you could use the following recipe from itertools
to just get the next 5 cards depending on how many players.
def grouper(n, iterable, fillvalue=None):
from itertools import izip_longest
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
hand = grouper(5, cards)
for i in xrange(5): # deal for 5 players...
print next(hand) # each time we call this, we get another 5 cards
('4D', 'KC', '5H', '9H', '7D')
('2D', '4S', '8D', '8S', '4C')
('AD', '2H', '4S', 'KS', '9S')
('6H', 'AH', '4H', '5S', 'KD')
('6S', 'QD', '3C', 'QC', '8H')