pythoncombinatoricsplaying-cards

Get all possible deals variation for Preferance (or Bridge) game


Does anybody know the best method to generate all possible and different variations of deals for Preferance game (Total card quantity is 32.) in such variation in 3 hands? For example (where ('X', 'Y') can be any card -> e.g. ('J', '♠')):

1st deal:

1st hand -> (('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'))
2nd hand -> (('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'))
3rd hand -> (('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'), ('X', 'Y'))
The rest cards - -> (('X', 'Y')*13)
Trump -> (('X', 'Y'))

I mean that: 1st deal for 1nd hand:

(
(('7', '♦'), ('8', '♥')), # edited line
(('9', '♦'), ('10', '♥')),
(('J', '♦'), ('Q', '♥')),
(('X', 'X')*13,
(('A', '♦'))
)

2nd deal for the 1st hand:

(
(('8', '♥'), ('7', '♦')), # edited line
(('9', '♦'), ('10', '♥')),
(('J', '♦'), ('Q', '♥')),
(('X', 'X')*13,
(('A', '♦'))
)

these both deals are defined like ONLY 1 deal but NOT 2 because actualy the hand has the same cards.

Also it can be resolved using "itertools.permutations" lib and then filter all the identical combinations (like I mentioned above) but I think there is another method more quick?


Solution

  • I think you should use "combinations" instead of "permutations" because you get all possible unique combinations and quantities. At first you can get all combinations for the 1st hand and use such approach for other ones

    deck = [('7', '♠'), ('7', '♣'), ('7', '♦'), ('7', '♥'), ('8', '♠'), ('8', '♣'), ('8', '♦'), ('8', '♥'), ('9', '♠'), ('9', '♣'), ('9', '♦'), ('9', '♥'), ('10', '♠'), ('10', '♣'), ('10', '♦'), ('10', '♥'), ('J', '♠'), ('J', '♣'), ('J', '♦'), ('J', '♥'), ('Q', '♠'), ('Q', '♣'), ('Q', '♦'), ('Q', '♥'), ('K', '♠'), ('K', '♣'), ('K', '♦'), ('K', '♥'), ('A', '♠'), ('A', '♣'), ('A', '♦'), ('A', '♥')]
    i = 1
    for item in itertools.combinations(deck, 7):
        print(item)
        print(i)
        i = i + 1
    

    Also you can use such approach:

    def get_hands_from_deck(deck):
        hand_1, hand_2, rest_cards, trump = [], [], [], []
        for index, value in enumerate(deck):
            if index < 6:
                hand_1.append(value)
            if 6 <= index < 12:
                hand_2.append(value)
            if 12 <= index < 31:
                rest_cards.append(value)
            if index > 30:
                trump.append(value)
        return tuple(hand_1), tuple(hand_2), tuple(rest_cards), tuple(trump)
    
    unique_deals = []
    deck = [('A', '♠'), ('A', '♦'), ('10', '♠'), ('J', '♦'), ('J', '♣'), ('7', '♦'), ('10', '♥'), ('10', '♣'), ('7', '♠'), ('9', '♣'), ('8', '♥'), ('8', '♣'), ('7', '♥'), ('7', '♣'), ('8', '♦'), ('K', '♥'), ('J', '♥'), ('Q', '♥'), ('Q', '♠'), ('10', '♦'), ('J', '♠'), ('A', '♥'), ('9', '♠'), ('9', '♦'), ('Q', '♣'), ('9', '♥'), ('A', '♣'), ('8', '♠'), ('K', '♠'), ('Q', '♦'), ('K', '♦'), ('K', '♣')]
    for item in itertools.permutations(deck, 32):
        split_deck_between_hands = get_hands_from_deck(item)
        if not unique_deals:
            unique_deals.append(split_deck_between_hands)
        if sort_cards(unique_deals[-1][0]) == sort_cards(split_deck_between_hands[0]) \
                and sort_cards(unique_deals[-1][1]) == sort_cards(split_deck_between_hands[1]) \
                and sort_cards(unique_deals[-1][2]) == sort_cards(split_deck_between_hands[2]) \
                and sort_cards(unique_deals[-1][3]) == sort_cards(split_deck_between_hands[3]):
            continue
        unique_deals.append(split_deck_between_hands)
        print(split_deck_between_hands)
    

    But the only thing you should do is to create "sort_cards" method. Just get it from here Sort cards according to its suite and values using python

    This is quite ugly solution but works :-)