简单的蟒蛇卡游戏

时间:2011-04-10 00:19:37

标签: python playing-cards

我对python完全不熟悉,我不知道如何处理这个程序。

我正在尝试建立一个执行以下操作的迷你纸牌游戏

  1. 有六名球员。
  2. 每手牌开始时,每位牌手都会获得四张牌。
  3. 对于每个玩家,他们手中的所有对都被放下。玩家获得一对由两张等级小于10的牌组成的一对(ace计数大于10)。对于付款人而言,玩家得到两分,其中两张牌的等级为10或更高。如果手为两对,两者都放下。玩家获得适合该类对的点(1或2)。
  4. 双手落下后,指针结束。 (玩家实际上并没有输入输入或做出决定。我告诉你这是一个无聊的游戏。)所有牌都返回到牌组,它被重新洗牌,然后开始新的牌。
  5. 每轮结束后,球员按总分数的降序排列。如果两个玩家并列相同数量的积分,则首先使用编号最小的玩家打印。
  6. 经过六轮比赛,比赛结束。得分列表中的第一个玩家(如上所述)赢得游戏
  7. 输出应如下所示:

    Hand 1 deal:
    Player 1's hand: 5D 5H KD AS
    Player 2's hand: 7D 8D 9C JS
    Player 3's hand: 3D 3H 6S 7C
    Player 4's hand: 4C 6D 8S TH
    Player 5's hand: 4H 5C 7S QC
    Player 6's hand: 5S 6H 9H KH
    
    Dropping pairs:
    Player 1 dropped 1 pair.
    Player 2 dropped no pairs.
    Player 3 dropped 1 pair.
    Player 4 dropped no pairs.
    Player 5 dropped no pairs.
    Player 6 dropped no pairs.
    
    Score:
    Player 1: 1
    Player 3: 1
    Player 2: 0
    Player 4: 0
    Player 5: 0
    Player 6: 0
    

    我为这个游戏所拥有的模块包括。

    CARDS.py

    import string
    import random
    
    suits = ['S', 'C', 'D', 'H']
    longsuits = ['spades', 'clubs', 'diamonds', 'hearts']
    
    ranks = ['2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A']
    longranks = ['two', 'three', 'four', 'five', 'six', 'seven', 'eight',
            'nine', 'ten', 'jack', 'queen', 'king', 'ace']
    
    ranklist = string.join(ranks, "")
    
    ranklookup = {}
    for i in range(len(ranks)):
        ranklookup[ranks[i]] = i
    
    suitlookup = {}
    for i in range(len(suits)):
        suitlookup[suits[i]] = i
    
    class Card:
        """
        Class to hold information about a single playing card.  The card's rank
        and suit are stored.
    
        The constructor takes two arguments, the rank and suit of the card.  The
        rank and suit must be values from the ranks and suits list.
    
        >>> c1 = Card('8', 'C')
        >>> c2 = Card('K', 'H')
        >>> print c1
        8C
        >>> print c2
        KH
        """
    
        def __init__(self, rank, suit):
            self.__rank = ranklookup[rank]
            self.__suit = suitlookup[suit]
    
        def __cmp__(self, other):
            """
            Compare two card objects.
    
            >>> c1 = Card('8', 'C')
            >>> c2 = Card('K', 'H')
            >>> c1<c2
            True
            >>> c1>c2
            False
            >>> c1==c2
            False
            """
            if self.__rank == other.__rank:
                return cmp(self.__suit, other.__suit)
            else:
                return cmp(self.__rank, other.__rank)
    
        def __str__(self):
            """
            Return a two-character string representing the card.
    
            >>> c1 = Card('8', 'C')
            >>> str(c1)
            '8C'
            """
            return self.shortname()
        def __repr__(self):
            """
            Return a the Python code required to construt the card.
    
            >>> c1 = Card('8', 'C')
            >>> print repr(c1) .split(".",1)[1]
            Card('8', 'C')
            """
            return "%s.Card('%s', '%s')" % (self.__module__, ranks[self.__rank], suits[self.__suit])
    
        def suit(self):
            """
            Return a character representing the card's suit.  This will be one of the
            characters from suits.
    
            >>> c1 = Card('8', 'C')
            >>> c1.suit()
            'C'
            """
            return suits[self.__suit]
    
        def rank(self):
            """
            Return a character with the card's rank.  This will be one of the
            characters from ranks.
    
            >>> c1 = Card('8', 'C')
            >>> c1.rank()
            '8'
            """
            return ranks[self.__rank]
    
        def shortname(self):
            """
            Output a short two-character description of the card.
    
            >>> c1 = Card('8', 'C')
            >>> c1.shortname()
            '8C'
            """
            return ranks[self.__rank] + suits[self.__suit]
    
        def longname(self):
            """
            Return a long English description of the card.
    
            >>> c1 = Card('8', 'C')
            >>> c1.longname()
            'eight of clubs'
            """
            return longranks[self.__rank] + " of " + longsuits[self.__suit]
    
    
    
    testhand = [ Card('9', 'H'), Card('6', 'C'), Card('7', 'S'), Card('6', 'D'), Card('A', 'H') ]
    
    def deck():
        """
        Return an *unshuffled* deck of cards (list of card objects).
    
        >>> d = deck()
        >>> print hand_string(d)
        2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS AS 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC AC 2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD AD 2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH AH
        >>> print len(d)
        52
        """
        d = []
        for suit in range(len(suits)):
            for rank in range(len(ranks)):
                c = Card(ranks[rank], suits[suit])
                d.append(c)
    
        return d
    
    
    def small_deck():
        """
        Return a small *unshuffled* deck of cards (list of card objects).  This is
        smaller than a regular deck and can be used for testing.
    
        >>> d = small_deck()
        >>> print hand_string(d)
        9S TS JS QS KS AS 9C TC JC QC KC AC 9D TD JD QD KD AD 9H TH JH QH KH AH
        >>> print len(d)
        24
        """
        d = []
        for suit in range(len(suits)):
            for rank in [7,8,9,10,11,12]:
                c = Card(ranks[rank], suits[suit])
                d.append(c)
    
        return d
    
    
    
    def start_pair(hand):
    
        """
            Return index of first card in first pair of the hand.
            The index is for the order the hand has after sorting.
            If there are no pairs, return -1.
    
            Side effect:  The hand is sorted.
        """
        hand.sort()
        start = -1
        for i in range(len(hand)-1, 0, -1):
            if hand[i].rank() == hand[i-1].rank():
                start = i -1
        return start
    
    
    
    
    
    def drop_pair(hand):
        """
        Remove a pair from the hand (list of card objects) if possible.  Return
        the new hand and the number of pairs dropped (0 or 1).  A "pair" is two
        cards with the same rank.
    
        If there is more than one pair, only the first is removed.
    
        The hand MUST be sorted by rank before this function is called.  This
        can be done with:
            hand.sort()
    
        >>> testhand.sort()
        >>> print hand_string(testhand)
        6C 6D 7S 9H AH
        >>> newhand, pts = drop_pair(testhand)
        >>> print hand_string(newhand)
        7S 9H AH
        >>> print pts
        1
        """
        newhand = hand[:]
        for i in range(len(newhand)-1):
            if newhand[i].rank() == newhand[i+1].rank():
                del(newhand[i+1])
                del(newhand[i])
                return newhand, 1
        return newhand, 0
    
    
    
    def hand_string(hand):
        """
        Create a string that represents the cards in the player's hand.
    
        >>> hand_string(testhand)
        '6C 6D 7S 9H AH'
        >>> hand_string([])
        ''
        """
    
        return " ".join( [c.shortname() for c in hand] )
    
    
    def _test():
        import doctest
        doctest.testmod()
    
    if __name__ == "__main__":
        _test()
    

    模块结束。

    pointsort.py
    
    '''
        Module to sort players by points and player numbers.  See definition for
        function sortPlayers() for details of sort order.
    '''
    
    def playerToSort(p):
        ''' Represent player number such that lower-numbered players sort before higher-numbered '''
        return -p
    
    def playerFromSort(p):
        ''' Extract original player number from playerToSort() representation '''
        return -p
    
    def sortPlayers(playerNum, points):
        ''' Sort players by total points, then by player number within total points.
            Player numbers are sorted such that low-numbered players are highest.
    
            Returns list of tuples (playerNumber, points), sorted in *increasing* order
            by the two criteria.
        '''
        keys = []
        for n in playerNum:
            keys.append(playerToSort(n))
    
        order = []
        for i in range(len(points)):
            order.append((points[i], keys[i]))
    
        order.sort()
        result = []
        for i in range(len(order)):
            result.append((playerFromSort(order[i][1]), order[i][0]))
    
        return result
    
    if __name__ == "__main__":
        points = [3, 4, 1, 2, 0, 3]
        number = [2, 1, 3, 4, 0, 5]
        order = sortPlayers(number, points)
        # Note that the following prints results in the WRONG order for A4 
        for i in range(len(order)):
            print "Player " + str(order[i][0]) + " had " + str(order[i][1]) + " points."
    
    
    
    i was really hoping if someone could help me with the loops that this program needs, especially the point loop system. 
    this what i have so far, 
    
    import cards
    import random
    
    new = cards.small_deck()
    
    print cards.hand_string(new)
    print len(new)
    
    
    player1 = []
    player2 = []
    player3 = []
    player4 = []
    player5 = []
    player6 = []
    #shuffle the cards
    random.shuffle(new)
    num = input('How many cards to deal to each player? ')
    while num > 0:
            player1.append(new.pop(0))
            player2.append(new.pop(0))
            player3.append(new.pop(0))
            player4.append(new.pop(0))
            player5.append(new.pop(0))
            player6.append(new.pop(0))
            num = num - 1
    #prints out 8 cards for each person
    
    print 'the cards remaining in the deck are: '
    print len(new)
    
    #sorts player1 cards and removes the pairs
    player1.sort()
    print "sorted hand for player 1:"
    print cards.hand_string(player1)
    newplayer1 = []
    player1points = 0
    
    newplayer1, player1points = cards.drop_pair(player1)
    print cards.hand_string(newplayer1)
    
    #sorts player2 cards
    player2.sort()
    print "sorted hand for player 2:"
    print cards.hand_string(player2)
    newplayer2 = []
    player2points = 0
    
    newplayer2, player1points = cards.drop_pair(player2)
    print cards.hand_string(newplayer2)
    
    
    
    #sorts player3 cards
    player3.sort()
    print "sorted hand for player 3:"
    print cards.hand_string(player3)
    newplayer3 = []
    player3points = 0
    
    newplayer3, player1points = cards.drop_pair(player3)
    print cards.hand_string(newplayer3)   
    
    
    #sorts player4 cards
    player4.sort()
    print "sorted hand for player 4:"
    print cards.hand_string(player4)
    newplayer4 = []
    player4points = 0
    
    newplayer4, player1points = cards.drop_pair(player4)
    print cards.hand_string(newplayer4)
    
    
    #sorts player5 cards
    player5.sort()
    print "sorted hand for player 5:"
    print cards.hand_string(player5)
    newplayer5 = []
    player5points = 0
    
    newplayer5, player1points = cards.drop_pair(player5)
    print cards.hand_string(newplayer5)
    
    #sorts player6 cards
    player6.sort()
    print "sorted hand for player 6:"
    print cards.hand_string(player6)
    newplayer6 = []
    player6points = 0
    
    newplayer6, player1points = cards.drop_pair(player6)
    print cards.hand_string(newplayer6)
    

    我在循环方面遇到了很多麻烦,并且会提供任何我能得到的帮助,谢谢你提前

1 个答案:

答案 0 :(得分:1)

你似乎根本没有使用pointsort.py,这没关系,因为我并没有因为你的预期输出而需要它。

# main.py
import cards
import random

deck = cards.small_deck()

class Player(object):
    def __init__(self, number):
        self.number = number
        self.points = 0
        self.hand = []

    def __str__(self):
        return "Player %d" % self.number

players = [Player(num + 1) for num in xrange(6)]  # create six numbered players
rounds = 6
hand_size = 4

for round_num in xrange(rounds):
    #shuffle the cards
    random.shuffle(deck)
    print "Hand %d deal:" % (round_num + 1)
    # deal cards
    for _ in xrange(hand_size):
        for player in players:
            # draw from the back instead of the front: possibly slightly more efficient
            player.hand.append(deck.pop())

    # sort player cards
    for player in players:
        player.hand.sort()
        print "%s's hand: %s" % (player, cards.hand_string(player.hand))
    print

    print "Dropping pairs:"
    for player in players:
        #removes the pairs
        new_hand, dropped_cards, pairs = cards.drop_pairs(player.hand)
        deck.extend(player.hand)  # realistically we can dump the hand now anyway.
        player.hand = []

        player.points += pairs

        how_many = pairs
        plural = "s"
        if pairs == 0:
            how_many = "no"
        elif pairs == 1:
            plural = ""
        print "%s dropped %s pair%s" % (player, how_many, plural)
    print

    print "Score:"
    for player in players:
        print "%s: %d" % (player, player.points)
    print

我还将drop_pair更改为drop_pairs,并使其找到所有对而不是一对。如果它找到三种类型,它值2分,而四种类型值3。

# in cards.py
def drop_pairs(hand):
    new_hand = hand[:]
    dropped_cards = []
    pairs = 0
    for card1, card2 in zip(hand, hand[1:]):  # look at every two-in-a-row cards
        if card1.rank() == card2.rank():
            try:
                new_hand.remove(card1)
            except ValueError:
                pass
            else:
                dropped_cards.append(card1)
            try:
                new_hand.remove(card2)
            except ValueError:
                pass
            else:
                dropped_cards.append(card2)
            pairs += 1
    return new_hand, dropped_cards, pairs

我没有查看您的所有代码,也没有更多具体的指导,而不是“循环帮助”。我无法帮助太多,但我注意到了一些事情:

  • 在python中,您可以直接遍历列表而不是从0迭代到len - 1并检查索引。例如:

    # this will work, but it's not recommended
    for suit in range(len(suits)):
        for rank in range(len(ranks)):
            c = Card(ranks[rank], suits[suit])
            d.append(c)
    
    # this is much cleaner
    for suit in suits:
        for rank in ranks:
            d.append(Card(rank, suit))
    
  • 但是,有时你想要迭代一系列连续的数字,或者你只想要一些代码运行一定次数,在这种情况下你可以使用range(或xrange,在python 2中)对于大范围来说效率更高)

    # don't do this
    while num > 0:
        do_something()
        num = num - 1
    
    # Do this instead!
    for i in xrange(num):
        do_something()
    

另外,如果你不需要这样的话,那就是&#39;当前数字的变量,您可以使用名称&#39; _&#39;,它经常被重新分配,是垃圾数据的好地方。

  • 您还可以嵌套列表。如果您不确定自己将拥有多少个列表,这非常有用。也就是说,如果你有六名球员:

    # no no no
    player1 = []
    player2 = []
    player3 = []
    player4 = []
    player5 = []
    player6 = []
    
    # better...
    players = [[], [], [], [], [], []]
    
    # yes!
    players = []
    for _ in xrange(6):
        players.append([])
    
    # There's also a shortcut called List Comprehensions, which allows us
    # to be even more concise with our list definitions.
    players = [[] for _ in xrange(6)]
    

后两个示例的优势在于,您可以通过更改数字6或甚至使用变量轻松更改游戏中有多少玩家。他们还减少了代码重复:你处理他们卡片的每个玩家的逻辑被复制粘贴6次,只有一个数字在他们之间改变。这不是非常可扩展的:如果您想添加或删除播放器,则必须在代码中添加或删除那些重复的块。代替:

    # no! bad!
    player1 = []
    player2 = []
    player3 = []
    player4 = []
    player5 = []
    player6 = []

    player1.do_stuff()
    player2.do_stuff()
    player3.do_stuff()
    player4.do_stuff()
    player5.do_stuff()
    player6.do_stuff()

    # much easier!
    for player in players:
        player.do_stuff()