J'ai essayé d'implémenter le blackjack du jeu Trump en Python

introduction

La dernière fois, j'ai créé la fonction deck de Trump comme indiqué dans ici.

En utilisant la fonction de deck précédente, j'ai essayé cette fois d'implémenter la fonction de jeu principale du Blackjack. Comment écririez-vous réellement un programme et étendriez-vous ce que vous avez dit des exigences existantes? Je pense que j'ai beaucoup appris en y réfléchissant!

Exigences fonctionnelles

Pour les règles et exigences de base, reportez-vous à celle dans Développement du «Blackjack» pour les examens de fin d'études des débutants en programmation. Je vous remercie!

--La carte initiale est 52. Assurez-vous qu'il n'y a pas de cartes en double lors du dessin --Deux joueurs et revendeurs. Les joueurs courent, les croupiers courent automatiquement

  • Au début de l'exécution, le joueur et le croupier tirent chacun deux cartes. La carte dessinée s'affiche à l'écran. Cependant, ** Je ne connais pas la deuxième carte du croupier **
  • Après cela, le joueur pioche la carte en premier. Rafale si le nombre de joueurs dépasse 21, le jeu se termine à ce point
  • Les joueurs peuvent choisir de piocher la carte suivante à chaque fois qu'ils tirent une carte
  • Une fois que le joueur a fini de dessiner, le croupier continuera à dessiner jusqu'à ce que sa main atteigne 17 ou plus.
  • Un jeu où le joueur et le croupier finissent de dessiner. Le plus proche de 21 victoires --J, Q et K sont traités comme 10
  • ** A est traité uniquement comme "1" pour le moment. ** Ne définissez pas sur "11"
  • Pas de double vers le bas, pas de scission, pas de reddition, pas d'autres règles spéciales

Cette fois, en plus de ces exigences, j'ai ajouté les fonctions suivantes.

la mise en oeuvre

Nous avons préparé les classes suivantes et séparé chaque fichier. La classe Card et la classe Deck n'incluent pas de spécifications spécifiques au Blackjack afin qu'elles puissent être utilisées dans d'autres jeux Trump.

Classe de carte / classe de deck

J'ai utilisé celui créé dans cet article tel quel.

Classe de joueur / classe de croupier

from bj import BlackJack


class Player:
    """
Enfant (lecteur qui peut être actionné manuellement)
    """

    def __init__(self):
        self.win_count = 0
        self.hands = []
        self.card_current_score = 0
        self.card_current_score_sub = 0
        self.has_A_card = False

    def keep_drawing_card(self, deck):
        """
Laissez le joueur décider de frapper ou de se tenir debout
(Le stand termine le tour du joueur)

        Parameters
        ----------
        deck : deck
Un jeu de cartes
        """
        want_to_draw = True
        while want_to_draw:
            hit_or_stand_msg = "\nHit(1) or Stand(2) : "
            hit_or_stand_res = input(hit_or_stand_msg)
            if hit_or_stand_res == "1":
                #1 nul pour coup
                self.draw_card(deck)
                print(f"player draw card is : {self.hands[-1]}")
                BlackJack.calc_current_score(self)
                sub_score = ""
                if self.has_A_card is True:
                    sub_score = \
                        f", {self.card_current_score_sub}"
                print(
                    f"players's total_score : \
{self.card_current_score}{sub_score}")

                #Interruption forcée du tour du joueur avec rafale
                if BlackJack.is_score_bust(int(self.card_current_score)) and \
                    BlackJack.is_score_bust(
                        int(self.card_current_score_sub)):
                    print("player bust!!!")
                    want_to_draw = False

                if self.card_current_score == 21 or \
                        self.card_current_score_sub == 21:
                    #Résiliation forcée à 21 ans
                    want_to_draw = False

            elif hit_or_stand_res == "2":
                #Dans le cas du stand, le tour se termine
                want_to_draw = False
            else:
                # 1,Entrez à nouveau les commandes autres que 2
                print("Est inutile")

    def draw_card(self, deck, num=1):
        """
Piochez une carte du jeu et ajoutez-la à votre main
* Même si différents numéros sont tirés, c'est ok

        Parameters
        ----------
        num : int, default 1
Nombre de fois pour piocher une carte

        Examples
        --------
        >>> player.draw_card(2) #2 nuls[♠︎-J, ♠︎-10]
        >>> player.draw_card(3) # [♦︎-9, ♣️-10, ♠︎-2]
        >>> print(player.hands)
        [♠︎-J, ♠︎-10, ♦︎-9, ♣️-10, ♠︎-2]
        """
        self.hands_store = deck.pick_card(num)
        self.hands.extend(self.hands_store)


class Dealer(Player):
    """
Parent (fonctionnement automatique)
    """

    def keep_drawing_card(self, deck):
        """
Le croupier continue de tirer des cartes automatiquement jusqu'à ce qu'il dépasse 17
Fin lorsque 17 est dépassé

        Parameters
        ----------
        deck : object
Main actuelle
        """
        self.has_A_card = False
        while self.card_current_score < 17 or \
                self.card_current_score_sub < 17:
            self.draw_card(deck)
            print(f"dealer draw card is : {self.hands[-1]}")
            BlackJack.calc_current_score(self)
            sub_score = ""
            if self.has_A_card:
                sub_score = \
                    f", {self.card_current_score_sub}"
            print(
                f"dealer's total_score : {self.card_current_score}{sub_score}")
            if BlackJack.is_score_bust(self.card_current_score) and \
                    BlackJack.is_score_bust(
                    int(self.card_current_score_sub)):
                print("dealer bust!!!")

Classe de jeu

from deck import stock
import role
from bj import BlackJack


class Game:
    """
Jeu principal (créer une instance de joueur et de croupier lors de la création d'une instance)

    Examples
    --------
    >>> game = Game()
    >>> game.main() #Début du jeu (affiche la phase initiale ci-dessous)
    dealer's hands : [❤︎-7, *-*]

    player's hands : [♠︎-9, ♦︎-J]
    players's total_score : 19

    Hit(1) or Stand(2) :
    """

    def __init__(self):
        #Créer un joueur et un croupier
        self.player = role.Player()
        self.dealer = role.Dealer()

    def get_nearest_score(self, score_list):
        """
Renvoie le nombre le plus proche de 21 en dessous de 21 à partir des scores principaux et secondaires
Renvoie 0 si les deux dépassent 21

        Parameters
        ----------
        score_list : list
Liste des scores principaux et secondaires

        Returns
        --------
        main_score : int
Un nombre proche de 21 des deux scores (0 si les deux sont supérieurs à 21)
        """
        main_score = 0
        for score in score_list:
            if score > 21:
                #Les nombres supérieurs à 21 éclatent
                continue
            elif main_score < score:
                main_score = score
        return main_score

    def judge_winner(self, player, dealer):
        """
Jugement gagnant / perdant

        Parameters
        ----------
        dealer : object
parent
        player : object
Enfant
        """

        # player,Obtenez et comparez le plus proche de 21 sur 21 ou moins dans le score de chaque concessionnaire
        player_score_list = [
            player.card_current_score,
            player.card_current_score_sub]
        player_score = self.get_nearest_score(player_score_list)

        dealer_score_list = [
            dealer.card_current_score,
            dealer.card_current_score_sub]
        dealer_score = self.get_nearest_score(dealer_score_list)

        judge_win = ""
        #Les deux rafales sont nulles
        if player_score == 0 and dealer_score == 0:
            judge_win = "---draw---"

        if dealer_score < \
                player_score <= 21:
            # dealer < player <=À 21 ans, le joueur gagne
            judge_win = "player win!"
            player.win_count += 1
        elif player_score <= 21 \
                < dealer_score:
            #Le joueur gagne quand le joueur a 21 ans ou moins, le croupier éclate
            judge_win = "player win!"
            player.win_count += 1
        elif player_score == dealer_score \
                and player_score <= 21:
            #Ni l'un ni l'autre n'éclate, et si les nombres sont les mêmes, un match nul
            judge_win = "---draw---"
        else:
            #Sinon, tous les joueurs perdent
            judge_win = "dealer win!"
            dealer.win_count += 1
        #Affichage de la console
        print(f"\n/***********/\n/{judge_win}/\n/***********/")

    def display_final_result(
            self,
            player_win_count,
            dealer_win_count,
            total_count):
        """
Jugement gagnant / perdant

        Parameters
        ----------
        player_win_count : int
Nombre de joueurs gagnés
        dealer_win_count : int
Le concessionnaire gagne
        total_count : int
Nombre total de jeux
        """
        #Calculez le nombre de tirages en soustrayant le nombre de victoires du joueur et du croupier du nombre total de parties
        draw_count = total_count - player_win_count - dealer_win_count
        return f"""\
*-*-*-*-*-*-*-*
total:{total_count}
win:{player_win_count}
lose:{dealer_win_count}
draw:{draw_count}
*-*-*-*-*-*-*-*\
"""

    def main(self):
        """
Fonction de jeu principale de Blackjack
        """

        #Deck set (déterminer le nombre d'ensembles)
        deck = stock.Deck()

        total_count = 0
        can_play_game = True
        #Lorsqu'il reste 5 cartes ou plus
        while can_play_game and len(deck.cards) > 5:

            self.player.hands = []
            self.dealer.hands = []

            #Nombre de parties+1
            total_count += 1

            #Dessinez deux au début
            self.player.draw_card(deck, 2)
            self.dealer.draw_card(deck, 2)

            #calcul du score initial du joueur
            BlackJack.calc_current_score(self.player)
            #Si A est soustrait, le sous-score est également affiché.
            player_sub_score = BlackJack.check_draw_A(self.player)

            #Affichage du score au moment du tirage initial (celui du côté du croupier est refusé)
            print("\n--Game Start--\n")
            first_msg = f"""\
dealer's hands : [{self.dealer.hands[0]}, *-*]
player's hands : {self.player.hands}

players's total_score : {self.player.card_current_score}{player_sub_score}\
            """
            print(f"{first_msg}")

            #Laisser le joueur décider de toucher ou de se tenir debout (le stand met fin au tour du joueur)
            self.player.keep_drawing_card(deck)

            print("\n--Result--\n")

            #calcul du score du concessionnaire
            BlackJack.calc_current_score(self.dealer)
            #Si A est soustrait, le sous-score est également affiché.
            dealer_sub_score = BlackJack.check_draw_A(self.dealer)
            dealer_msg = f"""\
dealer's hands : {self.dealer.hands}
dealer's total_score : {self.dealer.card_current_score}{dealer_sub_score}\
            """
            print(f"{dealer_msg}")

            #Dessinez jusqu'à ce que la main du croupier soit de 17
            self.dealer.keep_drawing_card(deck)

            #Jugement gagnant / perdant
            self.judge_winner(self.player, self.dealer)

            print("\n--Game End--\n")

            #Redémarrage du jeu
            restart_msg = "Q termine le jeu, sinon le jeu commence:"
            start_res = input(restart_msg)
            if start_res == 'Q':
                can_play_game = False

        #Calculer et afficher le nombre de parties et le nombre de victoires
        final_score_str = self.display_final_result(
            self.player.win_count, self.dealer.win_count, total_count)
        print(final_score_str)


if __name__ == '__main__':
    game = Game()
    game.main()

Classe BlackJack

class BlackJack:
    """
Règles du Blackjack
    """

    RANKS = (*"A23456789", "10", *"JQK")
    values = list(range(1, 11))  # 1〜10
    values.extend([10, 10, 10])  # JQK
    VALUES = (values)
    #Associer la marque d'affichage à la partition
    # {'A': 1, '2': 2, '3': 3, '4': 4, '5': 5,
    #  '6': 6, '7': 7, '8': 8, '9': 9, '10': 10,
    #  'J': 10, 'Q': 10, 'K': 10}
    RANK_TO_VALUES = dict(zip(RANKS, VALUES))

    @classmethod
    def calc_current_score(cls, person):
        """
Calculer le score actuel

        Parameters
        ----------
        person : object
Main actuelle

        Returns
        --------
        card_current_score : int
Score actuel
        """
        person.card_current_score = 0
        person.card_current_score_sub = 0
        person.has_A_card = False
        for card in person.hands:
            card_rank = str(card).split("-")[1]
            card_value = cls.RANK_TO_VALUES[card_rank]

            #Considérez le temps de A
            person.card_current_score += card_value
            person.card_current_score_sub += card_value
            if card_value == 1:
                if person.has_A_card:
                    #Lorsque A est continu, le sous-score est doublé et le sous-score est ajouté.+10(+11-1)
                    person.card_current_score_sub += 10
                    print(person.card_current_score_sub)
                    continue
                person.has_A_card = True
                person.card_current_score_sub += 11

    @classmethod
    def is_score_bust(cls, total_score):
        """
Calculer le score actuel

        Parameters
        ----------
        current_hands : list
Main actuelle

        Returns
        --------
        True or False
Vrai en rafale
        """
        return total_score > 21

    @classmethod
    def check_draw_A(cls, person):
        """
S'il y a un A dans votre main, le sous-score est également affiché

        Parameters
        ----------
        person : object
            player or dealer

        Returns
        --------
        person_sub_score : str
Chaîne de caractères de sous-score (caractère vide s'il n'y a pas de A dans votre main)
        """
        person_sub_score = ""
        if person.has_A_card is True:
            person_sub_score = f", {person.card_current_score_sub}"
        return person_sub_score

Points inquiets

À propos du calcul du score de A (calc_current_score de la classe Player)

J'étais inquiet à ce sujet, mais j'ai préparé un sous-score depuis le début, et quand j'ai soustrait A, l'affichage de la console, Lors du calcul du score, je l'ai implémenté comme +1 pour le principal et +11 pour le sous-marin. Je pense qu'il existe d'autres moyens plus efficaces. J'ai pu l'implémenter assez facilement jusqu'au point de calculer le score avec A comme 1. En en faisant un moyen de préparer des sous-scores Je pense que c'est un peu un échec que le traitement du calcul des scores a augmenté.

Jugement de gain de score multiple (classe de jeu get_nearest_score, juge_ gagnant)

Cette fois, nous avons 2 scores chacun pour le joueur et le croupier Dans la liste des uns et des autres, le score plus proche de 21 sans dépasser 21 a été utilisé comme score de jugement.

Si les deux scores sont éclatés, le score sera de 0, et si l'un est éclaté, l'autre sera le score du jugement. → Il n'y a pas de joueur plus de 17 (car il y a un match nul à 16) → le croupier tire automatiquement jusqu'à ce que les deux scores dépassent 17

mouvement

Une fois exécuté, cela ressemble à ceci. Enfin, le nombre de parties et le nombre de joueurs gagnés sont affichés.

$ python main.py 

--Game Start--

dealer's hands : [❤︎-J, *-*]
player's hands : [♦︎-3, ♠︎-3]

players's total_score : 6            

Hit(1) or Stand(2) : 1
player draw card is : ♠︎-Q
players's total_score : 16

Hit(1) or Stand(2) : 1
player draw card is : ♠︎-5
players's total_score : 21

--Result--

dealer's hands : [❤︎-J, ♦︎-5]
dealer's total_score : 15            
dealer draw card is : ❤︎-Q
dealer's total_score : 25
dealer burst!!!

/***********/
/player win!/
/***********/

--Game End--

Q termine le jeu, sinon le jeu commence:

--Game Start--

dealer's hands : [♠︎-10, *-*]
player's hands : [♠︎-8, ♦︎-8]

players's total_score : 16            

Hit(1) or Stand(2) : 2

--Result--

dealer's hands : [♠︎-10, ♣️-A]
dealer's total_score : 11, 22            
dealer draw card is : ♣️-5
dealer's total_score : 16, 27
dealer draw card is : ♣️-Q
dealer's total_score : 26, 37
dealer burst!!!

/***********/
/player win!/
/***********/

--Game End--

Q termine le jeu, sinon le jeu commence:

--Game Start--

dealer's hands : [❤︎-K, *-*]
player's hands : [♦︎-A, ♠︎-7]

players's total_score : 8, 19            

Hit(1) or Stand(2) : 2

--Result--

dealer's hands : [❤︎-K, ♠︎-J]
dealer's total_score : 20            

/***********/
/dealer win!/
/***********/

--Game End--

Terminez le jeu avec Q, démarrez le jeu sinon: Q
*-*-*-*-*-*-*-*
total:3
win:2
lose:1
draw:0
*-*-*-*-*-*-*-*

fin

Double down et split sont des problèmes futurs.

Recommended Posts

J'ai essayé d'implémenter le blackjack du jeu Trump en Python
J'ai essayé d'implémenter le jeu de cartes de Trump en Python
J'ai essayé d'implémenter PLSA en Python
J'ai essayé d'implémenter la permutation en Python
J'ai essayé d'implémenter ADALINE en Python
J'ai essayé d'implémenter PPO en Python
J'ai essayé de mettre en œuvre un jeu de dilemme de prisonnier mal compris en Python
J'ai essayé d'implémenter TOPIC MODEL en Python
J'ai essayé d'implémenter le tri sélectif en python
J'ai essayé d'implémenter un pseudo pachislot en Python
J'ai essayé d'implémenter le poker de Drakue en Python
J'ai essayé d'implémenter GA (algorithme génétique) en Python
J'ai essayé d'implémenter un automate cellulaire unidimensionnel en Python
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
J'ai essayé de corriger "J'ai essayé la simulation probabiliste du jeu de bingo avec Python"
J'ai écrit un doctest dans "J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python"
J'ai essayé de jouer à un jeu de frappe avec Python
J'ai essayé d'implémenter la régression linéaire bayésienne par échantillonnage de Gibbs en python
J'ai essayé d'implémenter PCANet
J'ai essayé d'implémenter StarGAN (1)
J'ai essayé de représenter graphiquement les packages installés en Python
Je veux facilement implémenter le délai d'expiration en python
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de résumer comment utiliser les pandas de python
[Python] J'ai essayé d'obtenir Json de squid ring 2
J'ai essayé d'implémenter le calcul automatique de la preuve de séquence
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé d'implémenter le tri par fusion en Python avec le moins de lignes possible
J'ai essayé d'implémenter ce qui semble être un outil de snipper Windows avec Python
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé d'implémenter Deep VQE
J'ai essayé de créer une API list.csv avec Python à partir de swagger.yaml
J'ai essayé de toucher Python (installation)
Implémentation du jeu de vie en Python
J'ai essayé de mettre en place une validation contradictoire
J'ai essayé "Comment obtenir une méthode décorée en Python"
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai essayé d'implémenter Realness GAN
J'ai essayé la notification de ligne en Python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
[Python] J'ai essayé d'implémenter un tri stable, alors notez
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
J'ai essayé de créer une liste de nombres premiers avec python
J'ai écrit le code pour écrire le code Brainf * ck en python
Implémenter un automate fini déterministe en Python pour déterminer des multiples de 3
J'ai essayé de faire 5 modèles de base d'analyse en 3 ans
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
J'ai essayé de collecter automatiquement des images de Kanna Hashimoto avec Python! !!
J'ai essayé de résumer la gestion des exceptions Python
J'ai essayé d'implémenter Autoencoder avec TensorFlow
Entrée standard Python3 que j'ai essayé de résumer
J'ai essayé d'utiliser l'optimisation bayésienne de Python
Je voulais résoudre ABC159 avec Python
J'ai essayé d'implémenter CVAE avec PyTorch
[Python] J'ai essayé de calculer TF-IDF régulièrement