View Full Version : [CICLO 16] Storia 1
Storia 1: Bugfix e refactoring. Introduzione di un sistema per riprodurre i log.
P.S.: Prima di postare, aspettiamo la divisione in task fissi ;)
Task:
16.1.1: Bonfo: completato
Suddividere l'intrfaccia Droppable in piu' interfacce, secondo lo schema usato nel precedente refactoring di Droppable
16.1.2: Ufo13: 3 giorni
Cambiare BigGem per implementare Droppable e modificare il codice di Grid e GridController per essere agnostici rispetto a BigGem. Da fare in Pair.
16.1.3:
Razionalizzare GridController, State e Action suddividendo i loro compiti nelle giuste classi. La definizione di Action e' "il solo componente che puo' cambiare la configurazione e lo stato di un GridController". La definizione di State e' "Lo stato corrente di GridController che restituisce la prossima Action da eseguire".
16.1.4: DanieleC88: 4 giorni
Scrivere la classe LogWriter che scrive l'elenco delle Action eseguite divese per turno e l'ultimo stato del GridController.
16.1.5: cdimauro: 2 giorni
Scrivere la classe LogReader per leggere il file di Log e memorizzarlo in una struttura dati in memoria
16.1.6: 71104: 2 giorni
Scrivere la classe LogPlayer per eseguire le Action memorizzate nel log letto da LogReader
cdimauro
16-05-2006, 11:52
Prendo il 5. Tempo stimato: 2 giorni.
avendo gia affrontato con insuccesso il task 5, mi sento di dire che va specificato meglio.
Punti fondamentali sono:
-il playback è timer dipendente?(ma dalla precedente discussione direi di no :) )
-cosa e quando si deve loggare.
Io avevo scelto di loggare i commandHandler(in verità c'erano gia), e gli stati.
per i commandHandler non ho trovato problemi di sorta, mentre invece non è chiaro quando loggare gli stati e quando eseguirli.
Se la loro esecuzione deve essere indipendente dal timer, devono essere loggati in maniera dipendente dal timer.
Mi spiego meglio.
Nella mia implementazione ogni volta che veniva eseguita una update di qualunque stato, veniva loggata una riga.
Percui WaitStateBeforeNewGemsPair veniva eseguito e loggato un numero N di volte.
Pero nel playback non puo essere eseguito N volte, ma solo una.(l'esecuzione deve essere indipendente dal timer).
Questo si puo risolvere rendendo il log dello stato dipendente dal timer, cioè loggando solo quando la gemsPair viene inserita.
Se invece ora il log è timer dipendente il problema non sussiste(ma ce ne saranno altri :P )
Il log dev'essere indipendente dal timer.
Quello che non mi e' chiaro (perche' non conosco piu' benissimo il codice relativo agli stati) e' perche' devi loggare gli stati.
Dovrebbe essere possibile loggare solo le azioni. Se non definiamo le azioni come l'unico elemento che puo' cambiare lo stato di un GridController (inserire gemme, togliere gemme, far rompere gemme), la configurazione attuale di un GridController dovrebbe essere descritta totalmente dall'elenco di azioni, a meno dello stato finale.
Che dici? Ovvio che a questo punto significa che il refactoring di State/Action deve arrivare a questa definizione che ho appena dato.
Cesare, thebol, ho modificato i task e aggiunto un nuovo task.
Il log dev'essere indipendente dal timer.
Quello che non mi e' chiaro (perche' non conosco piu' benissimo il codice relativo agli stati) e' perche' devi loggare gli stati.
Dovrebbe essere possibile loggare solo le azioni. Se non definiamo le azioni come l'unico elemento che puo' cambiare lo stato di un GridController (inserire gemme, togliere gemme, far rompere gemme), la configurazione attuale di un GridController dovrebbe essere descritta totalmente dall'elenco di azioni, a meno dello stato finale.
Che dici? Ovvio che a questo punto significa che il refactoring di State/Action deve arrivare a questa definizione che ho appena dato.
Mi sembra che si vadi a loggare un po troppo in basso in questa maniera.
Per quanto riguarda la definizione di action e state, io la vedevo diversamente.
Fra l'altro mi sembra ci sia una relazione incrociata fra le 2 cose(lo state restituisce una action, la action restituisce uno state).
Ora vado a nuoto, dopo aggiungo qualcosa.
Mi spieghi meglio tu come vedi Action e State? Quello che hai scritto collima con quello che penso: Action restituisce il nuovo State e State restituisce l'Action da eseguire.
Uno State puo' non restituire un'Action se e' uno State di pura attesa. Bonfo, se ci sei batti un colpo, mi fa l'elenco di quali Action abbiamo in questo momento?
Fek...dimmi se ho capito bene.
Lo stato StoneFallState ora inserisce le stone nella griglia.
Dopo il refactoring ci deve essere lo FallStoneState che invoca la StonaAction, che è l'unica che si occupa di inserire le stone. giusto??
Altra cosa: secondo me l'interfaccie che sostituiranno droppable dovranno avere anche moveDown e canMoveDown....come ho già spiegato ogni entità sa come è fatta e quindi chiedendo lo stato di grid sa se può muoversi e come muoversi.
Inoltre i droppables secondo me dovrebbero implementare anche Drawable.
Infine anche AbstractDroppable, conseguentemente a queste modifiche, dovrà essere rimaneggiato.
Ho detto castronerie ?? :confused:
Io mi butterei sul task 1 o sul 2.
Nel caso dell'1 però mi tengo un bel po' di giorni...oltre agli impegni è un po' delicato, quindi non vorrei correre. Tipo 4 giorni ;)
Ecco il colpo:
- 2 CrushAction (Flash e Chest)
- CanMoveDownAction
- CreateNewBigGemsAction
- DrawGemsAction
- UpdateAnimationsAction
- UpdateFallsAction
- UpdateStoneAction
Ho fatto solo copia e incolla...io mi ero già piantato a rifattorizzare CanMoveDownAction :(
Ecco una cosa che aggiungerei nei task, o forse è già parte del task 3.
Molte Action usano dei metodi di Grid che dovrebbero essere privati delle Action. Quindi anche Grid va rifattorizzato. :O
Inoltre modificherei Grid in modo che non sia più un insieme di Celle, ma un insieme di Droppables....dovrebbe risolverci un sacco di problemi.
Lo avevo già spiegato in un altro post :sofico:
Fek...dimmi se ho capito bene.
Lo stato StoneFallState ora inserisce le stone nella griglia.
Dopo il refactoring ci deve essere lo FallStoneState che invoca la StonaAction, che è l'unica che si occupa di inserire le stone. giusto??
Il mio e' un suggerimento. Direi di si', dopo il refactoring dovrebbe esserci un InsertStoneAction o qualcosa di simile. Che cosa ne pensi?
Rispondimi aprendo un thread di discussione su questo refactoring :)
Riguardo Grid, per ora concentriamoci su un refactoring alla volta. Cerca di individuare quello piu' semplice. Per fare questo ti serve prima il Refactoring di Droppable, quello di BigGem o puoi gia' partire?
In questa ottica forse dovremmo introdurre anche una GravityAction....ovvero un Action che gestisce il cambio di gravità.
...in ogni caso sto aprendo il thread ;)
Non lo so di cosa ho biosgno prima....ma a quale refactoring fai riferimento: interfacce??
Io so solo che ho preso CanMoveDownAction e ho visto che il codePath è discretamente ingrabugliato tra le varie classi.
Già il fatto che ci sia grid.canMoveDown(gem) e bigGem.canMovceDown(grid) mi ha fatto capire che c'era qualcosa da mettere a posto.
Quindi io partirei mettendo questo metodo dentro l'interfaccia, o meglio in una delle interfaccie, di droppable.
Inoltre per evitare ogni volta di tenere memoria delle BigGem "visitate" per sapere se la cella considerata non è da "visitare", bisognerebbe fare quel refactoring di grid non più orinetato alle celle, ma ai droppables contenuti.
Mi prenoto per il pair del task 2 :) 3 giorni
Quindi io partirei mettendo questo metodo dentro l'interfaccia, o meglio in una delle interfaccie, di droppable.
Partiamo con questo, ma prima bisogna suddividere l'interfaccia Droppable. Te ne occupi tu?
Per il refactoring di Grid, ci pensiamo al prossimo Ciclo.
DanieleC88
16-05-2006, 15:51
Il task 4 non sembra molto cattivo, forse è alla mia portata... ci provo, se poi non capisco bene cosa fare contatto qualcuno su MSN, appena MSN mi torna a funzionare.
E speriamo sia la volta buona che riesco a tornare attivo, è da Gennaio che non riesco a fare un task. :(
Partiamo con questo, ma prima bisogna suddividere l'interfaccia Droppable. Te ne occupi tu?
Per il refactoring di Grid, ci pensiamo al prossimo Ciclo.
Ok...ci lavoro sopra.
Comunico tutti i passaggi sul forum....dalle interfacce dipendono molte cose ;)
vorrei il 16.1.6, 2 giorni a partire dalla fine di quelli propedeutici (2 giorni per stare larghi, non penso ci voglia molto in realtà); e nel frattempo per non stare senza far niente, ne prenoto uno della storia 3 che è stato fatto apposta per me :cool:
Ho iniziato a lavorare.
Scusate l suffisso Object, ma altrimenti non sapevo come chiamare queste interfacce.
Eccole:
- FallingObject
- AnimetedObject
- ScoreObject
- BrightlyObject
- PairObject
- Futura interfaccia contenete CanMoveDown e MoveDown. Non so chiamarla :rolleyes:
Una precisazione su FallingObject: BigGem non è un FallingObject !!!
Altra cosa...che senso ha di esistere stop() se esiste drop()?
PairObject è il solo metodo moveToCell...in realtà è usato solo nel caso il droppable sia in una pair...quini l'ho estratto: è sbagliato??
Le cose che non sapevo dove mettere...probabilmente sono proprio dell'interfacca droppable ( getType, getColor, isSameOf,getCell) :D
Se approvate, posto tutti i metodi di tutte le interfacce così avete la visone totale.
Se approvate pure quello passo alla riorganizzazione del codice ;)
Ho iniziato a lavorare.
Scusate l suffisso Object, ma altrimenti non sapevo come chiamare queste interfacce.
Eccole:
- FallingObject
- AnimetedObject
- ScoreObject
- BrightlyObject
- PairObject
- Futura interfaccia contenete CanMoveDown e MoveDown. Non so chiamarla :rolleyes:
Una precisazione su FallingObject: BigGem non è un FallingObject !!!
Altra cosa...che senso ha di esistere stop() se esiste drop()?
PairObject è il solo metodo moveToCell...in realtà è usato solo nel caso il droppable sia in una pair...quini l'ho estratto: è sbagliato??
Le cose che non sapevo dove mettere...probabilmente sono proprio dell'interfacca droppable ( getType, getColor, isSameOf,getCell) :D
Se approvate, posto tutti i metodi di tutte le interfacce così avete la visone totale.
Se approvate pure quello passo alla riorganizzazione del codice ;)
potresti chiarirmi sulla FallingObject!?!
potresti chiarirmi sulla FallingObject!?!
public interface FallingObject
{
boolean isFalling();
boolean isNotFalling();
void setCollisionSound(Sound sound);
Sound getCollisionSound();
boolean isCollisionSoundSet();
void stop(); // SECONDO ME DA ELIMINARE
void drop();
void applyGravity(float actualGravity);
}
Domande?? :D :D
Addirittura i metodi relativi al suono potrebbero essere ulteriormente estratti in n'altra interfaccia...
cdimauro
17-05-2006, 08:52
Il task 4 non sembra molto cattivo, forse è alla mia portata... ci provo, se poi non capisco bene cosa fare contatto qualcuno su MSN, appena MSN mi torna a funzionare.
E speriamo sia la volta buona che riesco a tornare attivo, è da Gennaio che non riesco a fare un task. :(
Daniele, dobbiamo metterci d'accordo sul formato del file di log da utilizzare, visto che tu devi produrlo e io leggerlo. ;)
vorrei il 16.1.6, 2 giorni a partire dalla fine di quelli propedeutici (2 giorni per stare larghi, non penso ci voglia molto in realtà); e nel frattempo per non stare senza far niente, ne prenoto uno della storia 3 che è stato fatto apposta per me :cool:
Non tenerti largo, dicci quanto pensi di impiegarci nella maniera piu' precisa che ti e' possibile.
Ho iniziato a lavorare.
Scusate l suffisso Object, ma altrimenti non sapevo come chiamare queste interfacce.
Eccole:
- FallingObject
- AnimetedObject
- ScoreObject
- BrightlyObject
- PairObject
- Futura interfaccia contenete CanMoveDown e MoveDown. Non so chiamarla :rolleyes:
Una precisazione su FallingObject: BigGem non è un FallingObject !!!
Altra cosa...che senso ha di esistere stop() se esiste drop()?
PairObject è il solo metodo moveToCell...in realtà è usato solo nel caso il droppable sia in una pair...quini l'ho estratto: è sbagliato??
Le cose che non sapevo dove mettere...probabilmente sono proprio dell'interfacca droppable ( getType, getColor, isSameOf,getCell) :D
Se approvate, posto tutti i metodi di tutte le interfacce così avete la visone totale.
Se approvate pure quello passo alla riorganizzazione del codice ;)
I metodi relativi al suono mettili in un'altra interfaccia. Dal nome BrightlyObject non mi suggerisce molto, che cos'e'? PairObject anche e' un po' confusa. Una cosa importante che devi provare a fare e' eliminare metodi: togli tutti i metodi che ti e' possibile togliere incorpandoli oppure spostando il codice a colpi di MoveMethod.
Esempio, se hai qualcosa del tipo:
object.methodA();
object.methodB();
Puoi eliminare methodA() e methodB() ed avere un solo methodC() nell'interfaccia che li chiama entrambi.
Ok...capito.
Allora lo cosa è più complicata del previsto....che bello ;)
BrightlyObject: oggetti che possono essere resi Brighter
PairObject: più che il nome chiedo conferma se ha senso separalo...e di conseguenza mi viene da chiedermi cosa sono le RotateClockWise et similia.
Ora non ho sotto il codice...ma mi ricordo che erano a metà tra handler e Action su pair ;)
Anche quelle vanno definite meglio ;)
In ogni caso ieri c'è stato il primo morto: stop() non esiste più :sofico:
Stasera vediamo di fare fuori qualcun'altro :boxe: :D
EDIT: ho appena preso una decisione...i nomi delle interfaccie sranno orribili ma chiari!! Ci penserà poi il team a trovare il nome giusto...altrimenti mi cconcentro solo sui nomi e non sulle responsabilità ;)
cdimauro
17-05-2006, 14:11
Daniele, dobbiamo metterci d'accordo sul formato del file di log da utilizzare, visto che tu devi produrlo e io leggerlo. ;)
Ditto!
Ditto!
Visto che non sono ancora chiare le action, se volete partire da subito vi conviene usare il il Obj.getCLass().getName.
Magari potete cmq mettere su un sistema di collegamento stringa <->oggetto action, basato per ora sul nome classe, e in futuro su un nome logico staccato dalla classe.
Ok...capito.
Allora lo cosa è più complicata del previsto....che bello ;)
BrightlyObject: oggetti che possono essere resi Brighter
Metti quel metodo in Sprite.
In ogni caso ieri c'è stato il primo morto: stop() non esiste più :sofico:
Bemnissimo :D
EDIT: ho appena preso una decisione...i nomi delle interfaccie sranno orribili ma chiari!! Ci penserà poi il team a trovare il nome giusto...altrimenti mi cconcentro solo sui nomi e non sulle responsabilità ;)
Giusto cosi', una volta che le responsabilita' sono chiare, vedrai che anche il nome ti verra' chiaro e poi e' un colpo di click con Eclipse.
cdimauro
17-05-2006, 16:50
Visto che non sono ancora chiare le action, se volete partire da subito vi conviene usare il il Obj.getCLass().getName.
Magari potete cmq mettere su un sistema di collegamento stringa <->oggetto action, basato per ora sul nome classe, e in futuro su un nome logico staccato dalla classe.
Penso che la reflection in questo caso aiuterebbe non poco (sia per il writer sia per il reader), però così ci leghiamo alle classi. Che non è poi un male: mi sembra una soluzione abbastanza pratica.
Che ne dite?
Penso che la reflection in questo caso aiuterebbe non poco (sia per il writer sia per il reader), però così ci leghiamo alle classi. Che non è poi un male: mi sembra una soluzione abbastanza pratica.
Che ne dite?
avendo gia mezzo affrontato il task, non lo consiglio.
Secondo me è meglio creare prima gli oggetti, legarli a un nome(2 hashMap per avere i collegamento in entrambe le direzioni), e poi chiamare il metodo dell'action(un metodo in comune di un ipotetica interfaccia logEvent)
Questo perche, è abbastanza facile creare un metodo unico per tutti le action, ma è piu difficile fare un costruttore unico per tutte le action che accetta gli stessi parametri(a meno di fare un costruttore con molti parametri, e poi la action prende quelli che gli serve).
ps.avevo anche provato la via del metodo factory statico createForLog(), ma non è possibile definirlo nell'interfaccia(e mi sembra neanche abstract).
Io introdurrei AnimatedSprite che eredita da Sprite e non un'interfaccia così l'animazione è trasparente all'oggetto ma è relativa solo alla sprite dell'oggetto :)
Inoltre la gestione delle animazioni andrebbe resa un po' più trasparente...
Abbiamo sprite la cui animazione va avanti solo all'avvenimento di un certo evento (vedi Stone) sprite che si animano in base al timestamp.
Inoltre al momento la gestione delle animazioni ho visto che è abbastanza decentralizzata (soprattutto per quanto riguarda le stone) e secondo me deve rientrare all'interno della gestione delle sprite e non dei droppables :)
Fra? :P
Io introdurrei AnimatedSprite che eredita da Sprite e non un'interfaccia così l'animazione è trasparente all'oggetto ma è relativa solo alla sprite dell'oggetto :)
Inoltre la gestione delle animazioni andrebbe resa un po' più trasparente...
Abbiamo sprite la cui animazione va avanti solo all'avvenimento di un certo evento (vedi Stone) sprite che si animano in base al timestamp.
Inoltre al momento la gestione delle animazioni ho visto che è abbastanza decentralizzata (soprattutto per quanto riguarda le stone) e secondo me deve rientrare all'interno della gestione delle sprite e non dei droppables :)
Fra? :P
Per l'ultimo task della storia 3 avevo intenzione di fare una specie di Action ma per gli sprite in modo da sposatre fuori tutto il codice che gestisce animazioni e effetti speciali da quella classe che sta diventando un porcilaio. Si potrebbe tranquillamente fare una trasformazione per gestire le animazioni.
Volevo aspettare l'inizio delle storia tre per incominciare a lavorarci ma se serve posso cominciare subito.
ciao ;)
Penso che la reflection in questo caso aiuterebbe non poco (sia per il writer sia per il reader), però così ci leghiamo alle classi. Che non è poi un male: mi sembra una soluzione abbastanza pratica.
Che ne dite?
Cesare, il nome della classe ritornato da Java non e' garantito essere il medesimo neppure fra esecuzioni diverse, tanto meno fra implementazioni diverse della JVM.
Decisamente non e' una soluzione ideale. Va benissimo usare una convenzione che decidiamo noi.
Non tenerti largo, dicci quanto pensi di impiegarci nella maniera piu' precisa che ti e' possibile. mi sono tenuto largo perché ancora non ho analizzato la situazione per sapere come devo fare il task, quindi non so quali sorprese mi riserverà; se non sono 2 giorni è 1, ma io nella prenotazione lascerei scritto comunque 2. se poi quando lo faccio ci impiego un giorno solo mi autospezzo un paio di ditini e d'ora in poi dico sempre 1 :D
Metti quel metodo in Sprite.
Non mi piace molto.
A parte che non è un metodo solo; ma più che altro BigGem, che non ha "una" sprite, mi sa che già dal prossimo ciclo potrebbe diventare Britgher. Quindi non conviene legare tali metodi a Sprite.
Stessa cose è per AnimetedSprite, non lo abbiamo ancora fatto, ma anche le BigGem saranno animate ;)
E' il motivo per cui volevo anche che BigGem e i Droppables non fornissero accesso a Sprite, ma che implementassero ognuna il proprio Draw.
In ogni caso vedo che Vic sta già affrontando e cercando una soluzione per "tutti" i tipi di effetto grafico ;)
Non mi piace molto.
A parte che non è un metodo solo; ma più che altro BigGem, che non ha "una" sprite, mi sa che già dal prossimo ciclo potrebbe diventare Britgher. Quindi non conviene legare tali metodi a Sprite.
Ma per brighter si intende quel effetto che usavamo prima per evidenziare le gemme all'interno di una bigggem? Se si non doveva essere eliminato dal codice? Per cosa lo usiamo ancora?
ciao ;)
Ecco...seguendo il discorso di prima, io a ciò che rimane di droppable aggiungerei:
- moveDown
- canMoveDown
Poi eliminerei (come detto prima)
- getSprite
E poi sotituirei
- getCell -> getPosition
Con l'obbiettivo di rendere trasparente la differenza tra BigGem e Gem "singole".
Questa modifica però cambia milioni di cose....e forse sarà fattibile solo dopo il refactoring di grid orientata ai droppable invece che a celle.
L'illuminazione ci serve nel prossimo ciclo.
Non mi piace molto.
A parte che non è un metodo solo; ma più che altro BigGem, che non ha "una" sprite, mi sa che già dal prossimo ciclo potrebbe diventare Britgher. Quindi non conviene legare tali metodi a Sprite.
Stessa cose è per AnimetedSprite, non lo abbiamo ancora fatto, ma anche le BigGem saranno animate ;)
E' il motivo per cui volevo anche che BigGem e i Droppables non fornissero accesso a Sprite, ma che implementassero ognuna il proprio Draw.
In ogni caso vedo che Vic sta già affrontando e cercando una soluzione per "tutti" i tipi di effetto grafico ;)
Non sono d'accordo sul nascondere la sprite... il concetto di gemma ed i concetti di sprite ed animazione son cose totalmente differenti che non vanno confuse all'interno della stessa classe :)
Poi eliminerei (come detto prima)
- getSprite
Come appena detto non sono d'accordo ed inoltre il metodo getSprite() è appena stato introdotto proprio per quel motivo :)
Non sono d'accordo sul nascondere la sprite... il concetto di gemma ed i concetti di sprite ed animazione son cose totalmente differenti che non vanno confuse all'interno della stessa classe :)
Mi sipeghi meglio... :bimbo:
Non ho capito bene cosa intendi...la gemma non è costituita anche da una sprite??
Bene...io considero la sprite come una parte che costituisce la gemma. Quindi la gemma, sapendo come è fatta, gestisce se stessa perchè è l'unica che sa come è fatta.
Io faccio questo ragionamento pensando a BigGem...lei sa come è fatta e sa dunque come si deve disegnare.
Anch'io sono molto convinto che siano cose diverse, ma penso anche che sia la gemma a gestire la sua sprite...anche se non è per nulla una sprite.
Insomma la gemma utilizza i servizi forniti da Sprite.
...mi sono fatto capire??
Sto valutando questo metodo:
void addFrame(int x, int y, int delay);
Scusate, ma X e Y non sono una proprietà della animazione piuttosto che del singolo Frame??
Considetando anche i pronblemi posti, forse non conviene la creazione di una bella classe Animation??
Naturalmente vale la visone che ho esposto 2 secondi fa: sarà poi la gemma o similia che userà i servizi di questa classe per gestire l'animazione.
Ecco un altro problema di definizione di resposabilità.
E' il problema postoda cisc, se non mi ricordo male, ovvero che BigGem in realtà non ha la fase di caduta dall'alto come le gemme, ma solo la fase di discesa in caso di vuoto sottostante.
Questo implica comportamenti diversi??
Il problema sorge per come è gestito il movimento verso il basso nei due casi...purtroppo è tutto tranne che omogeneo :(
EDIT: Domani mattina ci sono...se ci fosse qualcuno con cui confrontare le idee mi farebbe molto piacere... Fek??
Ecco un altro problema di definizione di resposabilità.
E' il problema postoda cisc, se non mi ricordo male, ovvero che BigGem in realtà non ha la fase di caduta dall'alto come le gemme, ma solo la fase di discesa in caso di vuoto sottostante.
Questo implica comportamenti diversi??
Il problema sorge per come è gestito il movimento verso il basso nei due casi...purtroppo è tutto tranne che omogeneo :(
Tutti i droppable dovrebbero controllare ad ogni update se sotto di loro c'è del vuoto. Se lo trovano devono spostarsi fino a collidere con qualcosa che può essere un'altro droppable oppure il bordo inferiore. L'unica differenza tra le gemme e le bigGem è che in genere le gemspair vengono create in cima alla griglia e quindi trovano per alcuni cicli dopo la loro creazione del vuoto sotto di loro mentre le bigGem sono create in una posizione esattamente sopra ad un ostacolo quindi non possono muoversi finché qualcosa non rimuove quel ostacolo.
ciao ;)
Mi sipeghi meglio... :bimbo:
Non ho capito bene cosa intendi...la gemma non è costituita anche da una sprite??
Bene...io considero la sprite come una parte che costituisce la gemma. Quindi la gemma, sapendo come è fatta, gestisce se stessa perchè è l'unica che sa come è fatta.
Io faccio questo ragionamento pensando a BigGem...lei sa come è fatta e sa dunque come si deve disegnare.
Anch'io sono molto convinto che siano cose diverse, ma penso anche che sia la gemma a gestire la sua sprite...anche se non è per nulla una sprite.
Insomma la gemma utilizza i servizi forniti da Sprite.
...mi sono fatto capire??
Forse non ho capito io quello che vuoi dire...
Io sto solo dicendo che l'interfaccia (quindi il contratto) della gemma deve riguardare quello che fa la gemma. Se mi serve un servizio della Sprite allora faccio gem.getSprite() ed uso il servizio da quella.
Draw secondo me è una funzione più di sprite che di droppable ma nel caso della BigGem non vale bene il discorso in quanto è disegnata a tile e bisogna gestirla in maniera differente...
L'idea della classe animation secondo me rientra nel caso della AnimatedSprite. In ogni caso una Animation descriverebbe le posizioni (frame) del rectangle all'interno di una sprite. Tanto vale creare una AnimatedSprite (rende tutto più trasparente) secondo me :)
Forse non ho capito io quello che vuoi dire...
Io sto solo dicendo che l'interfaccia (quindi il contratto) della gemma deve riguardare quello che fa la gemma. Se mi serve un servizio della Sprite allora faccio gem.getSprite() ed uso il servizio da quella.
Draw secondo me è una funzione più di sprite che di droppable ma nel caso della BigGem non vale bene il discorso in quanto è disegnata a tile e bisogna gestirla in maniera differente...
Diciamo che Droppable espone i servizi di Sprite, ma modificati in base alla conoscenza che ha di se.
Quindi i servizi di Sprite non li gestisco io chiedendo a Gem di fornirli, ma chiedo a gem di effettuare operazioni sulla sua Sprite e ci penserà Gem a gestirli.
Praticamente la responsabilità della gestione di Sprite passa da chi usa Gem alla Gem stessa, perchè chi la usa non sa come è fatta dentro, mentre la Gem sa come è fatta dentro.
Naturalmente se un ble giorno decidiamo che chi usa Gem sa anche come è fatta...bhè..cambia tutto :D
Fare in modo che dal'esterno si sappia come è fatta una gemme è, in parole povere, rendere pubblico l'insieme delle gemme cosituenti una BigGem.
Però io preferirei mantenere l'incapsulamento. ;)
EDIT: il fatto è che droppable, quindi anche una BigGem, ha bisogno di fare qualcosa in più rispetto aquello che fa sprite...quindi, anche se dall'esterno il contratto è lo stesso, droppable ne modifica l'implementazione per soddisfrae i suoi bisogni
cdimauro
18-05-2006, 08:35
avendo gia mezzo affrontato il task, non lo consiglio.
Secondo me è meglio creare prima gli oggetti, legarli a un nome(2 hashMap per avere i collegamento in entrambe le direzioni), e poi chiamare il metodo dell'action(un metodo in comune di un ipotetica interfaccia logEvent)
Questo perche, è abbastanza facile creare un metodo unico per tutti le action, ma è piu difficile fare un costruttore unico per tutte le action che accetta gli stessi parametri(a meno di fare un costruttore con molti parametri, e poi la action prende quelli che gli serve).
ps.avevo anche provato la via del metodo factory statico createForLog(), ma non è possibile definirlo nell'interfaccia(e mi sembra neanche abstract).
Grazie del suggerimento: vado di hashmap, definendo dei nomi e rendendo le azioni "Executable" (spero che vada bene come nome per l'interfaccia. :D).
cdimauro
18-05-2006, 08:43
Cesare, il nome della classe ritornato da Java non e' garantito essere il medesimo neppure fra esecuzioni diverse, tanto meno fra implementazioni diverse della JVM.
E' una sorpresa per me. :) In Delphi i nomi delle classi sono quelli e non cambiano. Anzi, questo fatto viene utilizzato per implementare il sistema RTTI. ;)
Decisamente non e' una soluzione ideale. Va benissimo usare una convenzione che decidiamo noi.
OK. Per adesso metto dei nomi che rispecchiano le azioni, poi si può decidere di cambiarle in qualsiasi momento.
L'istanza di LogReader dove la infilo? In Environment? :fiufiu:
Ecco la test list:
- accertarsi che la lista sia vuota all'inizio;
- accertarsi che l'azione sia letta sia fra quelle contemplate;
- accertarsi che dopo aver introdotto un elemento, la lista non sia vuota;
- accertarsi che dopo aver inserito 2 elementi, il secondo sia consecutivo al primo;
- accertarsi che l'ultimo elemento letto dal file sia uno stato (quello di GridController).
Poiché le azioni vengono memorizzate in sequenza, penso che sia inutile pensare di memorizzare anche un timestamp o un id relativo al turno.
Se la test list va bene, procedo.
E' una sorpresa per me. :) In Delphi i nomi delle classi sono quelli e non cambiano. Anzi, questo fatto viene utilizzato per implementare il sistema RTTI. ;)
:D Oh, è una sopresa anche per me. Sarebbe una sorpresa anche per i redattori delle specifiche del linguaggio Java. Via, sarebbe una sorpresa un po' per tutti. :D
Secondo le specifiche del linguaggio (3a ed, 6.7, 13.1, 15.9.1) i nomi delle classi non possono cambiare.
cdimauro
18-05-2006, 09:58
Mi sembrava strano. :p
Grazie per l'informazione. :)
Alla fine uqetsa mattina non c'ero :( :ave:
Comunque il mio task è fortemente di design, ovvero le interfacce definiscono come la classi dovreanno comportarsi.
Quindi non me la sento di decidere tutto IO, anche perchè vedo che la mia visione non è sempre condivisa...per fortuna ;)
Questo task non si potrebbe farlo in Pair o addirittura in Treair :rotfl:
Tutti i droppable dovrebbero controllare ad ogni update se sotto di loro c'è del vuoto. Se lo trovano devono spostarsi fino a collidere con qualcosa che può essere un'altro droppable oppure il bordo inferiore. L'unica differenza tra le gemme e le bigGem è che in genere le gemspair vengono create in cima alla griglia e quindi trovano per alcuni cicli dopo la loro creazione del vuoto sotto di loro mentre le bigGem sono create in una posizione esattamente sopra ad un ostacolo quindi non possono muoversi finché qualcosa non rimuove quel ostacolo.
ciao ;)
Ma allora come mai BigGem non implementa metodi come:
- applayGravity()
- isFalling()
- isNotFalling()
- drop()
?? :confused:
Questi metodi sono chiaramente presenti in Droppable per gestire la caduta.
Infatti stavo pensando di fare metodi un po' più generali, che anche BigGem oltre oltre ai Droppable, possano implementare.
void moveDown(Grid grid);
sarebbe la somma dell'applayGravity() di dropable e il metodo moveDown di BigGem, che però non ha più come valore di ritorno un boolean...per quello ci sarà
boolean canMoveDown(Grid grid);
Inoltre manterrei i due isFalling e notFalling e il drop().
Vedendo però i droppable come li vede Vic anche questo metodo potrebbe sparire...nessuno deve fermare niente....si fermano da sole quando non possono più scendere (gestito da moveDown).
Però drop() è usatissimo nei test :(
Ma allora come mai BigGem non implementa metodi come:
- applayGravity()
- isFalling()
- isNotFalling()
- drop()
?? :confused:
Non ne ho idea. Probabilmente i due pezzi di codice hanno avuto due autori diversi che sono giunti a due soluzioni diverse per lo stesso problema. Un motivo in più per portare BigGem sotto Droppable e unificare la gestione.
ciao ;)
Ecco una differenza fortissima:
gli attuali droppable si possono muovere a destra e sinistra....BigGem manco per sogno.
Il tutto è gestito dal metodo moveToCell()...per quello io l'ho separato in un'altra interfaccia.
...sembra che abbia senso??
Lo so che ormai lo detto più di una volta...ma ormai sto scrivendo a ruota libera tutto quello che mi viene in mente :D :D
Ecco una differenza fortissima:
gli attuali droppable si possono muovere a destra e sinistra....BigGem manco per sogno.
Il tutto è gestito dal metodo moveToCell()...per quello io l'ho separato in un'altra interfaccia.
Questo perché in genere i Droppable sono creati all'interno di una DroppablesPair che è influenzata dagli handler. In teoria una volta implementati tutti i metotodi di Droppable in BigGem si potrebbero creare delle "BigGemsPair" e gestirle con i tasti cursore.
ciao ;)
Ecco una differenza fortissima:
gli attuali droppable si possono muovere a destra e sinistra....BigGem manco per sogno.
Il tutto è gestito dal metodo moveToCell()...per quello io l'ho separato in un'altra interfaccia.
...sembra che abbia senso??
Lo so che ormai lo detto più di una volta...ma ormai sto scrivendo a ruota libera tutto quello che mi viene in mente :D :D
in teoria solo la gemsPair si puo muovere a dx e sx.
Pero essendo composta da droppable..
in teoria solo la gemsPair si puo muovere a dx e sx.
Pero essendo composta da droppable..
Perfetto..ancora più convinto.
GLi oggeti che vogliono finire in una Pair devono potersi muovere ad una cella specifica: devono implementare l'interfaccai MoveableObject ;)
Siccome penso di aver fatto almeno una ventina di Post solo io parlando di aria fritta, ora faccoio un bel commit di un nuovo package
it.diamonds.droppable.interfaces
con tutte le interfaccie che mi sono venute fuori.
Ecco le cose più notevoli
- tolto getSprite: dal mio punto di vista getSprite deve sparire e deve invece essere implementata esplicitamente Drawable
- tolto getCell: la posizione viene gestita dalla Gemma stessa...è lei che sa come è fatta e dove può o non può andare.
- aggiunti i metodi moveDown e canMoveDown ed eliminati il metodo applyGravity: come detto...è la gemma, intesa anche come BigGem, che sa come è fatta e quindi sa anche se può cadere o no chiedendo a Grid il suo stato
Infine ci sono un paio di metodi che ho lasciato ma farei saprire volentieri:
- drop(): se le gemme sanno cadere non c'è bisogno che nessuno gli dica stop
- addFrame(): nel codice di prduzione viene usato solo all'interno della classe...forse è giusto che sia privato.
...entrambi però sono usati in una MAREA di test :(
EDIT: comunicazione di servizio: ho ragionato cercando di pensare il più possibile indipendentemente dal codice presente ora...ovvero ho cercato di pensare il più possibile come dovrebbe divenentare il codice, cioè al codice cui dobbiamo tendere
il moveToCell è usato nella gemsPair per muovere le gemme in risposta ad un input dell'utente, giusto? quindi credo che sia necessario metterci il getCell in MovableObject, a meno che non si mettono un moveLeft, moveRight......oppure usare direction...
Perfetto..ancora più convinto.
GLi oggeti che vogliono finire in una Pair devono potersi muovere ad una cella specifica: devono implementare l'interfaccai MoveableObject ;)
sì molto meglio :)
per quanto riguarda sprite secondo me per ora è meglio lasciare le cose come sono. L'interfaccia della Droppable descrive un determinato comportamento separato dal concetto di sprite..
Infine ci sono un paio di metodi che ho lasciato ma farei saprire volentieri:
- drop(): se le gemme sanno cadere non c'è bisogno che nessuno gli dica stop
- addFrame(): nel codice di prduzione viene usato solo all'interno della classe...forse è giusto che sia privato.
Il fatto che quei metodi siano usati in molti test significa che devi pensare alla rifattorizzazione di questi test. Di solito con pochi colpi di click dovrebbe risolverlo.
il moveToCell è usato nella gemsPair per muovere le gemme in risposta ad un input dell'utente, giusto? quindi credo che sia necessario metterci il getCell in MovableObject, a meno che non si mettono un moveLeft, moveRight......oppure usare direction...
Aspetta...per come è definita la MoveToCell non è necessario il getCell().
per quanto riguarda sprite secondo me per ora è meglio lasciare le cose come sono. L'interfaccia della Droppable descrive un determinato comportamento separato dal concetto di sprite..
ESATTO!!!!
Quinid droppable non deve dire assolutamente niente che centri con le Sprite.
Se poi quando la implementi gli vuoi dare pure una sprite...bhè...non è richiesto dall'interfaccia.
Per farmi cambiare questa idea dovrete sudare molto :D :D
Il fatto che quei metodi siano usati in molti test significa che devi pensare alla rifattorizzazione di questi test. Di solito con pochi colpi di click dovrebbe risolverlo.
Mentre su addFrame() sono abbastanza convinto che non debba esserci nell'interfaccia, non sono altrettando convinto di drop().
Vorrei prima avere la conferma da qualcuno, perchè la presenza o meno di quel metodo comporta una logica diversa delle classi
ESATTO!!!!
Quinid droppable non deve dire assolutamente niente che centri con le Sprite.
Se poi quando la implementi gli vuoi dare pure una sprite...bhè...non è richiesto dall'interfaccia.
Per farmi cambiare questa idea dovrete sudare molto :D :D
Hmm per favore puoi spiegarti meglio? Secondo me è giusto che un Droppable abbia una Sprite. Tutti i droppable devono averne una fino a questo momento :)
cdimauro
19-05-2006, 11:06
Attualmente la classe LogReader è ben diversa da quella che dovrebbe diventare a seguito del task 5 a cui sto lavorando. Ho visto che ci sono molti test in TestLog che sono legati a doppio filo col fatto che LogReader fornisce il metodo Read per leggere una riga alla volta dal file.
Con le modifiche che dovrei apportare, parecchi di quei test verrebbero fatti fuori (oltre al fatto che TestLog si sdoppierà in TestLogReader e TestLogWriter): posso procedere?
Hmm per favore puoi spiegarti meglio? Secondo me è giusto che un Droppable abbia una Sprite. Tutti i droppable devono averne una fino a questo momento :)
Cercherò di piegarmi nel meglio dei modi. :rolleyes:
EDIT: piegarmi....:rotfl: :rotfl:
Per me BigGem è un Droppable.
BigGem non ha una Sprite -> Droppable non deve avere all'interno della sua interfaccia getSprite()
Questa è la base da cui parto.
O la gestione del disegno la facciamo internamente agli oggetti (come fa BigGem) oppure la facciamo esternamente (come fa AbstractDroppable).
Il punto è:
facciamo che AbstractDroppable implementi anche lei come BigGem drawable OPPURE facciamo che BigGem fornisca l'insieme delle gemme di cui è composta fornendo la possibilità di accedere alle Sprite.
A me piace molto più la prima. Mi ripeto per la 100000millesima volta, è giusto che solo gli oggetti in Grid sappiano come sono fatti e sia responsabilità loro gestirsi.
Solo così potremmo usare BigGem come se fosse una gemma sola, ma solo più grande ;)
Cercherò di piegarmi nel meglio dei modi. :rolleyes:
EDIT: piegarmi....:rotfl: :rotfl:
Per me BigGem è un Droppable.
BigGem non ha una Sprite -> Droppable non deve avere all'interno della sua interfaccia getSprite()
Questa è la base da cui parto.
O la gestione del disegno la facciamo internamente agli oggetti (come fa BigGem) oppure la facciamo esternamente (come fa AbstractDroppable).
Il punto è:
facciamo che AbstractDroppable implementi anche lei come BigGem droppable OPPURE facciamo che BigGem fornisca l'insieme delle gemme di cui è composta fornendo la possibilità di accedere alle Sprite.
A me piace molto più la prima. Mi ripeto per la 100000millesima volta, è giusto che solo gli oggetti in Grid sappiano come sono fatti e sia responsabilità loro gestirsi.
Solo così potremmousare BigGem come se fosse una gemma sola, ma solo più grande ;)
approvo.
bigGem è una droppable(si sposta verso il basso con le sue politche), ed è drawable.
che poi sia fatta di sprite, o di noccioline, puo essere trasparente.
In questa maniera se una giorno cambiamo la visualizzazione delle bigGem (ad esempio con un texture stretchata a dovere), il tutto sarebbe trasparente a chi la usa.
Mentre su addFrame() sono abbastanza convinto che non debba esserci nell'interfaccia, non sono altrettando convinto di drop().
Vorrei prima avere la conferma da qualcuno, perchè la presenza o meno di quel metodo comporta una logica diversa delle classi
Anche su addFrame() no sono più così convinto.
Prima di eliminarlo io aspetterei la creazione della classe AnimetedSprite.
Forse è ancora prematuro eliminarlo.
Stessa cosa per Drop()...vediamo cosa porta l'implementazione dei metodi MoveDown e canMoveDown.
Già ho corso tanto cercando di guardare avanti, ma ho paura di star facendo il passo più grande della gamba....forse il codice non è ancora pronte per questi ulteriori tagli ;)
jappilas
19-05-2006, 12:14
Anche su addFrame() no sono più così convinto.
Prima di eliminarlo io aspetterei la creazione della classe AnimetedSprite.
....
AnimatedSprite... :O
;)
AnimatedSprite ;)
Ma che caspita....non so più scrivere.... :p :p
jappilas
19-05-2006, 12:17
Ma che caspita....non so più scrivere.... :p :p
e' che ultimamente le revisioni ortografiche dei termini inglesi sono l' unica cosa che sono capace a fare... :fagiano:
cdimauro
19-05-2006, 12:21
A proposito di Droppable: inserisco un metodo execute(), oppure creo un'interfaccia ad hoc, Executable, per quanto riguarda l'esecuzione delle azioni prelevate dal file di log?
A proposito di Droppable: inserisco un metodo execute(), oppure creo un'interfaccia ad hoc, Executable, per quanto riguarda l'esecuzione delle azioni prelevate dal file di log?
non ti conviene fare quest'interfaccia su chi usa le droppable?(action e commandHandler)
non ti conviene fare quest'interfaccia su chi usa le droppable?(action e commandHandler)
Sicuramente si fa una interfaccia a parte.
In ogn caso anch'io opererei solo su action e commandHandler ;)
cdimauro
19-05-2006, 13:07
Grazie per i consigli. :)
Vada per l'interfaccia a parte l'implementazione solo per action e handler.
jappilas
19-05-2006, 16:04
Siccome penso di aver fatto almeno una ventina di Post solo io parlando di aria fritta, ora faccoio un bel commit di un nuovo package
it.diamonds.droppable.interfaces
con tutte le interfaccie che mi sono venute fuori.
buona idea,
però allora, visto che le droppables e Grid sono oggetto di heavy refactoring, il mio task nella storia 2 mi sa che viene rimandato e i numeri sui candelotti non cambieranno per un altro po' :)
inoltre consideravo che forse manca un' interfaccia che descriva quello che è la dinamite, un oggetto non "animated" (per adesso) ma "stateful", basato su uno stato (il numero di candelotti in gioco) che ne pensate?
buona idea,
però allora, visto che le droppables e Grid sono oggetto di heavy refactoring, il mio task nella storia 2 mi sa che viene rimandato e i numeri sui candelotti non cambieranno per un altro po' :)
inoltre consideravo che forse manca un' interfaccia che descriva quello che è la dinamite, un oggetto non "animated" (per adesso) ma "stateful", basato su uno stato (il numero di candelotti in gioco) che ne pensate?
secondo me puoi gia lavorarci.
Basta creare un metodo da chiamare in gemsPariOnControllState, prima o dopo la updateStone.
Questo metodo accettera in input la gemsPair, controllerà se contiene una dinamite e in caso affermativo guarda quante dinamite ci sono in grid(ce gia la action) e setti il frame di conseguenza.
il tutto condito da test =D
jappilas
19-05-2006, 16:54
Basta creare un metodo da chiamare in gemsPariOnControllState, prima o dopo la updateStone.
Questo metodo accettera in input la gemsPair, controllerà se contiene una dinamite e in caso affermativo guarda quante dinamite ci sono in grid(ce gia la action) e setti il frame di conseguenza.
ok
ma se nel metodo controllo solo le gemspair, poi non posso scrivere i test atomici testando l' introduzione di una dinamite per volta, o sbaglio?
a sto punto pensavo di lavorare direttamente dentro Grid :O
il tutto condito da test =D
" Di Corsa ", cioè of course, come diceva un mio vecchio prof... ^^
ok
ma se nel metodo controllo solo le gemspair, poi non posso scrivere i test atomici testando l' introduzione di una dinamite per volta, o sbaglio?
a sto punto pensavo di lavorare direttamente dentro Grid :O
" Di Corsa ", cioè of course, come diceva un mio vecchio prof... ^^
si fa si fa :)
crei gridController.
Inserisci piu o meno dinamiti in grid
ottiene la gemsPair e la pulisci(in gridTestCase dovresti aver gia quello che fa al caso tuo, al max cerca in qualche test).
Poi inserisci 2 droppable in 13,4 e 12,4.
Queste 2 gemme le attacchi alla gemsPair.
fai partire la update di gridController.
dopo di che controlla che la dinamite abbia il frame giusto.
Ps.non so se è gia previsto ma la dinamite sarebbe da far cadere con il frame senza numero.
Penso di non aver postato mai così tanti messaggi in così poco tempo....
...io non so più che fare. :boh:
In realtà il mio task ha richiesto circa 8 minuti di lavoro...ma è almeno 5 giorni che mi scervello!!! :D
Io direi che ho terminato....anche perchè finchè non si va avanti non si capisce se ho fatto ca**ate o cose decenti.
Comuqnue questa storia me la sto pendrendo a cuore....quindi sarò sempre qui nei paraggi :Prrr:
Mi fate un aggiornamento sui task? 1 e 3 sono da assegnare.
l'1 non lo sta facendo Bonfo!?! potrei prendermi il 3, ma sono pieno di impegni, diciamo che avrei bisogno di 5 giorni...se c'è qualcuno che è meno impegnato e riesce a farlo in meno tempo....
Mi fate un aggiornamento sui task? 1 e 3 sono da assegnare.
Quasi quasi ti sgrido fek :mad:
E' quattro giorni che posto messaggi ad una frequenza disarmante per ciò che riguarda il task1....non è stato segnato nel primo post, ma le interfacce ci sono e sono pure già committate da un paio di giorni.
Ripeto quello che ho già detto...il task uno implica decisoni di design. Ho cercato di esporre i miei ragionamenti nel migliore dei modi nel topic.
Fek, se li ritieni validi, il task 1 e già fatto ;)
Quasi quasi ti sgrido fek :mad:
E' quattro giorni che posto messaggi ad una frequenza disarmante per ciò che riguarda il task1....non è stato segnato nel primo post, ma le interfacce ci sono e sono pure già committate da un paio di giorni.
Ripeto quello che ho già detto...il task uno implica decisoni di design. Ho cercato di esporre i miei ragionamenti nel migliore dei modi nel topic.
Fek, se li ritieni validi, il task 1 e già fatto ;)
Mea culpa mea culpa mea maxima culpa! Guardo subito il codice :D
Ok, le interfacce vanno abbastanza bene, ma ora Droppable deve solo piu' contenere i metodi per restituire il tipo di interfaccia e non tutta la sfilza di metodi, affinche' il task sia terminato. E getType() deve SPARIRE subito :)
Te ne puoi occupare?
Ok, le interfacce vanno abbastanza bene, ma ora Droppable deve solo piu' contenere i metodi per restituire il tipo di interfaccia e non tutta la sfilza di metodi, affinche' il task sia terminato. E getType() deve SPARIRE subito :)
Te ne puoi occupare?
Ecco....io prima di modificare Droppable mi sono fermato...mettere a posto il codice sarà un macello!!!
Volevo prima avere l'approvazione del lavoro.
Io eliminerei un metodo alla volta dall'interfaccia droppable, altrimenti il refactor diventa ingestibile.
Infine una domanda: cosa intendi per "i metodi per restituire il tipo di interfaccia" ??? :confused:
aahhh...forse ho capito.
Per evitare di fare dei cast rischiosi, ogni oggetto che si dice droppbale deve fonire dei getter per ogni interfaccia.
Esempio:
public interface Droppable
{
FallingObject getFallingObject();
}
e la classe verrà
public class AbstractDroppable implements Droppable,FallingObject
{
public FallingObject getFallingObject()
{
return this;
}
/*Metodi di FallingObject*/
}
Giusto?? :stordita:
Giusto?? :stordita:
Esatto :)
Fai un'interfaccia per volta. Sembra un lavoro lungo ma non e' cosi' male.
Poi, elimina l'interfaccia BrightObject e metti quei metodi nell'interfaccia Sprite.
Quando renderemo anche BigGem un droppable, cambieremo l'interfaccia Sprite e la chiameremo qualcosa di DrawableDroppable.
Stesso dicasi per getScore(), non merita un'interfaccia intera per un solo metodo. Bisogna trovargli un'altra casa.
Esatto :)
Fai un'interfaccia per volta. Sembra un lavoro lungo ma non e' cosi' male.
Poi, elimina l'interfaccia BrightObject e metti quei metodi nell'interfaccia Sprite.
Quando renderemo anche BigGem un droppable, cambieremo l'interfaccia Sprite e la chiameremo qualcosa di DrawableDroppable.
Stesso dicasi per getScore(), non merita un'interfaccia intera per un solo metodo. Bisogna trovargli un'altra casa.
Ok!! ;)
- Elimino l'interfaccia che contiene getScore;
- Elimino l'interfaccia BrightObject. finisce tutto in Sprite.
- Mi segno che le due cose sono ancora da mettere a posto. :Prrr:
Tutto ciò che riesco ad inseire in delle interfaccia sparirà da Droppable...il resto rimarà.
Quindi getCell e getScore e getSprite mi sa che rimarranno
Parto...vediamo che succede ;)
Domanda:
ma i getInterfaccia sono da testare o no??
che senso ha un getInterfaccia scusa? se una classe implementa un'interfaccia mica serve il getter, ci pensa già il polimorfismo... o ho capito male io? :p
Ok!! ;)
- Elimino l'interfaccia che contiene getScore;
- Elimino l'interfaccia BrightObject. finisce tutto in Sprite.
- Mi segno che le due cose sono ancora da mettere a posto. :Prrr:
Tutto ciò che riesco ad inseire in delle interfaccia sparirà da Droppable...il resto rimarà.
Quindi getCell e getScore e getSprite mi sa che rimarranno
Parto...vediamo che succede ;)
Sto seguendo, va bene :)
che senso ha un getInterfaccia scusa? se una classe implementa un'interfaccia mica serve il getter, ci pensa già il polimorfismo... o ho capito male io? :p
Questa volta hai capito male tu :p
E' un Design Pattern. Per altro e' il DP di COM. I getInterfaccia sono molto simili a QueryInterface.
Non sono da testare.
cdimauro
22-05-2006, 09:35
Stavo analizzando i costruttori delle azioni e degli stati per implementare il LogReader, ma mi sono accorto di un paio di cosette:
public StoneFallState(Environment environment, Pattern pattern)
public WaitBeforeNewGemsPairState(Environment environment, GridController controller, long time)
public WaitNextCrushState(Environment environment, long time)
public UpdateAnimationsAction(long timer)
public CreateNewBigGemsAction(Grid grid, BigGemList bigGems)
Per quanto riguarda StoneFallState, penso che dovrebbe essere sufficiente serializzare nel file di log anche l'oggetto pattern, oltre al nome dello stato.
I problemi sorgono con i costruttori che prevedono la presenza di un parametro time. La difficoltà non sta nel conservarla/recuperarla, ma sul fatto che time è legato al momento in cui è stato "eseguita" l'azione (o lo stato), per cui è già "scaduta" come informazione.
Ricordo male, o avevamo detto di far sparire il timestamp e basare tutto su un "GameTurn"?
Infine per CreateNewBigGemsAction noto che viene passata una lista di BigGem: è sufficiente serializzare l'elenco delle BigGem (più esattamente, row, column, e gemColor) e passaglierlo al costruttore (a naso direi di sì)?
Stavo analizzando i costruttori delle azioni e degli stati per implementare il LogReader, ma mi sono accorto di un paio di cosette:
public StoneFallState(Environment environment, Pattern pattern)
public WaitBeforeNewGemsPairState(Environment environment, GridController controller, long time)
public WaitNextCrushState(Environment environment, long time)
public UpdateAnimationsAction(long timer)
public CreateNewBigGemsAction(Grid grid, BigGemList bigGems)
Per quanto riguarda StoneFallState, penso che dovrebbe essere sufficiente serializzare nel file di log anche l'oggetto pattern, oltre al nome dello stato.
I problemi sorgono con i costruttori che prevedono la presenza di un parametro time. La difficoltà non sta nel conservarla/recuperarla, ma sul fatto che time è legato al momento in cui è stato "eseguita" l'azione (o lo stato), per cui è già "scaduta" come informazione.
Ricordo male, o avevamo detto di far sparire il timestamp e basare tutto su un "GameTurn"?
Infine per CreateNewBigGemsAction noto che viene passata una lista di BigGem: è sufficiente serializzare l'elenco delle BigGem (più esattamente, row, column, e gemColor) e passaglierlo al costruttore (a naso direi di sì)?
io ieri ho notato una cosa. Le action per come sono state pensate, sono delle azioni su una gemma, mentre per come stiamo ragionando su questo refactoring, sono delle azioni sulla griglia.
A parer miio bisognerebbe prendere le attuali action, rinominarle in qualche maniera(actionGem?), e costruire degli altri tipi di action (actionGrid?) che saranno quelle realmente chiamate dagli state e loggate.
Forse si risolverebbe anche il problema di CreateNewBigGemsAction, infatti sarebbe la actionGrid correlata a trovare la lista di bigGem da passare a
CreateNewBigGemsAction.
Questo potrebbe diminuire il numero di oggetti serializzati, e il numero di eventi da loggare, ma aggiunge un ulteriore livello di indirezione (state->gridAction->gemAction) e un ulteriore refactoring per arrivare al playback.
Per il fatto del time passato, secondo me nella riproduzione non va considerato, visto che si è deciso di non essere timer dipendenti. Si puo fare in modo che il timming venga gestito solo dagli state, mentre noi loggando solo le action ce ne possiamo disinteressare.
Per UpdateAnimationsAction questo discorso non so quanto valga, ma si puo anche considerare di non metterla nel log(non agisce sulla griglia, ma sulle texture delle gemme...al max si puo creare uno state he faccia il lavoro di timming).
ps.seguendo il discorso di fek di legarci il meno possibile alle classi e alla loro implementazione, eviterei di serializzare oggetti(a meno che le info relative siano molte e sia lungo e complicato farne una stringa, tipo l'eventuale lista di bigGem ;) ).
Questo potrebbe diminuire il numero di oggetti serializzati, e il numero di eventi da loggare, ma aggiunge un ulteriore livello di indirezione (state->gridAction->gemAction) e un ulteriore refactoring per arrivare al playback.
A pelle qual e' il tuo giudizio? Quale delle due soluzioni e' piu' semplice?
ps.seguendo il discorso di fek di legarci il meno possibile alle classi e alla loro implementazione, eviterei di serializzare oggetti(a meno che le info relative siano molte e sia lungo e complicato farne una stringa, tipo l'eventuale lista di bigGem ;) ).
Si', preferisco non serializzare oggetti. Per ora abbiamo solo un pattern quindi e' implcito. In futuro vedremo.
cdimauro
22-05-2006, 12:11
Immaginavo ci fosse qualche casino: sentivo puzza di bruciato. Ci rifletto sopra.
Per quanto riguarda la serializzazione, specifico che intendevo soltanto la scrittura dei dati di certi oggetti (pattern) su file, in qualche formato che decido io.
A pelle qual e' il tuo giudizio? Quale delle due soluzioni e' piu' semplice?
Lasciando le cose come adesso, ci sarebbe meno refactoring da fare, ma piu lavoro da fare sul logger(sopratutto si rischierebbe di dover gestire ogni action in maniera particolare).
Facendo il refactoring, si pederebbe tempo in questo(non so quanto tempo.. in alcuni ambiti basterebbe aggiungere una classe di indirezione, in altri casi si dovrebbe lavorare di piu), ma poi il logger dovendo lavorare al livello di azioni su grid, potrebbe essere piu semplice da realizzare.
Io preferisco la seconda ipotesi, a meno che cdimauro non trovi qualche altra soluzione, o un misto fra le 2.
Fra l'altro si potrebbero individurare le action da realizzare, e assegnarle come task.
cdimauro
22-05-2006, 12:31
Sinceramente in questo momento non ti so dire. Nella pausa pranzo controllo i sorgenti e cerco di capire quanto lavoro comporterebbe la rifattorizzazione (che è la strada che preferisco).
io ieri ho notato una cosa. Le action per come sono state pensate, sono delle azioni su una gemma, mentre per come stiamo ragionando su questo refactoring, sono delle azioni sulla griglia.
A parer miio bisognerebbe prendere le attuali action, rinominarle in qualche maniera(actionGem?), e costruire degli altri tipi di action (actionGrid?) che saranno quelle realmente chiamate dagli state e loggate.
[...]
Questo potrebbe diminuire il numero di oggetti serializzati, e il numero di eventi da loggare, ma aggiunge un ulteriore livello di indirezione (state->gridAction->gemAction) e un ulteriore refactoring per arrivare al playback.
Anche secondo me bisogna frae questo passaggio....e forse anche le "GemAction" potrebbero semplificarsi se non sparire ;)
cdimauro
22-05-2006, 15:13
Ho appena finito di analizzare Grid, Actions, States et similia: in effetti la soluzione migliore è rifattorizzare il codice introducendo delle GridActions, convogliando in esse tutto il codice che agisce poi a livello di action sulle single gemme.
In questo modo il logging (e l'esecuzione) delle (grid) action risulterebbe piuttosto semplice da implementare.
Il prezzo da pagare è, purtroppo, una sostanziasa rifattorizzazione. Perché se "convogliare" il codice di metodi di Grid come updateDroppableAnimations(), updateBigGems(), ecc. risulta piuttosto semplice, non è altrettanto vero per metodi come updateDroppable() che agiscono su singoli Droppable, e vengono richiamati da punti diversi del codice (non da Grid :( ) sia su singolo oggetti sia iterando su varii elementi.
E' un lavoro che, più che complicato, porterà via un po' di tempo, cercando di ricostruire i flussi delle chiamate ai varii e metodi di Grid. Ma è anche un lavoro che vedo come prioritario per razionalizzare e semplificare il codice.
Personalmente mi piacerebbe vedere, come dicevo all'inizio, tutto il codice che comporta l'esecuzione di azioni in un solo posto, e sotto forma di grid action.
Ho appena finito di analizzare Grid, Actions, States et similia: in effetti la soluzione migliore è rifattorizzare il codice introducendo delle GridActions, convogliando in esse tutto il codice che agisce poi a livello di action sulle single gemme.
In questo modo il logging (e l'esecuzione) delle (grid) action risulterebbe piuttosto semplice da implementare.
Il prezzo da pagare è, purtroppo, una sostanziasa rifattorizzazione. Perché se "convogliare" il codice di metodi di Grid come updateDroppableAnimations(), updateBigGems(), ecc. risulta piuttosto semplice, non è altrettanto vero per metodi come updateDroppable() che agiscono su singoli Droppable, e vengono richiamati da punti diversi del codice (non da Grid :( ) sia su singolo oggetti sia iterando su varii elementi.
E' un lavoro che, più che complicato, porterà via un po' di tempo, cercando di ricostruire i flussi delle chiamate ai varii e metodi di Grid. Ma è anche un lavoro che vedo come prioritario per razionalizzare e semplificare il codice.
Personalmente mi piacerebbe vedere, come dicevo all'inizio, tutto il codice che comporta l'esecuzione di azioni in un solo posto, e sotto forma di grid action.
approved :rulez:
per updateDroppable and company, si possono lasciare in grid, ma spostare la loro chiamata in gridAction apposite.
Anzi io creerei una actionGem apposita per far scendere le gemme.
Poi creerei N actionGrid per ogni azione di far cadere le gemme(tutte, solo la gemsPair, solo le Stone, etc), che verranno chiamate dai vari stati.
Ho appena finito di analizzare Grid, Actions, States et similia: in effetti la soluzione migliore è rifattorizzare il codice introducendo delle GridActions, convogliando in esse tutto il codice che agisce poi a livello di action sulle single gemme.
In questo modo il logging (e l'esecuzione) delle (grid) action risulterebbe piuttosto semplice da implementare.
Il prezzo da pagare è, purtroppo, una sostanziasa rifattorizzazione. Perché se "convogliare" il codice di metodi di Grid come updateDroppableAnimations(), updateBigGems(), ecc. risulta piuttosto semplice, non è altrettanto vero per metodi come updateDroppable() che agiscono su singoli Droppable, e vengono richiamati da punti diversi del codice (non da Grid :( ) sia su singolo oggetti sia iterando su varii elementi.
E' un lavoro che, più che complicato, porterà via un po' di tempo, cercando di ricostruire i flussi delle chiamate ai varii e metodi di Grid. Ma è anche un lavoro che vedo come prioritario per razionalizzare e semplificare il codice.
Personalmente mi piacerebbe vedere, come dicevo all'inizio, tutto il codice che comporta l'esecuzione di azioni in un solo posto, e sotto forma di grid action.
Attenzione: con il refactoring in atto su Droppable Grid dovrebba avere una gestione mooolto più semplice.
E anche le action di conseguenza.
Se la mia previsone non sbaglia guardate come diventerà la UpdateFallsAction:
public void applyOn(EngineInterface engine, Droppable gem)
{
if(gem.getFallingObject().canMoveDown())
{
gem.getFallingObject().moveDown())
}
}
:sofico: :sofico:
cdimauro
22-05-2006, 15:52
[AVVOLTOIO MODE ON]
Allora aspetto che finiate.
[AVVOLTOIO MODE OFF]
:D
x thebol: è quello che pensavo di fare. Mi sembra la soluzione più semplice ed elegante. :)
Bonfo per quando pensi di finire?
Bonfo per quando pensi di finire?
Altra cosa: Il mio task è da fare in pair e nessuno si è ancora offerto :P
FINITO :D
O meglio...chissà se ho finito.
Questa storia è un lavoro continuo. In ogni caso si può lavorare tranquillamente.
Vi posso solo dire che ora la gestione della caduta delle gemme è molto più semplice e chiara...sono molto soddisfatto!!!
Praticamente le righe di codice sono diminuite di più del 50% ;)
Altra cosa.
Ho spostato molti metodi da Grid a AbstractDroppbale.
In questo modo ho migliorato l'incapsulamento per ciò che riguarda Cell e Sprite.
Ma non va ancora bene. :O
In realtà molti di quei metodi sono responsabilità di Grid...
...il gioco è che diveranno solo metodi di "utilità" e sarà compito di AbsractDRoppable usarli nel modo giusto ;)
In questo modo grid non avrà bisogno di fare Sprite.getY() perchè tale valore sarà direttamente fornito all'invocazione del metodo.
Appena posso vado avanti.
A proposito...io ci sono per il pair :D
Bisogna solo mettersi un attimo d'accordo :(
public void applyOn(EngineInterface engine, Droppable gem)
{
if(gem.getFallingObject().canMoveDown())
{
gem.getFallingObject().moveDown())
}
}
E questo codice diventa automaticamente questo:
public void applyOn(EngineInterface engine, Droppable gem)
{
gem.getFallingObject().moveDown())
}
Dove canMoveDown() e' assorbito dentro moveDown().
Vi posso solo dire che ora la gestione della caduta delle gemme è molto più semplice e chiara...sono molto soddisfatto!!!
Praticamente le righe di codice sono diminuite di più del 50% ;)
Bravissimo!
Metto qui i metodi che sono in AbstractDroppable e che devono abdare in Grid, altrimenti me lo scordo :D
Nel passaggio io metterei come parametri (float verticalPosition, int row)
Praticamente grid si prende il compito di dirci come siamo posizionati rispetto alla riga data la posizione verticale:
private boolean isDroppableCollidingWithBottom(Grid grid)
private boolean willDroppableCollideWithBottom(Grid grid)
private boolean hasDroppableMovedToNextRow(Grid grid)
private boolean willDroppableMovedToNextRow(Grid grid)
private boolean isDroppableInItsOwnRow(Grid grid)
In questo modo si unificano pure le prime due coppie di metodi ;)
Bene. Sposta pure quei metodi in Grid.
E questo codice diventa automaticamente questo:
public void applyOn(EngineInterface engine, Droppable gem)
{
gem.getFallingObject().moveDown())
}
Dove canMoveDown() e' assorbito dentro moveDown().
Esatto...è diventato proprio così :D :D
EDIT: e canMoveDown() non è stato affatto assorbito...il che vuol dire che da qualche parte c'è un controllo che può essere sotituito ;)
Ecco...appunto.
Ho esplorato perchè moveDown funzionasse anche senza il controllo canMoveDown.
Semplicemente perchè c'è un controllo che evitache l'applicazione della gravità la faccia strabordare nonostatnte la gemma si possa ancora muovere perchè non è ancora arrivata. In questo caso si procede ad un semplice allineamento alla griglia.
Questo fantastico controllo fa sì che la gemma, ogni volta che gli si chieda di cadere, semplicemente si accorge che straborderebbe e quini si riallinea alla griglia non muovendosi.
Quindi la posizione Y della gemma viene in continuazione risetta...anche se ferma :eek: :eek:
La puzza di un comportamento strano lo avevo già avuto quando due metodi che dovrebbero funzionare allo stesso modo hanno implementazioni diverse:
private boolean isDroppableCollidingWithBottom(Grid grid)
{
return getSprite().getY() >= grid.getGridBottom();
}
private boolean willDroppableCollideWithBottom(Grid grid)
{
return getSprite().getY() + grid.getActualGravity() > grid.getGridBottom();
}
e basta cambiare uno dei due che dei test falliscono. :mad:
C'è qualcuno che ha la pazienza di darci un occhio iniseme a me??
E' da 2 giorni che guarda sempre la stessa roba e non ho più l'occhio critico :cry:
C'è qualcuno che ha la pazienza di darci un occhio iniseme a me??
E' da 2 giorni che guarda sempre la stessa roba e non ho più l'occhio critico :cry:
Cesare puoi guardarci? Sarebbe ottimo poter eliminare uno di quei due metodi, e' un'evidente duplicazione.
Mi sa di aver capito cosa c'è di strano :sofico:
canMoveDown() e droppableWontMoveDownAfterMoving(), che è il controllo per l'allineamento, non sono mai entrambi true...che mi sa di sbagliato.
Infatti:
[junit] ROW_13: yPos 456.0
[junit] MY_GEM: yPos 455.9
[junit] GRAVITY: 0.5
[junit] canMoveDown: true
[junit] droppableWontMoveDownAfterMoving: false
Non è un test...sono solo delle print perchè droppableWontMoveDownAfterMoving è privato.
In ogni caso non dovrebbe tornare TRUE :eekk:
cdimauro
23-05-2006, 08:28
Cesare puoi guardarci? Sarebbe ottimo poter eliminare uno di quei due metodi, e' un'evidente duplicazione.
OK, gli do un'occhiata.
cdimauro
23-05-2006, 09:18
Mi sa di aver capito cosa c'è di strano :sofico:
canMoveDown() e droppableWontMoveDownAfterMoving(), che è il controllo per l'allineamento, non sono mai entrambi true...che mi sa di sbagliato.
Infatti:
[junit] ROW_13: yPos 456.0
[junit] MY_GEM: yPos 455.9
[junit] GRAVITY: 0.5
[junit] canMoveDown: true
[junit] droppableWontMoveDownAfterMoving: false
Non è un test...sono solo delle print perchè droppableWontMoveDownAfterMoving è privato.
In ogni caso non dovrebbe tornare TRUE :eekk:
Ho finito di guardare i due metodi, e a mio avviso è giusto che non siano entrambi true, perché hanno significati diversi.
canModeDown fa uso di isDroppableCollidingWithBottom, che effettua un controllo sullo stato corrente dell'oggetto.
droppableWontMoveDownAfterMoving, usato da moveDown, esegue invece un controllo su quello che succederebbe alla prossima iterazione, cioé se al prossimo "frame" venisse applicata la gravità.
Tutto ciò chiaramente se non ho capito male. :)
Se è veramente così come penso, io direi che droppableWontMoveDownAfterMoving dovrebbe essere eliminato: eventuali decisioni future andrebbero prese, appunto, in futuro. Non adesso.
In parole povere: se per adesso io mi posso spostare giù, dovrei poterlo fare senza condizionamenti. Sotto è libero? Allora scendo. Se alla prossima iterazione non potrò più farlo, amen: me ne starò fermo.
Se è veramente così come penso, io direi che droppableWontMoveDownAfterMoving dovrebbe essere eliminato: eventuali decisioni future andrebbero prese, appunto, in futuro. Non adesso.
In parole povere: se per adesso io mi posso spostare giù, dovrei poterlo fare senza condizionamenti. Sotto è libero? Allora scendo. Se alla prossima iterazione non potrò più farlo, amen: me ne starò fermo.
No, non si può. :O
Come si vede dall'esempio che ho postato, la gemma può ancora cadere (ha ancora 0.1 di spazio), ma qualora gli venisse applicata la gravità, che è di 0.5) andrebbe a 456.4, ovvero 0.4 oltre il bordo della griglia.
Ecco cosa serve quel metodo, per dirci se, pur muovendoci ancora, non possiamo applicare interamente la gravità altrimenti "sfondiamo".
Qualora si presenti questo la gemma fa fatta cadere per quanto possibile, senza applicargli la gravità ,ovvero allinearla al fondo, nel nostro caso spostandola di 0.1
Ecco perchè in quel caso secondo me dorvrebbero essere entrambi TRUE. ;)
Forse bisogfna cambaire nome al metodo ;)
Potrebbe diventare:
canMoveButNotWithFullGravity
;)
EDIT: lo faccio subito :P
No, non si può. :O
Come si vede dall'esempio che ho postato, la gemma può ancora cadere (ha ancora 0.1 di spazio), ma qualora gli venisse applicata la gravità, che è di 0.5) andrebbe a 456.4, ovvero 0.4 oltre il bordo della griglia.
Ecco cosa serve quel metodo, per dirci se, pur muovendoci ancora, non possiamo applicare interamente la gravità altrimenti "sfondiamo".
Qualora si presenti questo la gemma fa fatta cadere per quanto possibile, senza applicargli la gravità ,ovvero allinearla al fondo, nel nostro caso spostandola di 0.1
Ecco perchè in quel caso secondo me dorvrebbero essere entrambi TRUE. ;)
Non si puo mettere il controllo nel moveDown? Controllo se cè spazio(S), mi devo muvoere di di tot (G) per la gravità, controllo che X sia >= G, se è vero mi muovo di G, altrimenti di S?
non ho il sorgente sotto mano..(direi che è il mio discorso è similie a quello di cdimauro, cioè il controllo va fatto quando ci muoviamo, non prima)
Mi sa di aver capito cosa c'è di strano :sofico:
canMoveDown() e droppableWontMoveDownAfterMoving(), che è il controllo per l'allineamento, non sono mai entrambi true...che mi sa di sbagliato.
Infatti:
[junit] ROW_13: yPos 456.0
[junit] MY_GEM: yPos 455.9
[junit] GRAVITY: 0.5
[junit] canMoveDown: true
[junit] droppableWontMoveDownAfterMoving: false
Non è un test...sono solo delle print perchè droppableWontMoveDownAfterMoving è privato.
In ogni caso non dovrebbe tornare TRUE :eekk:
...ora ritornano entrambi true...senza cambiare nulla....
Mi sa che avevo sbagliato io :cry: :cry:
:ops:
In ogni caso
private boolean isDroppableCollidingWithBottom(Grid grid)
{
return getSprite().getY() >= grid.getGridBottom();
}
private boolean willDroppableCollideWithBottom(Grid grid)
{
return getSprite().getY() + grid.getActualGravity() > grid.getGridBottom();
}
Sono da unificare.
Non si puo mettere il controllo nel moveDown? Controllo se cè spazio(S), mi devo muvoere di di tot (G) per la gravità, controllo che X sia >= G, se è vero mi muovo di G, altrimenti di S?
non ho il sorgente sotto mano..(direi che è il mio discorso è similie a quello di cdimauro, cioè il controllo va fatto quando ci muoviamo, non prima)
Infatti...è proprio in moveDown che viene fatto
public void moveDown(Grid grid)
{
if(canMoveButNotWithFullGravity(grid))
{
sprite.setPosition(sprite.getX(), grid.getRowUpperBound(getCell().getRow()));
this.drop();
}
else
{
sprite.translate(0, grid.getActualGravity());
}
if(isDroppableMovedToNextRow(grid))
{
grid.removeDroppableFromGrid(this);
getCell().setRow(getCell().getRow()+1);
grid.addDroppableToGrid(this);
}
}
cdimauro
23-05-2006, 13:29
No, non si può. :O
Come si vede dall'esempio che ho postato, la gemma può ancora cadere (ha ancora 0.1 di spazio), ma qualora gli venisse applicata la gravità, che è di 0.5) andrebbe a 456.4, ovvero 0.4 oltre il bordo della griglia.
Ecco cosa serve quel metodo, per dirci se, pur muovendoci ancora, non possiamo applicare interamente la gravità altrimenti "sfondiamo".
Qualora si presenti questo la gemma fa fatta cadere per quanto possibile, senza applicargli la gravità ,ovvero allinearla al fondo, nel nostro caso spostandola di 0.1
Ecco perchè in quel caso secondo me dorvrebbero essere entrambi TRUE. ;)
Ho capito. Ma in questo caso non basterebbe impostare la posizione della gemma a 456.0 e fermarla?
WOW... :D
piccola modifica di una condizione e sapete che è successo:
-isDroppableCollidingWithBottom(Grid grid) è sparito da AbstractDroppable
-un'altro metodo è sparitop da grid, getGridBottom
- si è aperta la strada per altree semplificazioni ;)
cdimauro
23-05-2006, 13:54
Ma come, dopo tutte le discussioni che abbiamo fatto, non ci dici neppure cos'hai cambiato? Preparo il gatto a 9 code... :D
Build failed
Test: testBottomCollision
Class: it.diamonds.tests.TestCellsideCollision
Type: java.lang.ArrayIndexOutOfBoundsException
Message: 14
java.lang.ArrayIndexOutOfBoundsException: 14 at it.diamonds.grid.Grid.addDroppableToGrid(Grid.java:280) at it.diamonds.droppable.AbstractDroppable.moveDown(AbstractDroppable.java:317) at it.diamonds.grid.Grid.updateDroppable(Grid.java:239) at it.diamonds.tests.TestCellsideCollision.testBottomCollision(TestCellsideCollision.java:142)
Test: testBottomCollisionSound
Class: it.diamonds.tests.TestCellsideCollision
Type: java.lang.ArrayIndexOutOfBoundsException
Message: 14
java.lang.ArrayIndexOutOfBoundsException: 14 at it.diamonds.grid.Grid.addDroppableToGrid(Grid.java:280) at it.diamonds.droppable.AbstractDroppable.moveDown(AbstractDroppable.java:317) at it.diamonds.grid.Grid.updateDroppable(Grid.java:239) at it.diamonds.tests.TestCellsideCollision.testBottomCollisionSound(TestCellsideCollision.java:159)
cdimauro
23-05-2006, 14:53
Build failed
Test: testBottomCollision
Class: it.diamonds.tests.TestCellsideCollision
Type: java.lang.ArrayIndexOutOfBoundsException
Message: 14
java.lang.ArrayIndexOutOfBoundsException: 14 at it.diamonds.grid.Grid.addDroppableToGrid(Grid.java:280) at it.diamonds.droppable.AbstractDroppable.moveDown(AbstractDroppable.java:317) at it.diamonds.grid.Grid.updateDroppable(Grid.java:239) at it.diamonds.tests.TestCellsideCollision.testBottomCollision(TestCellsideCollision.java:142)
Test: testBottomCollisionSound
Class: it.diamonds.tests.TestCellsideCollision
Type: java.lang.ArrayIndexOutOfBoundsException
Message: 14
java.lang.ArrayIndexOutOfBoundsException: 14 at it.diamonds.grid.Grid.addDroppableToGrid(Grid.java:280) at it.diamonds.droppable.AbstractDroppable.moveDown(AbstractDroppable.java:317) at it.diamonds.grid.Grid.updateDroppable(Grid.java:239) at it.diamonds.tests.TestCellsideCollision.testBottomCollisionSound(TestCellsideCollision.java:159)
Cantami o diva del pelide Achille, l'ira funesta che infiniti addusse, lutti :asd:
:asd:
Bonfo torna qua e sistema la build, scappa dopo :D
jappilas
23-05-2006, 15:04
O_o
ho l' impressione che qualche ditino sia in procinto di spezzarsi... :p :(
Non ho cambiato niente....o meglio ho solo cambiato una condizione...ma a me ANT da tutto verde.
Ci riguardo ;)
EDIT: no...ANT da rosso :(
Ho fatto una piccola ingenuità di indexing...ero convinto che getNumberOfRows() desse 13 :fagiano:
CORRETTO ;)
Non ho cambiato niente....o meglio ho solo cambiato una condizione...ma a me ANt da tutto verde.
Ci riguardo ;)
un random bug?
No no....
...avevo proprio sbagliato io :muro: :muro:
No no....
...avevo proprio sbagliato io :muro: :muro:
No prob. La build machine e' li' proprio per prendere al volo queste sviste :)
OK...direi che ora ho proprio "finito".
Ovvero il task è più che conlcuso. Rinnovo la mia disponibilità a fare il task 2 in pair con UFO.
In ogni caso la rifattorizzazione di grid è necessaria al più presto.
Per come sono memorizzate le gemme, ogni volta che si cambia Row o COlumn a una gemma bisogna invocare anche removeDRoppable e addDroppable.
grid.removeDroppableFromGrid(this);
getCell().setRow();
grid.addDroppableToGrid(this);
Per me è un po' molto schifoso :D :D
OK...direi che ora ho proprio "finito".
Ovvero il task è più che conlcuso. Rinnovo la mia disponibilità a fare il task 2 in pair con UFO.
In ogni caso la rifattorizzazione di grid è necessaria al più presto.
Per come sono memorizzate le gemme, ogni volta che si cambia Row o COlumn a una gemma bisogna invocare anche removeDRoppable e addDroppable.
grid.removeDroppableFromGrid(this);
getCell().setRow();
grid.addDroppableToGrid(this);
Per me è un po' molto schifoso :D :D
Fantastico lavoro. Come direbbe Peter, "Amazing job!" :D
Possiamo mettere la rifattorizzazione di Grid come un paio di task del prossimo Ciclo.
Ora non ci restano che i due pair con Ufo e concludere l'altra Storia.
Il task 1 quindi è completato giusto ?
ciao ;)
sì sì...completato ;)
Ricordate del problema che canMoveDown non era usato in moveDown e la gestione della non caduta era fatta da canMoveButNotWithFullGravity...??
Ora vi espongo cosa ho fatto.
Per primo ho modificato
public void moveDown(Grid grid)
{
CODICE
}
in
public void moveDown(Grid grid)
{
if(canMoveDown(grid))
{
CODICE
}
}
A questo punto il primo test che fallisce è questo: it.diamonds.tests.TestCellsideCollision.testBottomCollisionSound
Vado a vedere e scopro subito il perchè:
public void testBottomCollisionSound()
{
Sound sound = environment.getAudio().createSound("diamond");
gem.getObjectWithCollisionSound().setCollisionSound(sound);
grid.setGravity(1);
grid.insertDroppable(gem, 13, 4);
grid.updateDroppable(gem);
assertTrue(sound.wasPlayed());
}
prima passava perchè ola condizione canMoveButNotWithFullGravity era vera e quindi la gemma all'update veniva riallineata, ora non più.
Inoltre non capendo quel setGravity lo tolgo e cambio il test.
public void testBottomCollisionSound()
{
Sound sound = environment.getAudio().createSound("diamond");
gem.getObjectWithCollisionSound().setCollisionSound(sound);
grid.insertDroppable(gem, 12, 4);
while(gem.getFallingObject().canMoveDown(grid))
{
grid.updateDroppable(gem);
}
assertTrue(sound.wasPlayed());
}
Il test mi sembra corretto, anzi mooolto corretto. :D
Il problema è...NON PASSA :muro: :muro:
Allora vado da una vecchia conoscenza in AbstractDroppable e cambio il metodo (ho aggiunto l'uguale)
private boolean isDroppableCollidingWithBottomApplyingGravity(Grid grid)
{
float gridBottom = grid.getRowUpperBound(grid.getNumberOfRows() - 1);
return getSprite().getY() + grid.getActualGravity() >= gridBottom;
}
Ora il test PASSA.
Questo è uno dei due famosi metodi che facevano la stessa cosa ma erano diversi...bhè ora fanno proprio la stessa cosa...e vedo già ulteriori semplificazioni.
Ora però ci sono altri test che non passano...lì dò per sbagliati e li correggo alla luce delle nuove rivelazioni ;)
CIAO
P.S.: penso di committare domani finito di correggere i test :sofico:
P.P.S.: a proposito...già che c'ero ho eliminato da grid getYStep()....praticamente non lo usa più nessuno :Prrr: :sofico:
Ecco...come volevasi dimostrare.
Non è una questione di test "sbagliati" e da aggiornare....è proprio una questione di codice.
Domani esploro un'altro po'....ora LETTO!!! :ronf:
Il 16.1.2 e' da riassegnare. Il 16.1.3 e' ancora libero. Abbiamo due giorni per 4 task, forza!
Il 16.1.2 e' da riassegnare. Il 16.1.3 e' ancora libero. Abbiamo due giorni per 4 task, forza!
stavo guardando per il 2..
è veramente molto complesso, bisogna pianificare bene i passaggi da fare per il refactoring.
ad esempio il getSprite e il getCell di droppable non ha senso per una bigGem, bisogna incorporare tutto il codice che utilizza queste funzioni in droppableAbstract & soons
ad esempio per integrare le bigGem, non ci starebbe male una nuova interfaccia
GrouppableObject, con dei metodi isGrouppable, setInGroup, isInGroup
...
...
ho fatto delle prove, sembra molto utile, e sembra anche un passettino avanti verso la rimozione del getType(usando isGrouppable, non controllo se la droppable è una gemma ;) )
purtroppo ho sul portatile la versione buggata di ieri, e non posso fare sync fino a stassera, quindi non riesco a vedere se la modifica fa fallire dei test.
Direi cmq che è un buon punto di inizio.
... quindi anche una BigGem per te è un GrouppableObject?!? :mbe:
MI PIACE!!!! :D
A prima sensazione, secondo me ora state complicando troppo una cosa sostanzialmente semplice.
Se le interfacce di Droppable e BigGem (ad esempio Sprite) sono differenti, il passo successivo non e' creare una nuova interfaccia, ma rendere le due interfacce uguali.
Droppable puo' diventare piu' simile all'interfaccia di BigGem oppure BigGem puo' essere "adattata" a diventare un Droppable. Interfacce come Sprite e Cell non sono immutabili, possono cambiare per aiutare questa unione.
Provate questa strada.
... quindi anche una BigGem per te è un GrouppableObject?!? :mbe:
MI PIACE!!!! :D
sarebbe da valutare quando le bigGem si possono unire, ma per ora lascerei perdere.
A prima sensazione, secondo me ora state complicando troppo una cosa sostanzialmente semplice.
Se le interfacce di Droppable e BigGem (ad esempio Sprite) sono differenti, il passo successivo non e' creare una nuova interfaccia, ma rendere le due interfacce uguali.
Droppable puo' diventare piu' simile all'interfaccia di BigGem oppure BigGem puo' essere "adattata" a diventare un Droppable. Interfacce come Sprite e Cell non sono immutabili, possono cambiare per aiutare questa unione.
Provate questa strada.
cell, è un bean per row e column, non si puo fare tanto..
Si potrebbe gestire una collection di Cell invece che una Cell, ma sarebbe una collection che serve solo a bigGem. E piu naturale che bigGem si adatti alle altre che il contrario.
stesso discorso per sprite
E secondo me piu semplice adattare droppable a bigGem che il contrario. getSprite e sopratutto getCell per una bigGem non hanno molto senso
cell, è un bean per row e column, non si puo fare tanto..
Si potrebbe gestire una collection di Cell invece che una Cell, ma sarebbe una collection che serve solo a bigGem. E piu naturale che bigGem si adatti alle altre che il contrario.
stesso discorso per sprite
E secondo me piu semplice adattare droppable a bigGem che il contrario. getSprite e sopratutto getCell per una bigGem non hanno molto senso
Si puo' dire che Cell e' un row e column con width e height che per una gemma e' fisso a 1x1. Per Sprite, basta cambiare nome all'interfaccia, gli altri metodi mi sembravano molto simili a quelli di BigGem.
Si puo' dire che Cell e' un row e column con width e height che per una gemma e' fisso a 1x1. Per Sprite, basta cambiare nome all'interfaccia, gli altri metodi mi sembravano molto simili a quelli di BigGem.
Direi che se consideriamo Cell così, finiscce direttamente in GridObject e diventata coerente anche per BigGem.
Per ciò che riguarda getSprite, io la incapsulerei dentro Droppable, al quale farei implementare Drawable.
Direi che se consideriamo Cell così, finiscce direttamente in GridObject e diventata coerente anche per BigGem.
Per ciò che riguarda getSprite, io la incapsulerei dentro Droppable, al quale farei implementare Drawable.
ok su entrambe le cose.
cosi le gemme normali sanno come disegnarsi, e uguale le bigGem.
AIUTO, mi sono perso!!!! :cry:
Non capisco più nulla.
Avete presente quel poste eterno di ieri notte...bene...non consideratelo.
REVERTO TUTTO. :muro: :muro:
Il ragionamento è giusto, ma non sto più riuscendo a gestire il codice, quel piccolo uguale impatta su tutto il gioco...MILLE MILIONI TI TEST (mi sento molto l'ingegner cane :D)
E in ogni caso se con il serGravity() di grid si mette un valore maggiore di YSTEP, ovvero Height/NumberOfRows, salta tutto!!!
Per fortuna nel codice di produzione non c'è manco un setGravity...quindi mi sa che bisogna adattare i test per eliminare pure quel metodo :perfido:
Si puo' dire che Cell e' un row e column con width e height che per una gemma e' fisso a 1x1. Per Sprite, basta cambiare nome all'interfaccia, gli altri metodi mi sembravano molto simili a quelli di BigGem.
Mi sono appena accorto, che diventerebbe una Rectangle, che fra l'altro ha gia alcuni metodi interessanti, tipo translate, resize(e che è gia usata in bigGem)
L'unica differenza e che Rectangle ha i vertici invece che le coord di un vertice piu width e height...
possiamo usare questa al posti di cell?
ce da dire che rectangle di solito viene usata per l'engine e gli sprite...
Mi sono appena accorto, che diventerebbe una Rectangle, che fra l'altro ha gia alcuni metodi interessanti, tipo translate, resize(e che è gia usata in bigGem)
L'unica differenza e che Rectangle ha i vertici invece che le coord di un vertice piu width e height...
possiamo usare questa al posti di cell?
ce da dire che rectangle di solito viene usata per l'engine e gli sprite...
mmmmhhh.....
ragioniamoci bene perchè vedo il rischio di mischiare resposabilità.
Ah...ecco già un punto a sfavore.
Rectangle è continua, ovvero può assumere valori con la virgola.
Cell invece è intera, ovvero le coord possono avere solo valori 1,2 ,3 ecc.
mmmmhhh.....
ragioniamoci bene perchè vedo il rischio di mischiare resposabilità.
Ah...ecco già un punto a sfavore.
Rectangle è continua, ovvero può assumere valori con la virgola.
Cell invece è intera, ovvero le coord possono avere solo valori 1,2 ,3 ecc.
non avevo visto che aveva i valori float :-/
e meglio tenerle divise :-\
mmmmhhh.....
ragioniamoci bene perchè vedo il rischio di mischiare resposabilità.
Ah...ecco già un punto a sfavore.
Rectangle è continua, ovvero può assumere valori con la virgola.
Cell invece è intera, ovvero le coord possono avere solo valori 1,2 ,3 ecc.
http://bunkandrambling.com/images/blog/yagni060524c.png
Rectangle fa parte dell'Engine, non c'entra con la griglia. Ci serve solo estendere il concetto di Cell.
mmmmhhh.....
ragioniamoci bene perchè vedo il rischio di mischiare resposabilità.
Ah...ecco già un punto a sfavore.
Rectangle è continua, ovvero può assumere valori con la virgola.
Cell invece è intera, ovvero le coord possono avere solo valori 1,2 ,3 ecc.
ma rectangle ha valori interi :mumble:
Rectangle fa parte dell'Engine, non c'entra con la griglia. Ci serve solo estendere il concetto di Cell.
si ma è usata anche dentro a bigGem per gestire la grandezza della bigGem
provo introducendo la cell al posto del rectangle?
anzi ci ho gia provato ma becco un po di errori :(
..
ps. inizializzavo male l'oggetto, ora è tutto ok
gestendo la bigGem come droppable, all'inserimento di una gemma dentro una bigGem, la gemma che fine fa?
La togliamo da grid(al suo posto apparirà una bigGem), oppure la lasciamo e consideriamo la bigGem solo come un contenitore da usare in determinate situazioni?
Nella prima ipotesi, si potrebbero complicare la gestione delle adiacenze.
b
xxx
xxx
Se assegniamo la bigGem all'elemento della griglia corrispondente all'angolo sinistro della bigGem, allora quando b controlla cosa cè sotto di lui non troverà nulla.
Pero potremmo assengare la bigGem a tutti gli indici della matrice che occupa, ma poi nello scorrere la matrice incontreremmo piu volte la bigGem(potremo risolvere questo scorrendo non piu la matrice, ma una lista degli elementi della griglia. La matrice servirà solo per gestire le adiacenze).
Io tratterei per coerenza BigGem come un elemento della griglia, ed effettivamente risolverei il problema con una lista di oggetti nella griglia e non piu' una matrice.
Qual e' la tua opinione?
Il task 2 lo stiamo facendo io e Bonfo :P
Il task 2 lo stiamo facendo io e Bonfo :P
ah ok, avevo visto che era da riassegnare :doh:
Io tratterei per coerenza BigGem come un elemento della griglia, ed effettivamente risolverei il problema con una lista di oggetti nella griglia e non piu' una matrice.
Qual e' la tua opinione?
farei pure io cosi, ma terrei anche la matrice per sapere cosa cè vicino a una droppable(a meno che ci siano altre soluzioni a questo problema)
farei pure io cosi, ma terrei anche la matrice per sapere cosa cè vicino a una droppable(a meno che ci siano altre soluzioni a questo problema)
Hmmm... puzza di duplicazione.
Hmmm... puzza di duplicazione.
assolutamente, ma utile per sapere cosa sta a sx di una droppable :)
si potrebbe risolvere tenendo i riferimenti direttamente nella droppable, ma nasce il problema di tenerli aggiornati, e delle bigGem che devono poter avere n riferimenti.
certo si puo scorrere tutta la lista, ma puo capitare che venga passata molte volte, e in piu puo dar problemi con alcune funzioni che usano la ricorsione
Nessuna di queste soluzioni e' ideale.... hmmm
Nessuna di queste soluzioni e' ideale.... hmmm
Cosa intendete per collisioni??
Se si parla del metodi isCellBelowFull(Droppable)...sappiate che quello deve essere prima o poi modificato in isCellFull(Cell) ....e a quel punto bisogna vedere come Cell implementa l'equals dopo che avremo esteso il concetto di Cell anche per le BigGem.
La lista di oggetti pone il problema di scorrerla ogni volta.
Ma qui diventa un problema di ottimizzazione....ovvero avere una implementazione che ci permetta un accesso sequenziale (Lista) e uno diretto (Matrice)
Cosa intendete per collisioni??
Se si parla del metodi isCellBelowFull(Droppable)...sappiate che quello deve essere prima o poi modificato in isCellFull(Cell) ....e a quel punto bisogna vedere come Cell implementa l'equals dopo che avremo esteso il concetto di Cell anche per le BigGem.
La lista di oggetti pone il problema di scorrerla ogni volta.
Ma qui diventa un problema di ottimizzazione....ovvero avere una implementazione che ci permetta un accesso sequenziale (Lista) e uno diretto (Matrice)
i metodi per le crush da chest (e da flash), trovata una chest, controllano le gemme "intorno a loro" per poi far partire la cancellazione.
penso, ma non sono sicuro accada qualcosa di simile per le bigGem
Io farei con calma... Tanto per cominciare integriamo BigGem con l'interfaccia poi secondo me BigGem non deve essere più una collection di oggetti Gem ma bensì un unico oggetto con tutte le conseguenze del caso :)
probabilmente è un bug da refactoring in progress(ma i test danno verde :| ), cmq è buffissimo =D
ho formato una bigGem, ed è venuto fuori sto popo di gemmone =D
probabilmente è un bug da refactoring in progress(ma i test danno verde :| ), cmq è buffissimo =D
ho formato una bigGem, ed è venuto fuori sto popo di gemmone =D
Ahi :D
Che strano tral'altro per ora non mi pare di aver toccato niente di strano...
trovato l'errore :)
Per favore, mi aggiornate sulla situazione degli ultimi tre task?
Io e Ufo dovremmo finire il task 16.1.2 entro oggi.
Probabilmente risulterà fatto, senza neanche volere, parte, se non tutto, del task 16.1.3.
In ogni caso il codice era un po' messo male, molto male :(
Quindi sarebbe necessario capire se i refctoring sono sufficenti o se siamo solo alla punta dell'iceberg :D
Io e Ufo dovremmo finire il task 16.1.2 entro oggi.
Probabilmente risulterà fatto, senza neanche volere, parte, se non tutto, del task 16.1.3.
In ogni caso il codice era un po' messo male, molto male :(
Quindi sarebbe necessario capire se i refctoring sono sufficenti o se siamo solo alla punta dell'iceberg :D
Buon lavoro. Continuiamo anche nel prossimo Ciclo con i refactoring, il codice va sistemato.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.