| 
 | |||||||
| 
 | 
|  | 
|  | 
|  | Strumenti | 
|  10-12-2008, 19:15 | #1 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
				
				[Python] Ereditarietà e gioco Old Maid
			 
		Apro un nuovo topic dato che l'altro sul libro in generale ormai e poco controllato. Ecco in breve cosa mi interesserebbe sapere, il libro che sto studiando negli ultimi capitoli ha un sacco di errori e ho passato più tempo a scovarli e correggerli che a concentrarmi sullo studio vero e proprio. Per prima cosa posto il codice, cosi da avere le idee chiare: Codice: class Carta:
    ListaSemi = ["Fiori", "Quadri", "Cuori", "Picche"]
    ListaRanghi = ["impossibile", "Asso", '2', '3', '4', '5', '6', '7', '8', \
                   "9", "10", "Jack", "Regina", "Re"]
                   
    def __init__(self, Seme=0, Rango=0):
        self.Seme = Seme
        self.Rango = Rango
    def __str__(self):
        return (self.ListaRanghi[self.Rango] + " di " + self.ListaSemi[self.Seme])
    def __cmp__(self, Altro):
        #controlla il seme
        if self.Seme > Altro.Seme: return 1
        if self.Seme < Altro.Seme: return -1
        #controlla il rango
        if (self.Rango == 1) and (Altro.Rango != 1): return 1 
        if (self.Rango != 1) and (Altro.Rango == 1): return -1 
        if self.Rango > Altro.Rango: return 1
        if self.Rango < Altro.Rango: return -1
        #se anche il rango ? uguale allora le carte sono uguali
        return 0
    
class Mazzo:
    def __init__(self):
        self.Carte = []
        for Seme in range(4):
            for Rango in range(1, 14):
                self.Carte.append(Carta(Seme, Rango))
    def StampaMazzo(self):
        for Carta in self.Carte:
            print Carta
    def __str__(self):
        s = ""
        for i in range(len(self.Carte)):
            s = s + ""*i + str(self.Carte[i]) + '\n'
        return s
    def Mescola(self):
        import random
        NumCarte = len(self.Carte)
        for i in range(NumCarte):
            j = random.randrange(i, NumCarte)
            self.Carte[i], self.Carte[j] = self.Carte[j], self.Carte[i]
            
    def RimuoviCarta(self, Carta):
        if Carta in self.Carte:
            self.Carte.remove(Carta)
            return 1
        else:
            return 0
        
    def PrimaCarta(self):
        return self.Carte.pop()
    
    def EVuoto(self):
        return(len(self.Carte) == 0)
    def Distribuisci(self, ListaMani, NumCarte=999):
        NumMani = len(ListaMani)
        for i in range(NumCarte):
            if self.EVuoto(): break
            Carta = self.PrimaCarta()
            Mano = ListaMani[i % NumMani]
            Mano.AggiungiCarta(Carta)
class Mano(Mazzo):
    def __init__(self, Nome=""):
        self.Carte = []
        self.Nome = Nome
    
    def AggiungiCarta(self,Carta):
        self.Carte.append(Carta)
        
    def __str__(self):
        s = "La mano di " + self.Nome
        if self.EVuoto():
            s = s + " e' vuota\n"
        else:
            s = s + " contiene queste carte: \n"
        return s + Mazzo.__str__(self)
        
class GiocoDiCarte:
    def __init__(self):
        self.Mazzo = Mazzo()
        self.Mazzo.Mescola()
class ManoOldMaid(Mano):
    def RimuoviCoppie(self):
        Conteggio = 0
        CarteOriginali = self.Carte[:]
        for CartaOrig in CarteOriginali:
            CartaDaCercare = Carta(3-CartaOrig.Seme, CartaOrig.Rango)
            if CartaDaCercare in self.Carte:
                self.Carte.remove(CartaOrig)
                self.Carte.remove(CartaDaCercare)
                print "Mano di %s : %s elimina %s" % (self.Nome, CartaOrig, CartaDaCercare)
                Conteggio += 1
        return Conteggio
class GiocoOldMaid(GiocoDiCarte):
    
    def StampaMani(self):
        for Mano in self.Mani:
            print Mano
    def RimuoveTutteLeCoppie(self):
        Conteggio = 0
        for Mano in self.Mani:
            Conteggio = Conteggio + Mano.RimuoviCoppie()
        return Conteggio
    
    def TrovaVicino(self, Giocatore):
        NumMani = len(self.Mani)
        for Prossimo in range(1, NumMani):
            Vicino = (Giocatore + Prossimo) % NumMani
            if not self.Mani[Vicino].EVuoto():
            return Vicino
    def GiocaUnTurno(self, Giocatore):
        if self.Mani[Giocatore].EVuoto():
            return 0
        Vicino = self.TrovaVicino(Giocatore)
        CartaScelta = self.Mani[Vicino].PrimaCarta()
        self.Mani[Giocatore].AggiungiCarta(CartaScelta)
        print "Mano di ", self.Mani[Giocatore].Nome, ": scelta ", CartaScelta
        Conteggio = self.Mani[Giocatore].RimuoviCoppie()
        self.Mani[Giocatore].Mescola()
        return Conteggio
    
    def Partita(self, Nomi):
        self.Mazzo.RimuoviCarta(Carta(0, 12)) # Rimozione della regina di fiori
        self.Mani = [] # Creazione di una mano per ogni giocatore
        for Nome in Nomi:
            self.Mani.append(ManoOldMaid(Nome))
        self.Mazzo.Distribuisci(self.Mani) # Distribuzione delle carte
        print "----------- Le carte sono state distribuite -----------"
        self.StampaMani()
        NumCoppie = self.RimuoveTutteLeCoppie() # Toglie le coppie iniziali
        print "----------- Coppie scartate, inizia la partita -----------"
        self.StampaMani()
        Turno = 0 # Gioca finche' non sono state fatte 25 coppie
        NumMani = len(self.Mani)
        while NumCoppie < 25:
            Turno = (Turno + 1) % NumMani
            NumCoppie = NumCoppie + self.GiocaUnTurno(Turno)
        print "----------- La partita e' finita -----------"
        self.StampaMani()
Gioco = GiocoOldMaid()
Gioco.Partita(["Full", "Syst3m", "Io"])Adesso a noi: 1) ho provato a "runnare" ripetutamente il programma e alle volte viene eseguito senza problemi fino alla fine, altre dà un errore di indice (rilevato nella riga di codice in grassetto) e altre ancora si ferma al Nooooooooooooooooooooooooooooooo e finisce l'esecuzione. 2) Codice: Mano = ListaMani[i % NumMani] Mano.AggiungiCarta(Carta) Codice: self.Mani.append(ManoOldMaid(Nome)) P.S: credo che sia cosi controllando passo per passo, ma vorrei una conferma: l'ereditarietà funziona come una scatola dentro un'altra in pratica. Quindi ManoOldMaid oltre ad ereditare da Mano eredita anche da Mazzo visto che Mano eredita a sua volta da Mazzo? 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. Ultima modifica di ~FullSyst3m~ : 11-12-2008 alle 23:06. | 
|   |   | 
|  11-12-2008, 21:36 | #2 | |||||||||
| Senior Member Iscritto dal: Jan 2002 Città: Germania 
					Messaggi: 26110
				 | Quote: 
  Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 
				__________________ Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys | |||||||||
|   |   | 
|  11-12-2008, 23:14 | #3 | |||||||
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 Quote: 
 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. Ultima modifica di ~FullSyst3m~ : 13-12-2008 alle 15:10. | |||||||
|   |   | 
|  14-12-2008, 08:19 | #4 | ||||
| Senior Member Iscritto dal: Jan 2002 Città: Germania 
					Messaggi: 26110
				 | Quote: 
 Quote: 
 Per risponderti, Mano è una variabile, ma contiene appunto un'istanza della classe Mano: Mano = ListaMani[i % NumMani] ListaMani è una lista di istanze di mani, per cui con questa istruzione tu ne selezioni una. Visto che Mano contiene un'istanza di mani, allora può benissimo invocare il metodo AggiungiCarta. Quote: 
  Quote: 
 Quindi per ManoOldMaid, visto che non ha definito alcun metodo __init__, verrà chiamato il metodo __init__ della classe da cui eredita, e SOLO QUELLO. Se per caso ManoOldMaid ridefinisse il metodo __init__, allora NON verrebbe più chiamato nessun altro metodo __init__ di nessuna altra classe da cui essa deriva. Questo comporta due cose: o ManoOldMaid si occupa di effettuare tutte le inizializzazioni eseguite nelle classi da cui deriva, oppure a sua volta dentro il suo __init__ provvede a chiamare l'__init__ del classe da cui deriva. 
				__________________ Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys | ||||
|   |   | 
|  14-12-2008, 12:16 | #5 | ||
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | Quote: 
 Scusa se ti ho fatto perdere tempo, ma avevo già trovato risposta a tutto. Ho dimenticato di postare perchè sto capitolo mi ha fatto perdere un sacco di tempo, era scritto proprio con i piedi. Solo una cosa vorrei aggiungere: Quote: 
 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. | ||
|   |   | 
|  15-12-2008, 08:17 | #6 | 
| Senior Member Iscritto dal: Jan 2002 Città: Germania 
					Messaggi: 26110
				 | 
		Richiamare l'__init__ (in gergo tecnico nella OOP viene chiamato "costruttore") delle classi da cui si discende è, invece, estremamente utile e pratica molto comune. Quando avrai affinato le tue conoscenze della programmazione OOP lo capirai meglio.   
				__________________ Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys | 
|   |   | 
|  15-12-2008, 12:31 | #7 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
		
Al momento non ne vedo l'utilità sinceramente. Se si deve invocare il costruttore della classe genitore basta non definire un metodo di inizializzazione per la classe figlia cosi viene invocato in automatico quello della classe genitore. Come ManoOldMaid ad esempio
		 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. | 
|   |   | 
|  15-12-2008, 14:09 | #8 | 
| Senior Member Iscritto dal: Jan 2002 Città: Germania 
					Messaggi: 26110
				 | 
		L'utilità c'è se vuoi cambiare l'inizializzazione dell'oggetto, mantenendo però il setup che è previsto dalla classe genitrice. Cosa che, ripeto, è abbastanza frequente lavorando con la OOP. Vedrai che ti capiterà.   
				__________________ Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys | 
|   |   | 
|  15-12-2008, 14:19 | #9 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
		
In pratica potrebbe servire nel caso voglio scrivere un metodo di inizializzazione di una classe figlia, che però ha bisogno dell'__init__ della classe genitrice oltre a quello proprio? Ad esempio inserire nell'init della classe figlia il codice che serve e in più l'init della classe genitrice?
		 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. | 
|   |   | 
|  15-12-2008, 14:30 | #10 | 
| Senior Member Iscritto dal: Jan 2002 Città: Germania 
					Messaggi: 26110
				 | 
		Esatto. In genere il lavoro di inizializzazione della classe genitrice è utile e andrebbe fatto comunque. Oltre a questo, la classe figlia può voler effettuare ALTRE inizializzazioni.
		 
				__________________ Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys | 
|   |   | 
|  15-12-2008, 14:54 | #11 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
		
Ora inizio a vederci una certa utilità, anche se al momento personalmente non credo che mi serva
		 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. | 
|   |   | 
|  15-12-2008, 22:29 | #12 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
		Edit: spostato nel nuovo post http://www.hwupgrade.it/forum/showthread.php?t=1885943
		 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. Ultima modifica di ~FullSyst3m~ : 16-12-2008 alle 02:44. | 
|   |   | 
|  16-12-2008, 01:55 | #13 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
		Edit: spostato nel nuovo post http://www.hwupgrade.it/forum/showthread.php?t=1885943
		 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. Ultima modifica di ~FullSyst3m~ : 16-12-2008 alle 02:44. | 
|   |   | 
|  16-12-2008, 02:32 | #14 | 
| Senior Member Iscritto dal: Mar 2007 
					Messaggi: 4683
				 | 
		Edit: spostato nel nuovo post http://www.hwupgrade.it/forum/showthread.php?t=1885943
		 
				__________________ Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. Ultima modifica di ~FullSyst3m~ : 16-12-2008 alle 02:43. | 
|   |   | 
|   | 
| Strumenti | |
| 
 | 
 | 
Tutti gli orari sono GMT +1. Ora sono le: 12:47.









 
		 
		 
		 
		








 
  
 



 
                        
                        










