Vereinfachung möglich?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
illton
User
Beiträge: 3
Registriert: Montag 8. November 2010, 16:21

Ich habe hier dieses Programm gefunden....könnte man es auch in einer vereinfachten Form und nicht so umständlich programmieren?

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()
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja. Zum Beispiel koennte man die `if/elif` Kaskaden durch Dictionaries und lambdas ersetzen.

Erwartest du jetzt ernsthaft, dass dir jemand fuer einen Codedump der ueber 800 Zeilen lang ist, nicht lauffähig ist und auhc nur spaerlich kommentiert ist eine echte und ausfuehrliche Kritik schreibt? Wenn dich einzelne Teile stoeren und du nur die postest wirst du mehr Hilfe erhalten.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

illton hat geschrieben:könnte man es auch in einer vereinfachten Form und nicht so umständlich programmieren?
Ja.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

diese Funktion ist ein schönes Beispiel, wie man es nicht macht:

Code: Alles auswählen

    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()
- if einmal mit Klammern; einmal nicht
- Leerschläge zwischen Klammer und Text
- 1, 2 und 4 Leerschläge zum einrücken
- Funktionsaufrufe mit Leerschlag in Klammern
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

DaMutz hat geschrieben:diese Funktion ist ein schönes Beispiel, wie man es nicht macht:
Und sogar noch Hungarian Notation :roll:
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Das ist auch so ein Filetstückchen:

Code: Alles auswählen

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
Antworten