Есть ли способ сортировки объектов, созданных с помощью классов, который состоит из строк и целых чисел в Python? - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть задание создать колоду карт с помощью класса с методами, которые разыгрывают, перемешивают, раздувают, проверяют и проверяют, в порядке ли колода, но у меня возникают проблемы при создании последней. Колода должна быть упорядочена по их значениям в каждой масти, а масти - в виде треф, алмазов, сердец, а затем пиков. Мой код до этого момента находится ниже:

import random

class Card():

    def __init__(self, value, suit):
        self.value = value
        self.suit = suit


    def show_card(self):
        print(str(self.value)+ " of " + str(self.suit))


class Deck():

    deck_of_cards = []
    cards_in_play = [] 
    draw_card = None

    def __init__(self):
        self.make_deck()      


    def make_deck(self):
        for suit in ['Clubs', 'Diamonds', 'Hearts', 'Spades']:
            for value in [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']:
                self.deck_of_cards.append(Card(value,suit))
                self.cards_in_play.append(Card(value, suit))

    def shuffle(self):
        self.shuffled_deck = random.shuffle(self.cards_in_play)


    def fan(self):
        for card in self.cards_in_play:
            card.show_card()

    def deal(self):
        draw_card=self.cards_in_play.pop()
        draw_card.show_card()

    def order(self):
        for suit in ['Club', 'Diamonds', 'Hearts', 'Spades']:
            for value in [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']:
                self.deck_of_cards.append(Card(value, suit))
                self.cards_in_play.append(Card(value, suit))

Ответы [ 3 ]

0 голосов
/ 20 апреля 2020

Некоторые исправления кода перед тем, как мы go on:

  1. Универсализируем список suits и values, чтобы он мог использоваться всеми классами при необходимости.
  2. Переместите deck_of_cards и cards_in_play внутрь функции __init__. Если вы этого не сделаете, это называется «атрибут класса» и сделает его таким, чтобы у каждого класса было это значение, если оно не инициализировано (вероятно, что-то, что вы не собираетесь).
class Test:
    a = 10

t1 = Test
t2 = Test

t1.a = 11
print(t2.a) # >>> 11
random.shuffle() - это функция, которая работает на месте. Другими словами, он возвращает None, но изменяет указанный ему список.
import random

l = ["a", "b", "c"]
print(random.shuffle(l)) # >>> None
print(l) # >>> [b, c, a]
Не печатайте вещи - верните их. Это сделает ваш код не только более понятным, но и более полезным. Если вы хотите напечатать что-то, что возвращает функция, просто напечатайте возврат.
def deal(self):
    draw_card = self.cards_in_play.pop()
    return draw_card
Ознакомьтесь с sort и __lt__ (подробности ниже).
import random
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']

class Card:
    def __init__(self, value, suit):
        self.suit = suit
        self.value = value

    def __lt__(self, other):
        if suits.index(self.suit) > suits.index(other.suit):
            return False

        if values.index(self.value) > values.index(other.value):
            return False

        return True

    def __repr__(self):
        return f"{self.value} of {self.suit}"

class Deck:
    def __init__(self):    
        self.deck_of_cards = []
        self.cards_in_play = []

        self.make_deck()

    def make_deck(self):
        for suit in suits:
            for value in values:
                self.deck_of_cards.append(Card(value,suit))
                self.cards_in_play.append(Card(value, suit))

    def shuffle(self):
        random.shuffle(self.cards_in_play)

    def fan(self):
        for card in self.cards_in_play:
            print(card)

    def deal(self):
        draw_card = self.cards_in_play.pop()
        return draw_card

    def order(self):
        self.cards_in_play.sort()

    def __repr__(self):
        return repr(self.cards_in_play)

Использование метода волхвов c __lt__ (меньше), мы можем использовать функцию sort для автоматической сортировки class. Чтобы прояснить ситуацию, обратите внимание на следующее:

# Your new `order` function.
def order(self):
    self.cards_in_play.sort()

# Implementing __lt__ now allows us to do the following comparison (which is what sort will use to sort your list of Card objects):
print(Card("Clubs", 2) > Card("Clubs", 3)) # True

# If you notice on docs, __ge__ (greater than), __eq__ (equal than), etc. can also be implemented to give you full flexibility.

Обратите внимание, я также добавил функцию __repr__ к Deck и Card, чтобы вы могли вместо этого больше просто сделайте:

card = Card("Clubs", 2)
print(card) # >>> 2 of Clubs

Редактировать: @Discussion ниже.

suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']

class Card:
    def __init__(self, value, suit):
        self.suit = suit
        self.value = value

    def __lt__(self, other):
        if suits.index(self.suit) > suits.index(other.suit):
            return False

        if values.index(self.value) > values.index(other.value):
            return False

        return True

    def __eq__(self, other):
        if self.suit == other.suit and self.value == other.value:
            return True
        else:
            return False

    def __repr__(self):
        return f"{self.value} of {self.suit}"

С новым методом __eq__ мы можем использовать знак == между классами.

c1 = Card(2, "Clubs")
c2 = Card(2, "Diamonds")
c3 = Card(2, "Diamonds")

print(c1 == c2) # False
print(c1 > c2) # False
print(c1 < c2) # True
print(c2 == c3) # True

Это позволяет нам с легкостью сравнивать Card s.

0 голосов
/ 20 апреля 2020

Вы можете инициализировать свой класс карты следующим образом:

values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']

class Card:
    def __init__(self, value, suit):
        self.suit = suit
        self.value = value
        #if value order matters in first place
        self.rank = 4*values.index(self.value) + suits.index(self.suit)
        #else
        self.rank = 13*suits.index(self.suit) + values.index(self.value)

и создать функцию проверки следующим образом:

class Deck:
    def check(self):
        rank_before = self.cards_in_play[0].rank
        for card in self.cards_in_play[1:]:
            rank = card.rank
            if rank > rank_before:
                rank_before = rank
            else:
                return False
        return True
0 голосов
/ 20 апреля 2020

Канонический способ справиться с этим - понять, что у вас есть две идентичности для карты: ее игровая ценность и ее отображаемое значение. Вам нужен простой аналог функции __repr__.

Очень просто, значение value с простым целым числом ранга, card_rank, 0-12. Значение display , которое вы печатаете каждый раз, когда human ссылается на него, обрабатывается с помощью тривиального списка перевода:

print_value = (
    '2', '3', '4', '5', '6', '7', '8', '9', '10',
    'Jack', 'Queen', 'King', 'Ace'
)

Всякий раз, когда вам нужно вывести значение, вы просто используете print_value[card_rank]. Поместите это в функцию __repr__ вашего Card класса.

С этим разделением функций сортировка по card_rank решает вашу проблему без лишних слов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...