Code: Alles auswählen
self.cs = ""
self.nn = 0
self.suit = suit
self.value = value
self.color = COLOR[suit]
self.face_shown = 0
self.x = self.y = 0
self.group = Group(canvas)
self.cs = self.cardmap(value, suit)
filename = pathname + self.cs + ".gif"
self.fimg = PhotoImage(file=filename)
self.__front = ImageItem(canvas, 0, 0,
anchor=NW, image=self.fimg )
self.group.addtag_withtag(self.__front)
self.nn = self.nn+value
self.csbk = self.cardback(self.nn)
filename = pathname + self.csbk + ".gif"
self.img = PhotoImage(file=filename )
self.__back = ImageItem(canvas, 0, 0,
anchor=NW, image=self.img )
self.group.addtag_withtag(self.__back)
def cardback(self, nc):
if (nc == 1 ):
n = 6
oldsets = ["back001", "back101", "back102", "back111", "back191", "back192"]
for i in randperm(n):
newsets.append(oldsets[i])
oldsets = newsets
return oldsets[0]
else:
return newsets[0]
def randpm(self):
"""Function returning a random permutation of range(n)."""
r = range(n)
x = []
while r:
i = random.choice(r)
x.append(i)
r.remove(i)
return x
def cardmap(self, rank, tsuit):
text = ""
t1 = ""
n = 0
suit = 0
if (tsuit == "Club"):
suit = 0
elif (tsuit == "Heart"):
suit = 1
elif (tsuit == "Diamond"):
suit = 2
elif (tsuit == "Spade"):
suit = 3
if (rank >=1 and rank <= 9):
if (suit == 3):
n = rank
t1 = str(n)
text = "0"+ t1 + "s"
elif (suit == 2):
n = rank
t1 = str(n)
text = "0"+ t1 + "d"
elif (suit == 1):
n = rank
t1 = str(n)
text = "0"+ t1 + "h"
elif (suit == 0):
n = rank
t1 = str(n)
text = "0"+ t1 + "c"
if (rank >=10 and rank <= 13):
if (suit == 3):
n = rank
t1 = str(n)
text = t1 + "s"
elif (suit == 2):
n = rank
t1 = str(n)
text = t1 + "d"
elif (suit == 1):
n = rank
t1 = str(n)
text = t1 + "h"
elif (suit == 0):
n = rank
t1 = str(n)
text = t1 + "c"
return text
def __repr__(self):
"""Return a string for debug print statements."""
return "Card(%s, %s)" % (`self.suit`, `self.value`)
def moveto(self, x, y):
"""Move the card to absolute position (x, y)."""
self.moveby(x - self.x, y - self.y)
def moveby(self, dx, dy):
"""Move the card by (dx, dy)."""
self.x = self.x + dx
self.y = self.y + dy
self.group.move(dx, dy)
def tkraise(self):
"""Raise the card above all other objects in its canvas."""
self.group.tkraise()
def showface(self):
"""Turn the card's face up."""
self.tkraise()
self.__front.tkraise()
self.face_shown = 1
def showback(self):
"""Turn the card's face down."""
self.tkraise()
#self.__front.tkraise()
self.__back.tkraise()
self.face_shown = 0
class Stack:
"""A generic stack of cards.
This is used as a base class for all other stacks (e.g. the deck,
the suit stacks, and the row stacks).
Public methods:
add(card) -- add a card to the stack
delete(card) -- delete a card from the stack
showtop() -- show the top card (if any) face up
deal() -- delete and return the top card, or None if empty
Method that subclasses may override:
position(card) -- move the card to its proper (x, y) position
The default position() method places all cards at the stack's
own (x, y) position.
userclickhandler(), userdoubleclickhandler() -- called to do
subclass specific things on single and double clicks
The default user (single) click handler shows the top card
face up. The default user double click handler calls the user
single click handler.
usermovehandler(cards) -- called to complete a subpile move
The default user move handler moves all moved cards back to
their original position (by calling the position() method).
Private methods:
clickhandler(event), doubleclickhandler(event),
motionhandler(event), releasehandler(event) -- event handlers
The default event handlers turn the top card of the stack with
its face up on a (single or double) click, and also support
moving a subpile around.
startmoving(event) -- begin a move operation
finishmoving() -- finish a move operation
"""
def __init__(self, x, y, game=None):
"""Stack constructor.
Arguments are the stack's nominal x and y position (the top
left corner of the first card placed in the stack), and the
game object (which is used to get the canvas; subclasses use
the game object to find other stacks).
"""
self.x = x
self.y = y
self.game = game
self.cards = []
self.tagcards = []
self.group = Group(self.game.canvas)
self.group.bind('<1>', self.clickhandler)
self.group.bind('<Double-1>', self.doubleclickhandler)
self.group.bind('<B1-Motion>', self.motionhandler)
self.group.bind('<ButtonRelease-1>', self.releasehandler)
self.group.bind('<3>', self.rightclickhandler)
self.makebottom()
def makebottom(self):
pass
def __repr__(self):
"""Return a string for debug print statements."""
return "%s(%d, %d)" % (self.__class__.__name__, self.x, self.y)
def isEmpty(self):
return (len(self.cards) == 0)
def isQspade(self):
for card in self.cards:
if ( card.suit == 'Spade' and card.value == 12 ):
return card;
else:
return 0;
def popCard(self):
card = self.cards.pop()
card.group.dtag(self.group)
return card
def numCard(self):
return len(self.cards)
# Public methods
def add(self, card):
self.cards.append(card)
card.tkraise()
self.position_maid(card)
self.group.addtag_withtag(card.group)
def tagremove(self, card):
self.tagcards.remove(card)
def delete(self, card):
self.cards.remove(card)
card.group.dtag(self.group)
def showtop(self):
if self.cards:
self.cards[-1].showface()
def deals(self):
if not self.cards:
return None
for card in self.cards:
if ( card.suit == 'Club' and card.value == 12 ):
self.game.board.add(card)
card.showface()
self.delete(card)
card = self.cards[-1]
self.delete(card)
return card
# Subclass overridable methods
def position(self, card):
card.moveto(self.x, self.y)
def position_maid(self, card):
card.moveto(self.x, self.y)
def userclickhandler(self):
pass
def userdoubleclickhandler(self):
pass
def usermovehandler(self, cards):
for card in cards:
self.position(card)
# Event handlers
def rightclickhandler(self, event):
tags = self.game.canvas.gettags('current')
for i in range(len(self.tagcards)):
card = self.tagcards[i]
if card.group.tag in tags:
count = i
#self.game.canvas.itemconfig(card.group.tag, fill='white')
break
def clickhandler(self, event):
self.finishmoving() # In case we lost an event
self.userclickhandler()
self.startmoving(event)
def motionhandler(self, event):
self.keepmoving(event)
def releasehandler(self, event):
self.keepmoving(event)
self.finishmoving()
def doubleclickhandler(self, event):
self.finishmoving() # In case we lost an event
self.userdoubleclickhandler()
self.startmoving(event)
# Move internals
moving = None
def startmoving(self, event):
self.moving = None
tags = self.game.canvas.gettags('current')
for i in range(len(self.cards)):
card = self.cards[i]
if card.group.tag in tags:
break
else:
return
self.moving = self.cards[i]
card = self.cards[i]
card.showface()
self.lastx = event.x
self.lasty = event.y
card.tkraise()
def keepmoving(self, event):
if not self.moving:
return
dx = event.x - self.lastx
dy = event.y - self.lasty
self.lastx = event.x
self.lasty = event.y
card = self.moving
card.moveby(dx, dy)
def finishmoving(self):
card = self.moving
if card:
self.usermovehandler(card)
self.moving = None
class Deck(Stack):
"""The deck is a stack with support for shuffling.
New methods:
fill() -- create the playing cards
shuffle() -- shuffle the playing cards
A single click moves the top card to the game's open deck and
moves it face up; if we're out of cards, it moves the open deck
back to the deck.
"""
def makebottom(self):
bottom = Rectangle(self.game.canvas,
self.x, self.y,
self.x+CARDWIDTH, self.y+CARDHEIGHT,
outline='black', fill=BACKGROUND)
self.group.addtag_withtag(bottom)
def fill(self):
for suit in ALLSUITS:
for value in ALLVALUES:
self.add(Card(suit, value, self.game.canvas))
def shuffle(self):
n = len(self.cards)
newcards = []
for i in randperm(n):
newcards.append(self.cards[i])
self.cards = newcards
def randperm(n):
"""Function returning a random permutation of range(n)."""
r = range(n)
x = []
while r:
i = random.choice(r)
x.append(i)
r.remove(i)
return x
class BoardStack(Stack):
def makebottom(self):
bottom = Rectangle(self.game.canvas,
self.x, self.y,
self.x+CARDWIDTH, self.y+CARDHEIGHT,
outline='black', fill='')
class PlayStack(Stack):
def position_maid(self, card):
x = self.x
y = self.y
yor = y
xor = x
i = 0
for c in self.cards:
if c == card:
break
if c.face_shown:
if (i <= 6):
y = y + 2*MARGIN
else:
x = xor + 2*MARGIN + CARDWIDTH
y = y + 2*MARGIN
i = i + 1
if ( i == 8 ):
y = yor
else:
if (i <= 6):
y = y + 2*MARGIN
else:
x = xor + 2*MARGIN + CARDWIDTH
y = y + 2*MARGIN
i = i + 1
if ( i == 8 ):
y = yor
card.moveto(x, y)
def OpenCards(self):
for card in self.cards:
#self.position_maid(card)
card.showface()
def moveACard(self,card):
self.game.board.add(card)
def OpenACard(self,card):
#self.position_maid(card)
card.showface()
def ShowABack(self,card):
#self.position_maid(card)
card.showback()
def cardExists(self,other):
for card in self.cards:
j = card.value
j1 = other.value
if card.suit == other.suit and j == j1:
self.game.board.add(card)
card.showface()
self.cards.remove(card)
return 0
def cardCkExists(self,other):
k = 0
for card in self.cards:
j = card.value
j1 = other.value
if card.suit == other.suit and j == j1:
k = k + 2
return k
def cardTagExists(self,other):
for card in self.tagcards:
j = card.value
j1 = other.value
if card.suit == other.suit and j == j1:
self.game.board.add(card)
card.showface()
self.cards.remove(card)
self.tagcards.remove(card)
return 0
def shuffled(self):
import random
nCards = len(self.cards)
for i in range(nCards):
j = random.randrange(i, nCards)
self.cards[i], self.cards[j] = self.cards[j], self.cards[i]
for card in self.cards:
self.position_maid(card)
def removeMatches(self):
count = 0
for card in self.cards:
if ( card.suit == 'Club' ):
match = Card('Spade', card.value, self.game.canvas)
i = self.cardExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
elif ( card.suit == 'Spade' ):
match = Card('Club', card.value, self.game.canvas)
i = self.cardExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
elif ( card.suit == 'Heart' ):
match = Card('Diamond', card.value, self.game.canvas)
i = self.cardExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
elif ( card.suit == 'Diamond' ):
match = Card('Heart', card.value, self.game.canvas)
i = self.cardExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
count = count + 1
return count
def removeTagMatches(self):
count = 0
for card in self.tagcards:
if ( card.suit == 'Club' ):
match = Card('Spade', card.value, self.game.canvas)
i = self.cardTagExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
self.tagremove(card)
elif ( card.suit == 'Spade' ):
match = Card('Club', card.value, self.game.canvas)
i = self.cardTagExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
self.tagremove(card)
elif ( card.suit == 'Heart' ):
match = Card('Diamond', card.value, self.game.canvas)
i = self.cardTagExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
self.tagremove(card)
elif ( card.suit == 'Diamond' ):
match = Card('Heart', card.value, self.game.canvas)
i = self.cardTagExists(match)
if i == 0:
self.game.board.add(card)
card.showface()
self.delete(card)
self.tagremove(card)
count = count + 1
while (len(self.tagcards) > 0):
for card in self.tagcards:
self.tagremove(card)
return count
def checkMatches(self):
k = 0
for card in self.cards:
if ( card.suit == 'Club' ):
match = Card('Spade', card.value, self.game.canvas)
k = k + self.cardCkExists(match)
if (match):
match.showface()
card.showface()
elif ( card.suit == 'Spade' ):
match = Card('Club', card.value, self.game.canvas)
k = k + self.cardCkExists(match)
if (match):
match.showface()
card.showface()
elif ( card.suit == 'Heart' ):
match = Card('Diamond', card.value, self.game.canvas)
k = k + self.cardCkExists(match)
if (match):
match.showface()
card.showface()
elif ( card.suit == 'Diamond' ):
match = Card('Heart', card.value, self.game.canvas)
k = k + self.cardCkExists(match)
if (match):
match.showface()
card.showface()
return k
def userdoubleclickhandler(self):
tags = self.game.canvas.gettags('current')
for i in range(len(self.cards)):
card = self.cards[i]
self.moving = card
if card.group.tag in tags:
self.tagcards.append(card)
if ( len(self.tagcards) >=2 ):
self.game.StartOM()
def usermovehandler(self, card):
count = 0
stack = self.game.closeststack(card)
if not stack or stack is self:
count = count + 1
else:
self.delete(card)
stack.add(card)
stack.shuffled()
self.game.DiscardCards()
class gameMaid:
def __init__(self, master):
self.master = master
self.canvas = Canvas(self.master,
background=BACKGROUND,
highlightthickness=0,
width=NROWS*XSPACING + 60,
height=3*YSPACING + 260 + MARGIN)
self.canvas.pack(fill=BOTH, expand=TRUE)
self.dealbutton = Button(self.canvas,
text="Deal",
highlightthickness=0,
background=BACKGROUND,
activebackground="blue",
command=self.dealOM)
Window(self.canvas, MARGIN, MARGIN + 60,
window=self.dealbutton, anchor=SW)
self.startbutton = Button(self.canvas,
text="Play",
highlightthickness=0,
background=BACKGROUND,
activebackground="blue",
command=self.selfStartOM)
Window(self.canvas, MARGIN, MARGIN + 90,
window=self.startbutton, anchor=SW)
self.quitbutton = Button(self.canvas,
text="Quit",
highlightthickness=0,
background=BACKGROUND,
activebackground="red",
command=self.Quit)
Window(self.canvas, MARGIN, MARGIN + 120,
window=self.quitbutton, anchor=SW)
self.labelnorth = Label(self.canvas,
text="North",
highlightthickness=1,
background=BACKGROUND)
Window(self.canvas, 200, MARGIN/2, anchor=N, window=self.labelnorth)
self.labelsouth = Label(self.canvas,
text="South",
highlightthickness=1,
background=BACKGROUND)
Window(self.canvas, 200, 600, anchor=S, window=self.labelsouth)
self.labeleast = Label(self.canvas,
text="East",
highlightthickness=1,
background=BACKGROUND)
Window(self.canvas, 680, MARGIN + 150, anchor=E, window=self.labeleast )
self.labewest = Label(self.canvas,
text="West",
highlightthickness=1,
background=BACKGROUND)
Window(self.canvas, MARGIN, MARGIN+150, anchor=W, window=self.labewest)
x = MARGIN
y = MARGIN
self.deck = Deck(x, y, self)
x = x + 320
y = y + 200
self.board = BoardStack(x, y, self)
self.rows = []
self.names = []
for i in range(NHANDS):
if (i == 0 ):
x = 250
y = MARGIN
self.names.append("North")
elif (i == 1 ):
x = 500
y = 200
self.names.append("East")
elif (i == 2 ):
x = 250
y = 360
self.names.append("South")
elif (i == 3 ):
x = MARGIN
y = 200
self.names.append("West")
self.rows.append(PlayStack(x, y, self))
self.openstacks = [self.board] + self.rows
def dealOM(self):
# remove Queen of Clubs
# and deal remaining cards
self.dealer(52)
for i in range(NHANDS):
if ( i == 2 ):
self.rows[i].OpenCards()
tkMessageBox.showinfo("Pick", "Pick a card from your left Or press Play button for computer self play")
def DiscardCards(self):
j = 2
matches = self.rows[j].checkMatches()
n1 = matches/2
if n1 >=2:
tkMessageBox.showwarning("Play", "Doubleclick on matched cards Found %d" % n1 )
else:
tkMessageBox.showinfo("Play", "No matches found, Game proceeds")
cplay = 0
k = 0
for i in range(NHANDS):
k = (i+j)%NHANDS
self.playOneTurn(k,cplay)
self.FindLoser()
def StartOM(self):
i = 2
self.rows[i].removeTagMatches()
self.rows[i].shuffled()
self.rows[i].removeMatches()
self.rows[i].shuffled()
j = 2
k = 0
cplay = 0
for i in range(NHANDS):
k = (i+j)%NHANDS
self.playOneTurn(k,cplay)
self.FindLoser()
def selfStartOM(self):
matches = 0
cplay = 1
turn = 0
for i in range(1,NHANDS+1):
self.playOneTurn(turn,cplay)
turn = (turn + 1) % NHANDS
self.FindLoser()
def playOneTurn(self, i, cplay):
matches = 0
if self.rows[i].isEmpty(): return 0
neighbor = self.findNeighbor(i)
if self.rows[neighbor].isEmpty(): return 0
if (i == 2 ):
if (cplay == 1):
pickedCard = self.rows[neighbor].popCard()
self.rows[i].add(pickedCard)
self.rows[i].OpenACard(pickedCard)
matches = self.rows[i].removeMatches()
self.rows[i].shuffled()
else:
pickedCard = self.rows[neighbor].popCard()
self.rows[i].add(pickedCard)
self.rows[i].ShowABack(pickedCard)
self.rows[i].removeMatches()
self.rows[i].shuffled()
def findNeighbor(self, i):
next = 0
for next in range(1,NHANDS+1):
neighbor = (i + next) % NHANDS
if not self.rows[neighbor].isEmpty():
return neighbor
def FindLoser(self):
ntotal = 0
j = 0
for i in range(NHANDS):
n1 = self.rows[i].numCard()
ntotal = ntotal + n1
if (n1 == 1 ):
j = i
if ( ntotal == 1 ):
cardx = self.rows[j].isQspade()
if (cardx):
self.rows[j].OpenACard(cardx)
tkMessageBox.showinfo("Game Over", "The Looser is %s " % self.names[j] )
def closeststack(self, card):
closest = None
cdist = 999999999
# Since we only compare distances,
# we don't bother to take the square root.
for stack in self.openstacks:
#print "card x y ", card.x, card.y
dist = (stack.x - card.x)**2 + (stack.y - card.y)**2
if dist < cdist:
closest = stack
cdist = dist
return closest
def dealer(self, nCards= 999 ):
self.reset( )
if ( len(self.deck.cards) == 0 ):
self.deck.fill()
self.deck.shuffle()
for i in range(nCards):
card = self.deck.deals()
if not card:
break
r = self.rows[i % NHANDS]
r.add(card)
card.showback()
def Quit(self):
sys.exit(0)
def reset(self):
for i in range(NHANDS):
cardx = self.rows[i].isQspade()
if (cardx):
cardy = self.rows[i].popCard()
self.rows[i].moveACard(cardy)
# Main function, run when invoked as a stand-alone Python program.
def main():
root = Tk()
root.title("Old Maid Game")
print "---------- Let the old maid game begin"
game = gameMaid(root)
root.protocol('WM_DELETE_WINDOW', root.quit)
root.mainloop()