[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