[Edu-sig] more card play

Edward Cherlin echerlin at gmail.com
Tue Nov 3 05:27:35 CET 2009


Cards: You are right on the merits for combinatory math, but you will
run into strong cultural aversions.

Reverse string in place with new iterator: There is a great deal more
of this. In the 1980s Hewlett-Packard built an APL system around such
transformations in place and lazy evaluation rules, including
matrix/table transpose, take, drop, catenate, laminate, and a number
of other transformations and combinations. I can probably dig out
Harry Saal's paper on the subject. Indeed, that and several others.

http://portal.acm.org/citation.cfm?id=801218&dl=GUIDE&coll=GUIDE&CFID=59626041&CFTOKEN=28525913
An APL compiler for the UNIX timesharing system

http://portal.acm.org/citation.cfm?id=586034&dl=GUIDE&coll=GUIDE&CFID=59626133&CFTOKEN=77609109
Considerations in the design of a compiler for APL

http://portal.acm.org/citation.cfm?id=804441
A software high performance APL interpreter

On Sun, Nov 1, 2009 at 19:55, kirby urner <kirby.urner at gmail.com> wrote:
> I'm becoming more enamored of the idea of using playing cards as a
> standard feature in my Python pedagogy and andragogy (means teaching
> adults).  Not only do we have the standard deck, but also Tarot which
> could get us more into text files, string substitution
> (string.Template) and so forth.
>
> Cards have all the elements
>
> Mathematically, a Deck suggests the difference between Cardinality
> (yes, a silly pun) and Ordinality.  You might imagine a deck in which
> you can't decipher the cards, don't know their "face value", and so
> have no clear idea of their ranking (ordinality).
>
> On the other hand, you know which cards are the same and which are
> different across multiple decks (le'ts just say), which is the meaning
> of "cardinality" (difference without any implied ordering).
>
> Midhat Gazele dwells on this difference some in his book 'Number'.
> You might have a set of objects, say stones or wasp specimens, and a
> way of cataloging them that doesn't implement > or < or even ==.
> There is only the Python "is" and "is not" for determining of two
> objects have the same identity or not.  License plates on cars, proper
> names, have this purpose of distinguishing.
>
> However, very quickly just about any set beyond a certain size needs
> an ordering, perhaps simply alphabetical, so that one might flip
> through a lookup table in a hurry and get to the desired object.
> People used to use ledgers, thick books, for such cataloging.
>
> This is the beginning of data structuring or data structures.  The
> idea of "ordering" (ordinality) is very closely associated with that
> of cardinality.
>
> Anyway, over on Pyfora I was noticing a member suggesting reversing a
> string might be best accomplished by thestring[::-1], i.e. extended
> slicing with from the end to the beginning step with a step of -1.
> However PEP 322 suggests this will be inefficient compared a a built
> in function introduced in 2.4:  reversed.
>
> According to the PEP, all reversed needs is for the consumed object to
> support __getitem__ and __len__.  If those two are present, the
> function will do the rest, and return an iterator object in which the
> contents of a sequence are iterated over in reverse order.
>
>>>> a = 'the rain in spain stays mainly in the plain'
>>>> ''.join(reversed(a))
> 'nialp eht ni ylniam syats niaps ni niar eht'
>
> So for our Deck to be reversible by means of this built in function,
> the only methods we need to implement are these two, __getitem__ and
> __len__.  I do this below, plus make shuffling the deck upon
> instantiation an option, not de rigueur (not mandatory).  This makes
> it easier to see what reverse order is like.
>
> Note that the returned iterable is not itself a Deck, nor is it
> subscriptable, as the whole point of an iterable is it returns its
> contents "just in time" as you iterate over it.  The cards are not
> "already present" in reversed order, are simply returned in reverse
> order.
>
> Of course you can force the iterable to dump all its contents by
> coercing it into a list.  I do this as a part of the clone_deck
> method.  Playing Game of War with clone decks, one the reverse of the
> other, results in a draw if always dealing from the top (now the
> default, yet still optional).
>
> The code below is just my Game of War again, with a few wrinkles.
> I've upgraded all string printing to use the
> print(thestring.format(args)) approach, versus the old percent sign
> string substitution codes.  Other small improvements.
>
>>>> from sillygame import Deck
>>>> d = Deck(10)
>>>> newd = d.clone_deck()
>>>> newd[0] is d[0]
> True
>>>> id(newd[0])
> 22884944
>>>> id(d[0])
> 22884944
>>>> d.shuffle()
>>>> str(d)
> "['7 of Diamonds', 'Jack of Spades', 'Queen of Clubs', 'King of
> Spades', '5 of Clubs', '3 of Spades', '6 of Hearts', 'Ace of Clubs',
> '2 of Hearts', '9 of Spades']"
>>>> str(newd)
> "['2 of Hearts', 'Queen of Clubs', '6 of Hearts', '9 of Spades', '5 of
> Clubs', '7 of Diamonds', 'Ace of Clubs', '3 of Spades', 'Jack of
> Spades', 'King of Spades']"
>>>> d[0]
> Card(Diamonds, ('7', 7))
>>>> newd[5]
> Card(Diamonds, ('7', 7))
>>>> d[0] == newd[5]
> True
>>>> d[0] is newd[5]
> True
>
> Kirby
>
> For further reading:
> http://www.python.org/dev/peps/pep-0322/
>
>
> from random import shuffle, randint
>
> thesuits = ['Hearts','Diamonds','Clubs','Spades']
> theranks = ['Ace'] + [str(v) for v in range(2,11)] + ['Jack','Queen','King']
> rank_values = list(zip(theranks, range(1,14)))
>
> class Card:
>
>    def __init__(self, suit, rank_value ):
>        self.suit = suit
>        self.rank = rank_value[0]
>        self.value = rank_value[1]
>
>    def __lt__(self, other):
>        if self.value < other.value:
>            return True
>        else:
>            return False
>
>    def __gt__(self, other):
>        if self.value > other.value:
>            return True
>        else:
>            return False
>
>    def __eq__(self, other):
>        if self.value == other.value:
>            return True
>        else:
>            return False
>
>    def __repr__(self):
>        return "Card({0}, {1})".format(self.suit, (self.rank, self.value))
>
>    def __str__(self):
>        return "{0} of {1}".format(self.rank, self.suit)
>
> class Deck:
>
>    def __init__(self, numcards = 52, shuffle = True):
>        # build a complete deck then slice
>        try:
>            assert 0 < numcards <= 52
>        except AssertionError:
>            print("Defaulting to 52 cards")
>            numcards = 52
>
>        self.numcards = numcards
>        self.cards = [Card(suit, rank_value)
>                      for suit in thesuits
>                      for rank_value in rank_values
>                       ]
>        if shuffle: self.shuffle()
>        self.cards = self.cards[ : self.numcards]
>
>    def __getitem__(self, index):
>        return self.cards[index]
>
>    def shuffle(self):
>        shuffle(self.cards)
>
>    def spit_card(self, top=True):
>        try:
>            assert self.numcards > 0
>        except AssertionError:
>            raise Exception("Out of cards!")
>
>        if top:
>            some_card = self.cards.pop(0)
>        else:
>            some_card = self.cards.pop( randint( 0, self.numcards - 1 ))
>
>        self.numcards = len(self.cards)
>        return some_card
>
>    def clone_deck(self, reverse=False):
>        newdeck = Deck(numcards=1)
>        newdeck.numcards = self.numcards
>        if reverse:
>            newdeck.cards = list(reversed(self.cards))
>        else:
>            newdeck.cards = self.cards[:]
>        return newdeck
>
>    def __repr__(self):
>        return "Deck({0})".format(self.numcards)
>
>    def __str__(self):
>        return str([str(card) for card in self.cards])
>
>    def __len__(self):
>        return len(self.cards)
>
> def test():
>    thedeck = Deck()
>    print (str(thedeck))
>
> def game_of_war():
>    deckA = Deck(10)
>    # deckB = Deck(10)
>    deckB = deckA.clone_deck(reverse=True) # play a reversed clone
>    PlayerA_score = 0
>    PlayerB_score = 0
>
>    try:
>        assert deckA.numcards == deckB.numcards
>    except AssertionError:
>        raise Exception("Decks don't have same number of cards")
>
>    for i in range(deckA.numcards):
>        playerA_card = deckA.spit_card(top=False) # deal from anywhere
>        playerB_card = deckB.spit_card(top=False)
>
>        if playerA_card > playerB_card:
>            PlayerA_score += 1
>            print("A's {0} beats B's {1}".format(playerA_card, playerB_card))
>        if playerA_card < playerB_card:
>            PlayerB_score += 1
>            print("B's {0} beats A's {1}".format(playerB_card, playerA_card))
>        if playerA_card == playerB_card:
>            print("B's {0} matches A's {1}".format(playerB_card, playerA_card))
>
>    if PlayerA_score > PlayerB_score:
>        print("Game Over:  A wins")
>    if PlayerA_score < PlayerB_score:
>        print("Game Over:  B wins")
>    if PlayerA_score == PlayerB_score:
>        print("Game Over:  it's a draw!")
>
> if __name__ == '__main__':
>    # test()
>    game_of_war()
> _______________________________________________
> Edu-sig mailing list
> Edu-sig at python.org
> http://mail.python.org/mailman/listinfo/edu-sig
>



-- 
Edward Mokurai (默雷/धर्ममेघशब्दगर्ज/دھرممیگھشبدگر ج) Cherlin
Silent Thunder is my name, and Children are my nation.
The Cosmos is my dwelling place, the Truth my destination.
http://www.earthtreasury.org/


More information about the Edu-sig mailing list