【问题标题】:Generating 5 playing cards生成 5 张扑克牌
【发布时间】:2016-01-21 13:58:44
【问题描述】:

我一直在尝试为 IRC 制作一个扑克游戏机器人,但我似乎无法解决发牌问题。

我知道这个算法效率很低,但它是我使用我目前的 Python 技能所能想到的最好的算法。欢迎任何改进!

players 是一个字典,其中键是玩家的昵称,值是他们拥有的金额。

当代码运行时,如果只有 1 个玩家,它应该给出 5 张牌。但如果有 2 名玩家,则每人会生成 4 到 6 张牌。我还没有测试更多的玩家。

一些预先初始化的变量:

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

代码:

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)

如果需要任何示例或进一步解释,请询问:)

【问题讨论】:

    标签: python loops poker


    【解决方案1】:

    for 循环

    for c in range(0, 5):
    
    ...
    
        c -= 1
    

    不幸的是,for 循环在 Python 中不是这样工作的 - 递减 c 不会导致循环的另一个复飞。 for 循环遍历循环开始前固定的一组项目(例如,range(0,5) 是在循环期间未修改的 5 个项目的固定范围)。

    如果你想做你正在做的事情,你需要使用while 循环(它通过一个变量和条件工作,可以在循环期间进行修改):

    c = 0
    while c < 5:
        c += 1
    
        ...
    
        c -= 1
    

    range()编号

    if c == 5:
    

    目前不会遇到这种情况,因为range(N) 会生成一个从0N-1 的数字序列 - 例如range(5) 生成 0,1,2,3,4

    【讨论】:

      【解决方案2】:

      我会使用itertools.product 将卡片的可能值放入一个列表中,然后将其洗牌并为您想要的每个玩家一次取出 5 张卡片。

      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']
      

      您可以使用itertools 中的以下配方来获得接下来的 5 张牌,具体取决于玩家人数。

      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')
      

      【讨论】:

      • 嗯,这个解决方案显然比我的混合物好,但我不确定如果超过 5 个玩家,我将如何让它使用多个套牌。
      • @maciozo cards = list(...) * 2 会打出两副牌……等等……(但这会让一手牌可能有 5 个 A),而河牌圈还有 3 个……
      【解决方案3】:

      使用切片来完成此操作的一种简单方法是:

      num_players = 5
      num_cards_per_player = 5
      remaining_cards = list(range(100)) # Imagine a list backing a Deck object
      num_cards_to_deal = num_players * num_cards_per_player
      cards_to_deal, remaining_cards = (remaining_cards[0:num_cards_to_deal],
              remaining_cards[num_cards_to_deal:])
      cards_for_each_player = [cards_to_deal[player_num::num_players] for
              player_num in range(num_players)]
      cards_for_each_player
      [[0, 5, 10, 15, 20], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
      

      对于特定类型的卡片组,您可以实现一个卡片组对象,并使用上述代码稍作修改以在方法中使用。卡组对象将需要处理剩余卡牌不足的情况:),这可能是您正在玩的游戏所特有的。

      【讨论】:

        【解决方案4】:
        #! /usr/bin/python3.2
        
        import random
        
        players = ['Alice', 'Bob', 'Mallroy']
        suits = ["C","D","H","S"]
        ranks = ["2","3","4","5","4","6","7","8","9","J","Q","K","A"]
        decks = 2
        cards = ['{}{}'.format (s, r)
                 for s in suits
                 for r in ranks
                 for d in range (decks) ]
        
        random.shuffle (cards)
        for player in players:
            print ('{}\'s hand is {}'.format (player, cards [:5] ) )
            cards = cards [5:]
        

        【讨论】:

          【解决方案5】:

          只需使用 Python deuces 库,它就是专门为这种用途而构建的:

          from deuces import Card
          from deuces import Deck
          
          # create deck and shuffle it
          deck = Deck()
          deck.shuffle()
          
          # play a texas hold 'em game with two players
          board = deck.draw(5)
          player1_hand = deck.draw(2)
          player2_hand = deck.draw(2)
          
          # now see which hand won
          from deuces import Evaluator
          evaluator = Evaluator()
          p1handscore = evaluator.evaluate(board, player1_hand)
          p2handscore = evaluator.evaluate(board, player2_hand)
          

          【讨论】:

            【解决方案6】:
            from random import randint
            
            # This code below creates a deck
            cards = []
            for suit in ["diamond","club","heart","spade"]:
                for card in ['A','2','3','4','5','6','7','8','9','10','J','Q','K']:
                    cards.append(card+' '+suit)
            # To deal the cards we will take random numbers
            for i in range(5):
                a = randint(0,len(cards)-1)
                print cards(a)
                del cards[a] # We will delete the card which drew
            

            首先我们创建一个牌组,然后我们用randint 抽取一个随机数,然后我们用随机数抽一张牌

            我有一个程序来画翻牌和手牌

            def create_card():
                cards = []
                for suit in   [r'$\diamondsuit$',r'$\clubsuit$',r'$\heartsuit$',r'$\spadesuit$']:
                    for card in  ['A','2','3','4','5','6','7','8','9','10','J','Q','K']:
                        cards.append(card+suit)
                return cards
            
            def create_board_and_hand():
                cards = create_card()
                board = []
                for i in [0,1,2,3,4]:
                a  = randint(0,len(cards)-1)
                board.append(cards[a])
                del cards[a]
                hand = []
                for i in [0,1]:
                    a  = randint(0,len(cards)-1)
                    hand.append(cards[a])
                    del cards[a]
                return board,hand
            
            board,hand = create_board_and_hand()
            

            【讨论】:

              猜你喜欢
              • 2011-04-19
              • 2021-05-17
              • 1970-01-01
              • 1970-01-01
              • 2017-07-11
              • 2016-02-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多