ichabod801 / t_games

A collection of command-line interface games written in Python.
GNU General Public License v3.0
20 stars 4 forks source link

Make a Pile class in cards.py #416

Closed ichabod801 closed 4 years ago

ichabod801 commented 4 years ago

This would be the parent class of Hand and Deck, including all of the list methods, which go straight to the cards attribute. This is a child of issue #413: update cards.py.

ichabod801 commented 4 years ago

The sum totality of the Pile class is to apply all of the list methods to the cards attribute. Why not just have Hand and Deck inherit from list, and have the cards attribute be self? Deck could still have a discards attribute and they could have their extra methods. Just check whether I should inherit from list or UserList (that's a thing, right?).

ichabod801 commented 4 years ago

Okay, researched it, and there are three options for parent classes:

I don't intend to have them mess with dunders, so it seems that list is safe (and more efficient). So I don't need a pile class.

ichabod801 commented 4 years ago

Created issue #435 to redo Deck and Hand as inheriting from list.

ichabod801 commented 4 years ago

Directly subclassing from list is not working. I either need to subclass UserList or MutableSequence.

ichabod801 commented 4 years ago

UserList does a lot of the work for you, whereas MutableSequence only does some of the work for you. The thing with UserList is that when it creates a new item (such as from a slice), that item is passed through the init method with data (the list data) as the one argument. But I'm also going to be passing ranks and suits (and probably more) as arguments to the init. So if you have a Deck that isn't using the defaults, slices of it won't have the right attributes (they'll have the default attributes).

Now, you can override the right methods and fix that. And that's what you'd have to do with MutableSequence anyway. It might still be easier to do UserList than MutableSequence. However, UserList automatically defines the underlying list as data. So I would have to have a cards attribute pointing at the data attribute. With mutable sequence, I could just name the underlying sequence cards.

ichabod801 commented 4 years ago

Mutable sequence provides the following methods: __contains__, __iadd__, __iter__, __reversed__, append, count, extend, index, pop, reverse, and remove. But note that it does not provide __add__.

ichabod801 commented 4 years ago

Say I have a method named _attr_copy. It takes a sequence and creates an instance of the same class with the same attributes. Then the UserList methods can all be overridden like so:

def __add__(self, other):
    sum = super(UserDeck, self).__add__(other)
    return self._attr_copy(sum)
ichabod801 commented 4 years ago

I could do the same to simplify MutableSequence based lists:

def __add__(self, other):
    return self._attr_copy(self.cards + other.cards)

I think that would be even more lightweight.

ichabod801 commented 4 years ago

I'm planning on using MutableSequence, but there are some other questions to answer. When do you want a Deck, and when do you want a list of cards? If you're doing a slice, you are probably just interested in a list of cards, and don't need or want the extra baggage. But when you are adding two Decks, you are going to want a deck in response. Would implementing that inconsistency be a problem?

ichabod801 commented 4 years ago

Let's think about exactly what we are talking about here. What are the methods that return a container of cards?

That would be it, except for variants of the mathematical ones. It looks like getitem would be the only one to return a list. But that's in terms of Decks. A slice of a Hand should be a Hand. In that case, go with the extra baggage. If people don't want a full Deck, they can slice cards directly.

ichabod801 commented 4 years ago

Hearts seems to make the most use of self.deck.cards, so I will do testing in that game.

ichabod801 commented 4 years ago

Note that some of the changes affect the kitty in Hearts (extras = first or heart).

ichabod801 commented 4 years ago

Gin Rummy is tied for Hearts for number of 'hand' references. I am going to test the new hand in Gin for variety.