Cas pratique : jeu de cartes

Attention : cet exercice exploite les caractères Unicode représentant les cartes à jouer. Il apparrait que ces caractères ne sont pas disponibles sur un système Windows. Si la carte Roi de Trêfle n'apparait pas après l'exécution de la cellule suivante, votre système ne permet pas cet exercice.

Présentation

On peut utiliser les représentation Unicode pour afficher des caractères spéciaux en Python. Les cartes à jouer sont représentés entre les codes 0x1f0a1 et 0x1f0de et le dos avec 0x1f0a0. On peut donc afficher une carte par l'instruction suivante.


In [ ]:
print(chr(0x1f0de))

Vous pouvez aussi utiliser la fonction range() avec les hexa


In [ ]:
list(range(0x1f0da, 0x1f0df))

jouons aux cartes

Les cartes sont plus précisemment représentées par couleur entre les caractères 0x1f0[a-d]1 et 0x1f0[a-d]e. Il ne faut pas utiliser les caractères 0x1f0[a-c]f et 0x1f0[b-d]0.

Complétez le code permétant de créer une variable deck qui est une liste qui contiendra un jeu de cartes ordonné.


In [ ]:
deck = [chr(x) for x in (list(range(0x1f0a1, 0x1f0af))
                         + list(range(0x1f0b1, 0x1f0bf))
                         + list(range(0x1f0c1, 0x1f0cf))
                         + list(range(0x1f0d1, 0x1f0df)))]
print(deck)
print(len(deck))

Vous avez remarqué que chaque couleur a 14 cartes. L'encodage unicode des cartes permet de représenter un jeu de tarot et contient le cavalier. Pour la suite des travaux pratique, on utilisera donc un jeu de 58 cartes.

Nous souhaitons maintenant distribuer une main de 5 cartes. Ce sont les 5 premières qui sont distribuées dans la main.

Écrivez le code qui permet d'assigner à une variable hand une liste de 5 cartes qui sont les 5 premières cartes du deck.


In [ ]:
hand = deck[:5]
deck = deck[5:]

print(hand)

Récrivez ou complétez ce code en vous assurant que les cartes distribuées ne font plus parti du deck.


In [ ]:
print(len(deck) == 53)

Il y a maintenant 2 joueurs et on doit donc distribuer 2 mains. Les cartes sont tirées du deck et distribuées alternativement à chaque main (première carte au premier jouer, seconde au second, troisième au premier, quatrième au second…).

Écrivez le code qui permet de distribuer 2 mains.


In [ ]:
hand_player1 = deck[:10:2]
hand_player2 = deck[1:11:2]
deck = deck[10:]

print(hand_player1)
print(hand_player2)

Soit n_players le nombre de joueurs.

Écrivez une structure qui utilise cette variable pour tirer autant de mains que les joueurs et les afficher.


In [ ]:
n_players = 4
for player in range(n_players):
    print(deck[0 + player: (5*n_players) + player: n_players])

Écrivez une fonction draw_hands qui prend en paramètre le nombre de joueur et un deck et qui retourne deux résultats:

  • une liste des mains des joueurs (liste de listes de cartes)
  • un deck qui contient les cartes restantes dans le deck.

note: vous pouvez créer une fonction new_deck afin de générer un nouveau deck car celui que vous utilisez depuis le début du workbook se réduit de plus en plus…


In [ ]:
def new_deck():
    return [chr(x) for x in (list(range(0x1f0a1, 0x1f0af))
                         + list(range(0x1f0b1, 0x1f0bf))
                         + list(range(0x1f0c1, 0x1f0cf))
                         + list(range(0x1f0d1, 0x1f0df)))]


def draw_hands(number_players, fdeck):
    """
    La fonction utilise des variables fdeck et fplayer pour éviter la confusion avec les noms des variables globales.

    :param number_players:
    :param fdeck:
    :return:
    """
    hands = []

    if len(fdeck) == 58:
        import random
        random.shuffle(fdeck)

    for fplayer in range(number_players):
        hands.append(fdeck[0 + fplayer: (5 * number_players) + fplayer: number_players])
    fdeck = fdeck[number_players * 5:]

    return hands, fdeck

print(draw_hands(4, new_deck()))

Python propose un module random qui contient des outils intéressants pour simuler une vrai parti de cartes. Ce module contient une fonction shuffle(list) qui mélange le contenu d'une liste. Attention, shuffle retourne None, la fonction mélange la liste elle-même.

Modifiez la fonction précédente pour qu'elle mélange un nouveau deck et uniquement un nouveau deck avant de distribuer les cartes.


In [ ]: