samedi 25 juillet 2020

Is This The Right Way of using OOP in Python? [closed]

I Have Been Learning Python For Last 2 month and i am very confused with OOP. I Have Created A Simple Blackjack Game using tkinter Module using Classes. Is This The Right Way of Using Classes in Python. I'm mostly interested in improving my OOP, so I would appreciate your feedback.

Cards Images : https://drive.google.com/uc?export=download&id=1U3rgUNa8F93VQz-B39I7-V0w_RaLDQ5M

import random
import tkinter


class Deck(object):
    """Basic Class For Cards

    args:
        card_type (list[Card_Types]) = A list Containing All Cards Types diamond, spade, heart, club
        high_cards (list[high_cards]) = a List Containing high_cards jack, king, queen
        card_no (range) = card no from 1 to 10 for each card_type total 52 card
        cards list(card_image, card_value) = an Empty List To Store All Cards images and its value inside a Tuple
    methods:
        load_cards() : A Method To Load Cards images and its Value in Cards list
        shuffle() : A Method To Shuffle Cards"""

    def __init__(self):
        self.card_types = ["club", "diamond", "heart", "spade"]
        self.high_cards = ["jack", "king", "queen"]
        self.card_no = [i for i in range(1, 11)]
        self.cards = []

    def load_cards(self):
        extension = ".png"
        for card_type in self.card_types:
            for card_no in self.card_no:
                # Creating Card Directory Location
                card_dir = "cards/{0}_{1}{2}".format(card_no, card_type, extension)
                image = tkinter.PhotoImage(file=card_dir)
                self.cards.append((image, card_no))

            for card in self.high_cards:
                card_dir = "cards/{0}_{1}{2}".format(card, card_type, extension)
                image = tkinter.PhotoImage(file=card_dir)
                self.cards.append((image, 10))
        return self.cards

    def shuffle_cards(self):
        random.shuffle(self.cards)

    def __len__(self):
        return len(self.cards)

    def __getitem__(self, i):
        return self.cards[i]


class Dealer(object):
    def __init__(self):
        self.hand = []
        self.score = 0


class Player(Dealer):
    def __init__(self, name="unnamed"):
        super().__init__()
        self.name = name


class BlackJack(object):

    def __init__(self):
        self.main_window = tkinter.Tk()
        self.deck = Deck()
        self.player = Player("Afzal")
        self.dealer = Dealer()
        self.main_frame = tkinter.Frame(self.main_window, background="green")
        self.dealer_frame = tkinter.Frame(self.main_frame, background="green")
        self.player_frame = tkinter.Frame(self.main_frame, background="green")
        self.result_var = tkinter.StringVar()
        self.player_score_var = tkinter.IntVar()
        self.dealer_score_var = tkinter.IntVar()

    def start_game(self):
        self.main_window.title("BlackJack")
        self.main_window.geometry("640x480")
        self.main_window["padx"] = 7
        self.main_window["pady"] = 7
        # Adding Result Label To Display Who Wins
        result_label = tkinter.Label(self.main_window, textvariable=self.result_var)
        result_label.grid(row=0, column=0, columnspan=3, sticky="ew")
        result_label.config(background="green", fg="black")
        # Adding Card Frames For Player And Dealer
        # main_frame = tkinter.Frame(self.main_window, background="green")
        self.main_frame.grid(row=1, column=0, columnspan=3, rowspan=3, sticky="ew")
        self.main_frame["padx"] = 5
        self.main_frame["pady"] = 5

        # Adding Dealer_name and Score
        dealer_name = tkinter.Label(self.main_frame, text="Dealer")
        dealer_name.grid(row=0, column=0)
        dealer_name.config(background="green", fg="black")
        dealer_score = tkinter.Label(self.main_frame, textvariable=self.dealer_score_var)
        dealer_score.grid(row=1, column=0)
        dealer_score.config(background="green", fg="black")

        # Adding playername and Score
        player_name = tkinter.Label(self.main_frame, text=self.player.name)
        player_name.grid(row=2, column=0)
        player_name.config(background="green", fg="black")
        player_score = tkinter.Label(self.main_frame, textvariable=self.player_score_var)
        player_score.grid(row=3, column=0)
        player_score.config(background="green", fg="black")

        # Adding Frame For Dealers Cards
        self.dealer_frame.grid(row=0, column=1, rowspan=1, sticky="ew")
        self.dealer_frame["padx"] = 3
        self.dealer_frame["pady"] = 3

        # Adding Frame For Player Cards
        self.player_frame.grid(row=2, column=1, rowspan=1, sticky="ew")

        # Adding Buttons For Player , dealer and Newgame
        dealer_button = tkinter.Button(self.main_window, text="Dealer", command=self.dealer_card)
        player_button = tkinter.Button(self.main_window, text=self.player.name, command=self.player_card)
        new_game = tkinter.Button(self.main_window, text="New Game", command=self.new_game)
        dealer_button.grid(row=4, column=0)
        player_button.grid(row=4, column=1)
        new_game.grid(row=4, column=2)

        # Load Cards in Deck
        self.deck.load_cards()

        # Distribute Starting Cards 2 For Player And 1 For Dealer
        self.start_cards()

        self.main_window.mainloop()

    def deal_cards(self, frame):
        self.deck.shuffle_cards()
        next_card = self.deck.cards.pop()
        tkinter.Label(frame, image=next_card[0]).pack(side="left")
        # print(len(self.deck))
        self.deck.cards.append(next_card)
        print(self.deck.cards)
        return next_card

    def player_card(self):
        self.player.hand.append(self.deal_cards(self.player_frame))
        print("Player Hand", self.player.hand)
        self.player.score = self.calculate_hand(self.player.hand)
        self.player_score_var.set(self.player.score)
        if self.player.score > 21:
            self.result_var.set("Dealer Wins")
        elif self.player.score > 21 and self.player.score == self.dealer.score:
            self.result_var.set("Draw")

    def dealer_card(self):
        self.dealer.hand.append(self.deal_cards(self.dealer_frame))
        print("Dealer Hand", self.dealer.hand)
        self.dealer.score = self.calculate_hand(self.dealer.hand)
        self.dealer_score_var.set(self.dealer.score)
        if self.dealer.score > 21:
            self.result_var.set(self.player.name + " Wins")
        elif self.dealer.score > 21 and self.dealer.score == self.player.score:
            self.result_var.set("Draw")

    @staticmethod
    def calculate_hand(hand):
        ace = False
        score = 0
        for i in hand:
            card_value = i[1]
            if card_value == 1 and not ace:
                card_value = 11
                ace = True
            score += card_value
            if score >= 21 and ace:
                score -= 10
                ace = False
        return score

    def new_game(self):
        self.dealer.hand.clear()
        self.player.hand.clear()
        self.dealer_frame.destroy()
        self.player_frame.destroy()
        self.player.score = 0
        self.dealer.score = 0
        self.result_var.set("")
        self.dealer_frame = tkinter.Frame(self.main_frame, background="green")
        self.player_frame = tkinter.Frame(self.main_frame, background="green")
        self.dealer_frame.grid(row=0, column=1, rowspan=1, sticky="ew")
        self.player_frame.grid(row=2, column=1, rowspan=1, sticky="ew")
        self.deck.shuffle_cards()
        self.start_cards()

    def start_cards(self):
        self.player_card()
        self.dealer.hand.append(self.deal_cards(self.dealer_frame))
        self.dealer.score = self.calculate_hand(self.dealer.hand)
        self.dealer_score_var.set(self.dealer.score)
        self.player_card()


blackjack = BlackJack()
blackjack.start_game()



Aucun commentaire:

Enregistrer un commentaire