View Full Version : [CICLO 6/bis] Xmas Carol Story 2
Visto che siete insaziabili, e avete già prenotato tutti i task disponibili, allora possiamo permetterci di introdurre anche una nuova storia, che ci porterà ancora più vicini ad una versione effettivamente giocabile. Questa storia è indipendente dalla precedente, quindi potrete prenotarvi per i task fin da subito.
Storia 2: Le gemme devono scendere a coppie di due, sebbene la loro caduta sia scollegata. Quella inizialmente in basso è la gemma primaria della coppia, quella inizialmente in alto è la secondaria. Premendo il tasto Z, la secondaria deve cambiare posizione ruotando (ma non su sè stessa, le png devono avere lo stesso aspetto) in senso antiorario intorno alla primaria. Premendo il tasto X, invece, la secondaria deve ruotare in senso orario. Se la casella di destinazione della gemma secondaria è già occupata, e la rotazione è impossibile, la gemma verrà automaticamente fatta ruotare ulteriormente nello stesso senso di rotazione, fino a trovare una casella libera in cui posizionarla. Gli effetti delle rotazioni sono descritti nello schema:
- secondaria sopra la primaria -> la secondaria andrà rispettivamente a sinistra o a destra della primaria
- secondaria a sx della primaria -> andrà rispettivamente sotto o sopra
- secondaria sotto la primaria -> andrà rispettivamente a destra o a sinistra
- secondaria a dx della primaria -> andrà rispettivamente sopra o sotto
Mediante il tasto C, la gemma secondaria dovrà ruotare di due posizioni.
Quando ognuna delle due gemme collide con qualche oggetto sottostante, l'altra - se non troverà nulla al di sotto - proseguirà indipendentemente la propria caduta. Il box Next continuerà a mostrare, senza incertezze, la coppia di gemme immediatamente successiva a quella attualmente in caduta (la nuova primaria in basso, la nuova secondaria in alto).
Punti cardine da tenere a mente durante i lavori:
Mai fare a gara a chi finisce il task per primo, meglio procedere con calma, altrimenti perderemo molto più tempo in seguito
Evitiamo di complicarci la vita, esiste di certo una soluzione più semplice di quella che abbiamo pensato di implementare
MAI aggiungere elementi non richiesti esplicitamente dai task: se mai serviranno, se ne parlerà nelle prossime storie
Comunichiamo il più possibile, se qualcosa non è chiaro discutiamone tutti i dettagli fino ad eliminare ogni dubbio, anche il più insignificante
Postare sempre la test list PRIMA di mettere mano al codice
Piccolo schema riassuntivo per le rotazioni:
http://lnx.rc6.it/diamonds/varie/rotaz.jpg
Ecco i task per questa nuova storia.
Task
Xmas.2.1: thebol + Ufo13: completato
GridControl deve ora creare due gemme. La prima si chiamera pivot e sara quella sotto controllo tramite input. La secondaria deve seguire i movimenti della prima.
Xmas.2.2: DanieleC88: completato
Intercettare la pressione del tasto Z e ruotare la gemma secondaria di 90° in senso orario attorno al pivot
Xmas.2.3: VICIUS: completato
Intercettare la pressione del tasto X e ruotare la gemma secondaria di 90° in senso anti-orario attorno al pivot
Xmas.2.4: VICIUS: completato
Intercettare la pressione del tasto C e ruotare la gemma secondaria di 180°.
Xmas.2.5: 71104: completato
Quando una delle due gemme collide entrambe perdono il controllo e quella ancora libera precipita verso la prima cella libera.
ciao ;)
prendo Xmas.2.4, 2 giorni dopo la fine del task 1 :)
DanieleC88
16-12-2005, 16:06
Il Xmas.2.2 è mio. :D
1 giorno, direi.
Prendo l'Xmas 2.1
tempo 2 giorni
vorrei il 5°, 2 giorni a partire da quando finisco il task del game over ^^'
(provo a finirlo adesso)
Ho fatto un corposo refactoring di GridController e InputReactor (cionci, e' quello di cui abbiamo parlato). Fate un bell'update prima di iniziare i vostri task.
Mi raccomando la test list.
testlist provvisoria:
test inserire 2 gemme in grid e posizione
test che la prima gemma inserita sia quella sottocontrollo(pivot) e nella posizione
1,4
test che la seconda gemma sia in 0,4
test che a un movimento della prima gemma, corrisponda un movimento analogo della seconda
naturalmente, varie ed eventuali
Lo scopo del task è generare 2 gemme e metterle sotto il controllo di grid.
Per fare questo, voglio pero aggiungere un test, per controllare che la queue dopo essere stata creata sia full
public void testFullAfterNew()
{
assertTrue("queue must be full",new GemQueue(Config.createForTesting()).isFull());
}
poi inserisco il test
public void testInsertTwoNewGem()
{
int oldNumberOfGems = grid.getNumberOfGems();
grid.insertTwoNewGem();
assertTrue("two gem are added", grid.getNumberOfGems() - 2 == oldNumberOfGems);
}
public void testPositionOfInsertTwoNewGem()
{
grid.insertTwoNewGem();
assertTrue("one jem at 0,4", grid.isGemAt(0, 4));
assertTrue("one jem at 1,4", grid.isGemAt(1, 4));
}
implemento:
public void insertTwoNewGem()
{
insertGem(1,4, gemGenerator.extract());
insertGem(0,4, gemGenerator.extract());
}
ora devo settare la prima come master, e la seconda come slave
devo introdurre un nuovo metodo che inserisca la gemma come slave(ho aggiunto la variabile gemSlave).
ma ancor prima devo creare e testare che la setGemSlave e getSlave
public void testGetGemSlave()
{
grid.setGemSlave(gem1);
assertSame("Wrong gem under control", gem1, grid.getGemSlave());
}
public void testGetgemSlaveIsNotInTheGrid()
{
try
{
grid.insertGem(0, 0, gem1);
grid.setGemSlave(Gem.createForTesting());
}
catch(IllegalArgumentException e2)
{
return;
}
fail("must throw if gem is not in the grid");
}
e
public Gem getGemSlave()
{
return gemSlave;
}
public void setGemSlave(Gem gem)
{
if(!gem.isAttachedToGrid())
{
throw new IllegalArgumentException();
}
gemSlave= gem;
}
introduco poi il metodo insertGemAsSlave(...)
poi inserisco il test
public void testInsertTwoNewGem()
{
int oldNumberOfGems = grid.getNumberOfGems();
grid.insertTwoNewGem();
assertTrue("two gem are added", grid.getNumberOfGems() - 2 == oldNumberOfGems);
}
Qui secondo me convine usare: assetEquals("...", oldNumberOfGems + 2, grid.getNumberOfGems())
in questo modo è molto piu chiaro quello che vuoi testare.
ciao ;)
A questo punto per la insertGemAsSlave devo testare:
che inserisca la gemma in grid, che dove la inserisca non ci siano altre gemme, etc
Pero primi mi rendo conto che insertGemAsSlave fa praticamente tutto il lavoro di insertGem, ma invece di chiamare alla fine setGemUnderControl(gem);
chiamerà setGemSlave(gem);
per questo, prima di implementare insertGemSlave, faccio un po di refactoring.
tolgo la setGemUnderCOntrol(gem) da insertGem (rendendola piu generica) e la sposto nella
insertNewGem che diventa
public void insertNewGem()
{
Gem gem1 = gemGenerator.extract();
insertGemIntoColumn(4, gem1);
setGemUnderControl(gem1);
}
si sarebbe potuto creare un metodo insertGemUnderControl, ma per adesso penso vada bene cosi.
la insertNewGem() diventa percio
Gem gem1 = gemGenerator.extract();
insertGemIntoColumn(4, gem1);
setGemUnderControl(gem1);
la build cosi è molto rotta, perche in molti test(nel codice forse no, il gioco sembra andare bene) la insertGem e stata usata presupponendo che mettesse anche la gemma sotto controllo.
percui, rifaccio lo stesso refactoring ma in un altra maniera ;)
prima rinomino insertGem in insertGemUnderControl, e poi ci estraggo tutto il codice tranne l'ultim riga e rinomino il metodo insertGem.
Alla fine la insertGemUnderControl è venuta fuori =D. Si potrebbe fare un po di refactoring sui test per vedere dove andrebbe usate insertGem invece che insertGemUnderControl(la ex insertGem), ma si puo fare in futuro.
[la nuova funzione insertGem e testata implicitamente da tutti i test che testano insertGemUnderControl, percui escluso il discorso di prima, non cè bisogno di toccare i test]
a questo punto posso aggiungere
public void testInsertGemAsSlave(){
grid.insertGemAsSlave(0, 0, gem1);
assertSame("Wrong gem slave", gem1, grid.getGemSlave());
}
con relativa implementazione
public void insertGemAsSlave(int row, int column, Gem gem)
{
insertGem(row, column, gem);
setGemSlave(gem);
}
Qui secondo me convine usare: assetEquals("...", oldNumberOfGems + 2, grid.getNumberOfGems())
in questo modo è molto piu chiaro quello che vuoi testare.
ciao ;)
fatto;)
dopo questa modifica insertTwoNewGem() diventa
public void insertTwoNewGem()
{
insertGemUnderControl(1,4, gemGenerator.extract());
insertGemAsSlave(0,4, gemGenerator.extract());
}
e posso testare il fatto che
public void testInsertTwoNewGem()
{
int oldNumberOfGems = grid.getNumberOfGems();
grid.insertTwoNewGem();
assertEquals("two gem are added", oldNumberOfGems +2, grid.getNumberOfGems());
assertNotNull("Gem under control is null", grid.getGemUnderControl());
assertNotNull("Gem slave is null", grid.getGemSlave());
}
(Avrei dovuto fare il contrario, sorry :\ )
ora manca il test per il movimento simultaneo della gemmaPivot e per la slave
mi verrebbe da testare che a ogni movimento le posizioni relative rimangano costanti, ma se a qualcuno viene un idea migliore, forse e meglio ;)
inizio testando che la seconda gemma cada per la gravita
public void testTwoGemIsMovingWhenLowerCellIsEmpty()
{
grid.insertGemUnderControl(1, 4, gem1);
grid.insertGemAsSlave(0,4,gem2);
//grid.setGemUnderControl(gem1);
grid.setGravity(1.0f);
float oldPositionPivot = gem1.getY();
float oldPositionSlave = gem2.getY();
grid.update(new MockTimer());
assertEquals("Gem Pivot is not moving when cell under current position is empty",
oldPositionPivot + 1.0f, gem1.getY(), 0.0001f);
assertEquals("Gem Slave is not moving when cell under current position is empty",
oldPositionSlave + 1.0f, gem2.getY(), 0.0001f);
}
modificando il metodo update di grid
public void update(AbstractTimer timer)
{
updateGemAnimations(timer);
if(getGemUnderControl() == null)
{
return;
}
if(gemCantMoveDown(getGemUnderControl()))
{
alignGemToCellUpperBound(getGemUnderControl());
getGemUnderControl().dropGem();
if(gemIsSurroundedBySameType(getGemUnderControl()))
{
getGemUnderControl().useBrighterImage();
}
}
else
{
moveGem(getGemUnderControl());
if (getGemSlave() == null){
return;
}
moveGem(getGemSlave());
}
}
Cosi facendo, tutti i test passano e posso andare avanti.
[NB, con questa implementazione ci puo essere un bug se girando le gemme, quella piu in basso risulta la slave. Ma mi sembra che questa cosa vada risolta col 4 task, percui se non ricevo altre informazioni, questo caso non sarà coperto in questo task]
questo test compre anche il caso della pressione del tasto down, che presuppone un aumento
del fattore gravity
Ora ce da testare che se spingo lefkey, entrambe le gemme si spostino(andra poi fatto uguale per rightkey)
public void testTwoGemMoveLeft()
{
grid.insertGemUnderControl(1, 4, gem1);
grid.insertGemAsSlave(0, 4, gem2);
input.generateKey(KeyCode.vk_Left, timer.getTime());
inputReactor.reactToInput();
assertEquals("Gem pivot didnt move to the left", grid.getGemAt(1, 3), gem1);
assertEquals("Gem slave didnt move to the left", grid.getGemAt(0, 3), gem2);
}
per farlo passare, basta andare nella classe LeftKeyHandler e modificare executeWhenPressed
public void executeWhenPressed(InputReactor inputReactor)
{
KeyEventHandler rightHandler = inputReactor.getKeyHandler(KeyCode.vk_Right);
if(!rightHandler.wasRepeated()
&& !rightHandler.hasBeenRepeated(
inputReactor.getLastInputTimeStamp()))
{
if(this.grid.getGemUnderControl() != null)
{
this.grid.moveGemLeft(this.grid.getGemUnderControl());
}
if(this.grid.getGemSlave() != null)
{
this.grid.moveGemLeft(this.grid.getGemSlave());
}
}
}
analogo per il moveRight
^TiGeRShArK^
17-12-2005, 22:53
non ci posso credereeee!!!
mi avete lasciato il 2.3!!! :D
sono commosso!!! :cry:
non ci speravo proprio che dei lupi famelici come voi mi lasciassero qualcosa....
VICIUUUUSSSS:..
prenotami prima che se lo mangi qualcunoooo!!!!!!
tempo stimato ....... se il pc a torino non si è autodistrutto direi 2 giorni.... :Prrr:
ho una domanda da fare.
i test per il movimento, non è propriamente corretto, nel senso che se le 2 gemme sono messe in orizzontale (2,1)(2,0) puo non funzionare.
Questa e pero una casistica compresa nel mio task?
in teoria no, visto che non è ancora possibile farle girare...
percui introddurre questo test e andare fuori task o no?
ho una domanda da fare.
i test per il movimento, non è propriamente corretto, nel senso che se le 2 gemme sono messe in orizzontale (2,1)(2,0) puo non funzionare.
Questa e pero una casistica compresa nel mio task?
in teoria no, visto che non è ancora possibile farle girare...
percui introddurre questo test e andare fuori task o no?
Non hai tutti i torti, in effetti ci starebbe bene un sesto task, per definire il comportamento anche nei casi di posizionamenti relativi differenti.
Quando vedo Vicius su MSN vedremo di elaborarlo e di postarlo. Poi, se nessuno si prenota, allora sarà tuo di diritto :Prrr:
Sinceramente io avrei visto benissimo una classe GemsPair derivata da Gem con una istanza della gemma slave all'interno...
Continuando così si rende Grid troppo complicato...magari avrebbe dovuto essere il task Xmas.2.0...
Sinceramente io avrei visto benissimo una classe GemsPair derivata da Gem con una istanza della gemma slave all'interno...
Continuando così si rende Grid troppo complicato...magari avrebbe dovuto essere il task Xmas.2.0...
Sono d'accordissimo sul GemsPair che renderebbe il tutto mooolto più facile da gestire, però non capisco perchè deve derivare da Gem...
Non è detto, ma mi sembrava logico perchè dovrebbe erditarne non solo l'interfaccia, ma anche gran parte del codice... Inoltre in questo modo Grid non andrabbe modificata nemmeno di una virgola (anzi, qualcosa sì, ma solo per le collisioni)...
Sinceramente io avrei visto benissimo una classe GemsPair derivata da Gem con una istanza della gemma slave all'interno...
Continuando così si rende Grid troppo complicato...magari avrebbe dovuto essere il task Xmas.2.0...
"Prefer Composition over Inheritance"
GemsPair "non e' un" Gem. Quindi non deve derivare da Gem.
Sì, ma allora deriviamo PivotGem da Gem...e poi a PivotGem gli passaimo la gemma slave... Cambia il nome, ma il succo è lo stesso...mi sembra che sia necessario ottenere una classe di questo tipo prima di cominciare a lavorare sulle coppie di gemme...
Sì, ma allora deriviamo PivotGem da Gem...e poi a PivotGem gli passaimo la gemma slave... Cambia il nome, ma il succo è lo stesso...mi sembra che sia necessario ottenere una classe di questo tipo prima di cominciare a lavorare sulle coppie di gemme...
Perche' vuoi derivare? Questa classe contiene due gemme, una e' il pivot, l'altra lo slave. E tiene traccia delle due gemme. Secondo me non c'e' bisogno di derivare.
Boh io farei un GemsPair che estende Sprite e contiene due Gem
Boh io farei un GemsPair che estende Sprite e contiene due Gem
GemsPair "non e' un" Sprite.
http://www.eventhelix.com/RealtimeMantra/Object_Oriented/liskov_substitution_principle.htm
The Liskov Substitution Principle of object oriented design states:
In class hierarchies, it should be possible to treat a specialized object as if it were a base class object.
The basic idea here is very simple. All code operating with a pointer or reference to the base class should be completely transparent to the type of the inherited object. It should be possible to substitute an object of one type with another within the same class hierarchy. Inheriting classes should not perform any actions that will invalidate the assumptions made by the base class.
Ogni volta che derivate una classe da un'altra dovete porvi la domanda se il principio di sostituzione si applica. Una specializzazione di un Handler puo' ovviamente essere usata in sostituzione della classe base, mentre un GemsPair no: svolge azioni che invalidano le assuzioni fatte dalla classe base Sprite (infatti contiene due sprite e non uno solo).
hmmmm mi chiedo perchè no?
ahhhh ritiro subito la domanda :D
Volevo dire drawable :D
Ecco l'articolo completo:
http://www.objectmentor.com/resources/articles/lsp.pdf
Nel nostro caso, una funzione che usasse un GemsPair come se fosse uno Sprite, fallirebbe clamorosamente, perche' deve poter sapere di avere a che fare con GemsPair per onorarne il contratto.
E secondo me non e' neanche un Drawable :)
Le gemme sono disegnate dalla griglia, GemsPair deve solo controllare che scendano in maniera corretta e rispondano agl'input dell'utente.
mazza che figo sto sito :o
allora perdonami ho scritto senza guardare il codice... In realtà estendendo sprite saprei bene come gestire la cosa...
Secondo me basta tenere 2 Gems e poi implementare Drawable che diciamo esegue il draw delle due Gem nelle corrette posizioni.
Boh io farei un GemsPair che estende Sprite e contiene due Gem
Non sono d'accordo...a quel punto andrebbe estratta anche l'interfaccia di Gem...ed andrebbe poi implementata in GemsPair...
fek: ti spiego perchè voglio derivare... Così come è adesso Grid tutte le operazioni che adesso svolgiamo su Grid andrebbero duplicate... Invece non duplicando queste operazioni e derivando PivotGem da Gem potremmo settare la gemma slave dall'esterno (pivotGem.setSlaveGem(Gem slave)) e mantenendo la struttura attuale di Grid potremmo replicare le operazioni fatte sulla pivotGem all'interno della pivotGem...
Ad esempio:
public void moveRight(float step)
{
super.moveRight(step);
slave.moveRight(step);
}
Eriditare PivotGem è necessario per permettere a Grid di poter lavorare ancora tramite Gem (ad esempio il membro grid rimarrebbe una matrice di Gem)...anche perchè senza dubbio dovremmo ancora poter lavorare sulla gemma singola...
fek: ti spiego perchè voglio derivare... Così come è adesso Grid tutte le operazioni che adesso svolgiamo su Grid andrebbero duplicate... Invece non duplicando queste operazioni e derivando PivotGem da Gem potremmo settare la gemma slave dall'esterno (pivotGem.setSlaveGem(Gem slave)) e mantenendo la struttura attuale di Grid potremmo replicare le operazioni fatte sulla pivotGem all'interno della pivotGem...
Questo e' un'errore abbastanza classico, tanto che ci sto combattendo anche in ufficio. Non si deriva per riutilizzare il codice (eliminare la duplicazione nel tuo caso), ma si deriva sempre e solo per modellare relazioni ISA.
Noi sappiamo programmare quindi seguiamo questo principio ;)
GemsPair, come la giri, non modella una relazione ISA ne' con Gem, ne' con Sprite, ne' con Drawable. E' una semplice classe di controllo di due gemme, un classico esempio di Composizione. E quello implementiamo. Tutto il resto e' un forzare il design verso qualcosa che ci creera' problemi, quindi andiamo per le cose semplici.
Due gemme dentro GemsPair e via.
Cionci: sì scusa, leggi il mio post... Mi ero sbagliato... Avevo solo pensato al Draw e così ho pensato "sprite" senza tenere a mente tutto quello che Sprite comportava :)
Comunque non vedo perchè usare GemsPair in composition dovrebbe limitarci così tanto... Secondo me si può trovare una soluzione semplice anche per quello :)
Questo e' un'errore abbastanza classico, tanto che ci sto combattendo anche in ufficio. Non si deriva per riutilizzare il codice (eliminare la duplicazione nel tuo caso), ma si deriva sempre e solo per modellare relazioni ISA.
Noi sappiamo programmare quindi seguiamo questo principio ;)
GemsPair, come la giri, non modella una relazione ISA ne' con Gem, ne' con Sprite, ne' con Drawable. E' una semplice classe di controllo di due gemme, un classico esempio di Composizione. E quello implementiamo. Tutto il resto e' un forzare il design verso qualcosa che ci creera' problemi, quindi andiamo per le cose semplici.
Due gemme dentro GemsPair e via.
Hmmm forse ho capito come si può fare... Se mettete il task mi offrirei a farlo in pair programming con qualcuno :p
Comunque non vedo perchè usare GemsPair in composition dovrebbe limitarci così tanto... Secondo me si può trovare una soluzione semplice anche per quello :)
Semplicemente perchè andrebbe modificata tutta Grid...ma bisognerebbe comunque mantenere la possibilità di gestire una gemma singola...quindi verrebbe un macello enorme...
Questo e' un'errore abbastanza classico, tanto che ci sto combattendo anche in ufficio. Non si deriva per riutilizzare il codice (eliminare la duplicazione nel tuo caso), ma si deriva sempre e solo per modellare relazioni ISA.
Noi sappiamo programmare quindi seguiamo questo principio ;)
GemsPair, come la giri, non modella una relazione ISA ne' con Gem, ne' con Sprite, ne' con Drawable. E' una semplice classe di controllo di due gemme, un classico esempio di Composizione. E quello implementiamo. Tutto il resto e' un forzare il design verso qualcosa che ci creera' problemi, quindi andiamo per le cose semplici.
Due gemme dentro GemsPair e via.
Io no la vedo come GemsPair...io la vedo come PivotGem... PivotGem ha senso derivarla da Gem... PivotGem è la gemma che controlla la slave, quindi ha senso che pivotGem se viene mossa muova anche la gemma slave... Io non ci vedo niente di forzato...
Semplicemente perchè andrebbe modificata tutta Grid...ma bisognerebbe comunque mantenere la possibilità di gestire una gemma singola...quindi verrebbe un macello enorme...
ma non è vero... io penso che bastino poche modifiche :p
Io no la vedo come GemsPair...io la vedo come PivotGem... PivotGem ha senso derivarla da Gem... PivotGem è la gemma che controlla la slave, quindi ha senso che pivotGem se viene mossa muova anche la gemma slave... Io non ci vedo niente di forzato...
Secondo me non serve neppure derivare PivotGem. Esci dal loop in cui ti sei infilato, questo task e' molto piu' semplice di quanto pensi. Fallo in PP con Ufo e fatelo sulla linea di guida di non derivare nulla. Non serve.
hmmm mi va benissimo farlo in pair con cionci ed inizierei anche subito, ma non è meglio se aspettiamo che vicius confermi il task? :p
allora, la duplicazione era evidente, ma per ora preferivo mantenerla, fare funzionare il tutto(creazione, movimenti ed eventualmente collisioni) per poi proporlo.
D'accordo su fare la classe gemspair come composizione, e se la si implemente considerando la possibilita che controlli una sola gemma(la pivot) il codice non dovrebbe risentirne troppo.
Si puo considerare di estrarre l'interfaccia da gem, generare la classe composite come un proxy di 2 gem, ma non so se ne vale la pena
in effetti gempair si comporta come una gemma(forse) ma non è una gemma...
cmq ditemi se devo testare tutte le collisioni, o questo compito passa a un prox task(magari con in mezzo il refactoring di pairGem). Cosi tolgo il test per le collisioni gia realizzato e implemento correttamente il movimento(i test precedenti secondo me non sono completi, devo creare un altro test per verificare...), e aggiungo l'init e il rilascio di 2 gem alla volta(ma per questo devo implementare per forza la collisione dal basso...)
Secondo me non serve neppure derivare PivotGem. Esci dal loop in cui ti sei infilato, questo task e' molto piu' semplice di quanto pensi. Fallo in PP con Ufo e fatelo sulla linea di guida di non derivare nulla. Non serve.
io che faccio rilascio parte del task, loro fanno il task poi io adatto il mio?
io che faccio rilascio parte del task, loro fanno il task poi io adatto il mio?
Finisci il tuo task, loro partono col refactoring del tuo task e poi implementano il loro.
hmmm mi va benissimo farlo in pair con cionci ed inizierei anche subito, ma non è meglio se aspettiamo che vicius confermi il task? :p
Dopo un veloce consulto con fek, direi che potete iniziare anche subito ;)
I limiti del task sono chiari?
A sto punto credo che io e cionci dovremmo semplicemente implementare la classe GemsPair e thebol i controlli su di essa (collisioni e movimenti, ovviamente rotazioni escluse)
cionci se confermi iniziamo :)
Allora ridefinisco i limiti del mio task
-inserimento di 2 gemme(DO)
-gravità su entrambe le gemme(DO)(in configurazione pivot[1,4] slave[0,4])
-funzionamento downkey(venuto gratis dal sottotask precedente)(DO)
-Movimento di entrambe le gemme a sx e dx (in configurazione pivot[1,4] slave[0,4])(DO)
-Collisione a sx a dx e in basso (in configurazione pivot[1,4] slave[0,4])(TODO)
-init del gioco con 2 gemme e creazione di 2 gemme quando raggiungono il fondo(TODO)
Se volete ovviamente gestisco tutte le collisioni e i movimenti ;), ma dopo il refactoring del gempair magari è meglio
hmmm aspetto qualcuno che si confermi per il pair e parto subito :)
nessuno? :p
Non posso farlo in pair programming, sono occupato in questi giorni...
E ora le collisioni...
public void testMoveTwoGemLeftWithCollisionOfEach()
{
grid.insertGemUnderControl(1, 0, gem1);
grid.insertGemAsSlave(2,0,gem2);
input.generateKey(KeyCode.vk_Left, timer.getTime());
inputReactor.reactToInput();
assertEquals("Gem pivot must not move to the left", grid.getGemAt(1, 0), gem1);
assertEquals("Gem slave must not move to the left", grid.getGemAt(2, 0), gem2);
}
e relativo per desta.
public void testMoveTwoGemRightWithCollisionOfEach()
{
grid.insertGemUnderControl(1, GRID_COLUMNS - 1, gem1);
grid.insertGemAsSlave(2, GRID_COLUMNS - 1, gem2);
input.generateKey(KeyCode.vk_Right, timer.getTime());
inputReactor.reactToInput();
assertEquals("Gem pivot must not move to the right", grid.getGemAt(1, GRID_COLUMNS - 1), gem1);
assertEquals("Gem slave must not move to the right", grid.getGemAt(2, GRID_COLUMNS - 1), gem2);
}
I test passano senza modifiche, dato il fatto che le gemme sono incolonnate(in altre configurazioni probabilmente non sara cosi).
e ora la collisione in basso (aka bloccare le gemme dalla caduta per gravita)
public void testTwoGemIsNotFalling()
{
grid.insertGemUnderControl(GRID_ROWS - 1, 0, gem1);
grid.insertGemAsSlave(GRID_ROWS - 2, 0, gem2);
grid.update();
assertTrue(gem1.isNotFalling());
assertTrue(gem2.isNotFalling());
}
questo fallisce \o/ ma modificando la update di grid
if(gemCantMoveDown(getGemUnderControl()))
{
[...]
if (getGemSlave() != null){
getGemSlave().dropGem();
}
}
[NB manca l'align e il bright, lo faccio io o famo in un altro task?]
build verde :) ora si passa all'inserimento all'inizio delle 2 gemme, e durante il gioco :)
beh appena si offre qualcuno parto (fek? :D)... Sennò posso anche farlo non in pair
a questo punto, si potrebbe incominciare a metter insertTwoNewGem(); al posto di insertNewGem nel costruttore di grid.
public void testTwoGemInsertion()
{
assertNotNull("no gem Pivot inserted in grid after creation",
grid.getGemUnderControl());
assertNotNull("no gem Slave inserted in grid after creation",
grid.getGemSlave());
}
e implementazione
public Grid(Rectangle bounds, Config config, GemGenerator gemGenerator)
{
[...]
//insertNewGem();
insertTwoNewGem();
}
Ma questo rompe assai la build, ma basta cambiare il createForTesting di grid in maniera che rimuova anche la gemma slave da grid e torna ad andare tutto :)
public static Grid createForTesting(GemGenerator gemGenerator)
{
Grid grid = new Grid(new Rectangle(40, 40, 295, 487), Config
.createForTesting(), gemGenerator);
grid.removeGemFromGrid(grid.getGemUnderControl());
grid.removeGemFromGrid(grid.getGemSlave());
grid.gemUnderControl = null;
grid.gemSlave = null;
grid.empty = true;
return grid;
}
ora manca che a quando le gemme raggiungono il fondo, vengano create 2 gemme invece che 1
public void testTwoNewGemInsertion()
{
grid.insertGemUnderControl(13, 4, gem1);
grid.insertGemAsSlave(12,4,gem2);
controller.update(timer);
assertNotNull(grid.getGemUnderControl());
assertTrue(gem1 != grid.getGemUnderControl());
assertNotNull(grid.getGemSlave());
assertTrue(gem2 != grid.getGemSlave());
}
e implementazione
private void handleWaitState(AbstractTimer timer)
{
if(timer.getTime() - timeBase >= delay)
{
if(isGameOver())
{
return;
}
//grid.insertNewGem();
grid.insertTwoNewGem();
waitState = false;
}
}
questo rompe da problemi a testAfterSecondDelay, ma basta spostare il piazzamento della gemma in 12,4(quello previsto dall'init) e tutto ridiventa verde
controller.setDelay(300);
grid.insertGemUnderControl(12, 4, gem1);
controller.update(timer);
[...]
Secondo me Grid non deve sapere dell'esistenza di due gemme sotto controllo. Questo concetto deve essere esclusiva di GridControl. In altre parole vi avevo chiesto di non mettere nulla in Grid che non fosse strettamente necessario e questo non mi sembra il caso. Voglio essere molto draconiano su questo punto.
Secondo me Grid non deve sapere dell'esistenza di due gemme sotto controllo. Questo concetto deve essere esclusiva di GridControl. In altre parole vi avevo chiesto di non mettere nulla in Grid che non fosse strettamente necessario e questo non mi sembra il caso. Voglio essere molto draconiano su questo punto.
ti giuro che avevo fatto lo stesso pensiero.
solo che essendo la gemundercontrol in grid, ho preferito mantenere per ora il fatto delle 2 gemme in grid, aspettando(e proponendo) di spostare le gemme controllate in gridcontroll per il refactoring di gemPairs
grid deve essere solo una griglia dove inserire gemme, e che dia responsi se una gemma e spostabile o no, etc.
ora aggiungo un test per verificare che anche la seconda gemma contribuisca al brighten, poi faccio merg e committo il tutto.
Prima di fare il commit puoi togliere il concetto di coppia di gemme da Grid?
A proposito di Grid e Gem... Secondo me la classe Cell non dovrebbe stare dentro Gem...
Prima di fare il commit puoi togliere il concetto di coppia di gemme da Grid?
ok, tolgo proprio gemundercontrol e gemslave e le sposto(con relative logiche) in gridcontroll.
speriamo sia abbastanza indolore :O
A proposito di Grid e Gem... Secondo me la classe Cell non dovrebbe stare dentro Gem...
Secondo me sì... Prima era in Grid ed in pratica mettendola dentro Gem abbiamo eliminato una grande quantità di codice (ad esempio un funzione chiamata findGemCell che trovava la posizione di una Gem all'interno di grid scorrendo tutta la matrice)...
Inoltre il fatto che stia dentro Gem è logicamente corretto: una Gem sta in una data posizione e Cell (magari il nome non è il massimo) ne indica la posizione...
Sono d'accordissimo che la gemma ha una posizione dentro la griglia però, a parer mio, il concetto di Cell (vista come elemento di Grid) ed il concetto di Gemma sono abbastanza separati da giustificare l'indipendenza della classe Cell (e non un oggetto Cell) da Gem...
Se proprio non vi piace la classe Cell separata... Perchè non spostarne la dichiarazione dentro Grid invece che dentro Gem?
Se proprio non vi piace la classe Cell separata... Perchè non spostarne la dichiarazione dentro Grid invece che dentro Gem?
Era già dentro Grid...spostarla in Gem ha semplificato notevolmente il design... Magari come dicevo si potrebbe rinominare...
Secondo me il design ne è compromesso... Anche rinominandola continui ad avere dentro la classe Gem una classe che non c'entra con Gem...
Puoi benissimo tenere Cell in Grid e lasciare tutto com'è :)
cambia una sola riga in Gem.java:
private Cell cell;
diventa:
private Grid.Cell cell;
No, ok bisogna cambiare più di una riga perchè la classe Cell non ha i getter e setter...
Ah... addirittura ha solo i getter che non vengono mai utilizzati... Scusa ma per tenere una classe a mo di struct senza nemmeno utilizzare getter e setter methods tanto vale tenere 2 interi con la posizione nella griglia...
^TiGeRShArK^
18-12-2005, 18:25
ehm...
è normale???
:confused:
test:
[junit] Testsuite: it.diamonds.tests.TestBackground
[junit] Tests run: 4, Failures: 0, Errors: 1, Time elapsed: 2,564 sec
[junit] Testcase: testDraw(it.diamonds.tests.TestBackground): Caused a
n ERROR
[junit] it.diamonds.Background.draw(Lit/diamonds/engine/AbstractEngine;)V
[junit] java.lang.NoSuchMethodError: it.diamonds.Background.draw(Lit/diamond
s/engine/AbstractEngine;)V
[junit] at it.diamonds.tests.TestBackground.testDraw(TestBackground.java
:48)
BUILD FAILED
questo dopo aver fatto l'update alla version 880....
Io ho la 880 e non ho problemi :)
^TiGeRShArK^
18-12-2005, 18:50
mah...
ora mi passano....
misteri di ant... :confused:
sta venendo fuori un refactoring molto grosso, ho dovuto rendere pubblici alcuni metodi precedentemente privati di grid [moveGem(), updateGemAnimations(), gemCantMoveDown()]
inoltre quasi tutti i test che usavano grid per inserire gemme, etc ora useranno grid controll. Stessa cosa per le update.
Ho quasi finito, mi risulta un po ostica la create di grid e la createForTesting che ci dovro guardare un po meglio, ma conto di finire in serata.
Ho un problema con MoveRightCommandHandler.
questo ha ora bisogno di gridController per ottenere gemUndercontrol e slave.
Da gridController posso arrivare a grid, e questo non crea problemi.
Ma, la loro creazione è affidata a un metodo statico in gridController aka createInputReactor, a cui non posso passare un riferimento a gridController in quanto metodo statico.
per cui io vedo 2 soluzioni.
-rendere non statica la createInputReactor in modo da potergli passare il puntatore a this(con svariati problemi per i test).
-passare a reactToInput anche la gemma(e in futuro gemsPair)
altre idee?
ufo13 suggerisce un idea interessante:
gridController non conterra piu inputReactor, ma il contrario.
La classe game a questo punto conterra un inputReactor.
La catena Game->inputReactor->gridController->Grid suona bene.
Procedo cosi se nessuno ha qualcosa in contrario.
e alla fine ce l'ho fatta...
per spostare le 2 gemme da grid a gridcontroll alla fine e venuto fuori un gran refactoring...
spero piaccia.
ps.
questo test non ha piu senso perche non cè piu la update in grid, e l'ho tolto
(per ora e commentato)
public void testGridDoesntInsertNewGems()
{
gridController.insertGemUnderControl(13, 4, gem1);
gridController.update();
assertEquals(gem1, gridController.getGemUnderControl());
}
ora faccio commit
Volevo ricordare diversi punti:
1) il codice NON deve contenere commenti e soprattutto NON deve contenere codice commentato
2) prima di fare il commit bisogna eseguire la build in locale con ant, gli errori di formattazione vanno corretti altrimenti la build resta rotta
3) la classe InputReactor non deve contere la dichiarazione degli handle, deve essere GridController a dichiarare gli handle per i vari tasti
4) una istanza di InputReactor deve essere contenuta in GridController, non viceversa
Quindi i credo che vada fatto un revert...poi a fek la parola...
fek: credo che serva una wiki per le varie classi altrimenti tutte le volte si fanno modifche al design, poi la volta dopo vengono disfatte, poi rifatte ed ancora disfatte... IMHO bisogna mettere in chiaro le motivazioni che portano a scelte di design (come ad esempio i punti 3 e 4 esplicitati sopra), quindi prima di procedere a modifiche del design delle classi bisogna leggere e motivare le modifiche...
http://www.answers.com/main/ntquery?method=4&dsid=2222&dekey=Comparison+of+wiki+software&gwp=8&curtab=2222_1
vic: forse ti sei scordato di riaggiungere testConfig.java ? Ora non c'è nel repository...
Volevo ricordare diversi punti:
1) il codice NON deve contenere commenti e soprattutto NON deve contenere codice commentato
errore mio, ma dato il la pesantezza delle modificche ho preferito lasciare qualcosa(e alle 2 di notte mi sono dimenticato di dare una controllata
2) prima di fare il commit bisogna eseguire la build in locale con ant, gli errori di formattazione vanno corretti altrimenti la build resta rotta
erroraccio mio, usavo junit di eclipse a manetta e mi sono dimenticato di far girare la build di ant...scusate
3) la classe InputReactor non deve contere la dichiarazione degli handle, deve essere GridController a dichiarare gli handle per i vari tasti
questo e fattibile anche con la nuova implementazione, basta fare un metodo in gridcontroller che restituisca un array di handler, e che questo venga chiamato da inputArray
4) una istanza di InputReactor deve essere contenuta in GridController, non viceversa
ho dichiarato la scelta alle 21, nessuno ha detto nulla e ho proseguito.
Certo forse potevo motivare un po meglio, ma ho spiegato il perche di questa scelta(venuta in qualche modo naturale col refactoring chiesto da fek)
una cosa prima di revertare.
La build ora e rotta per l'errore mio di non aver fatto girare la build di ant....
pero gli unici errori sono in checkstyle, io sul mio worlspace li ho corretti(parentesi, tab, etc) e la build passa. Li committerei anche, ma non so se questo renderebbe piu difficile il revert per cui aspetto fino alle 8:30 che qualcuno dia l'ok, poi al massimo guardateci voi.
Gli errori di stile li ho già corretti io ieri sera... Non capisco come mai la build sia ancora rotta... Sembra che non trovi una immagine...back000 che comunque è nel repository...
Riguardo alla modifica che avevi dichiarato alle 21...è chiaro che tu abbia proseguito... E' per evitare questi problemi che chiedevo a fek una wiki per tenere conto di queste cose ;)
Comunque per evitare di dover fare le modifiche che sono state fatte a InputReactor e GridController basterebbe passare GridController invece di Grid al costruttore dei tasti... A quel punto fai 3 metodi in GridController: getPivotGem, getSlaveGem, getGrid...
secondo me è anche più corretto passare gridController invece che Grid agli handler...
EDIT: per favore leggete il thread dei problemi...
Questo perchè se una gemma isNotFalling anche l'altra lo deve diventare...
è proprio la coppia di gemme che non deve potersi separare a meno che una delle 2 non si depositi.
è proprio la coppia di gemme che non deve potersi separare a meno che una delle 2 non si depositi.
Sicuramente aiuterebbe molto GemsPair...
D'accordissimo... Io inizierei anche subito il refactoring però vorrei sapere se fek ha intenzione di revertare le modifiche di thebol o meno
cdimauro
19-12-2005, 14:33
Xmas.2.3 potrei prenderlo io. Tempo previsto: 2 giornid a quando finisce Xmas.2.1.
Gli errori di stile li ho già corretti io ieri sera... Non capisco come mai la build sia ancora rotta... Sembra che non trovi una immagine...back000 che comunque è nel repository...
Riguardo alla modifica che avevi dichiarato alle 21...è chiaro che tu abbia proseguito... E' per evitare questi problemi che chiedevo a fek una wiki per tenere conto di queste cose ;)
Ho messo su un paio di wiki sul server, ma sono entrambi piuttosto scomodi da usare. Appena torno in UK e mi trasferisco nella casa nuova, rimetto mano al server e troviamo una soluzione a questo problema.
Riguardo al commit: dopo aver letto tutti i commenti di cionci, piuttosto che aggiustare il codice perferisco si faccia un bel revert e si riparta daccapo. Si fa molto prima e si evitano problemi.
E poi, visto che questo task sta gia' creando molti problemi, fatelo in Pair Programming per favore.
errore mio, ma dato il la pesantezza delle modificche ho preferito lasciare qualcosa(e alle 2 di notte mi sono dimenticato di dare una controllata
Ho imparato personalmente nel modo peggiore che non si fa per nessun motivo un commit alle 2 di notte :)
ho dichiarato la scelta alle 21, nessuno ha detto nulla e ho proseguito.
Certo forse potevo motivare un po meglio, ma ho spiegato il perche di questa scelta(venuta in qualche modo naturale col refactoring chiesto da fek)
Colpa mia che non avevo chiarito questo punto a sufficienza: InputReactor non deve conoscere per alcun motivo le classi che fanno parte del gioco. Si sta configurando un'architettura dove InputReactor e' un servizio fornito dall'Engine agli strati superiori (il Gioco) e come tale c'e' comunicazione sempre e solo a salire, ma non a scendere.
allora reverta che ripartiamo in pair :)
allora reverta che ripartiamo in pair :)
Io non posso, a mala pena sono collegato a internet qui, sono in Italia :)
dei file che avevo cambiato ho tirato su la versione precedente, se volete committo il revert(o ce un altra maniera per farlo?).
Sicuramente c'è un altro modo, ma non ho mai capito come si fa...
Provo un po'...
Ufo13 e thebol: allora lo fate voi in pair programming questo task ?
Fatto il revert...però nel metodo rozzo :)
posso mercoledi sera, se avete fretta passo volentieri la mano :)
Cionci se ti offri te bene, altrimenti se vi va bene facciamo con thebol mercoledì oppure intanto faccio di refactoring per GemsPair poi si vede
^TiGeRShArK^
19-12-2005, 22:12
Xmas.2.3 potrei prenderlo io. Tempo previsto: 2 giornid a quando finisce Xmas.2.1.
:fiufiu:
http://www.hwupgrade.it/forum/showpost.php?p=10596042&postcount=16
cmq mi sa ke te lo devo lasciare...
in questi giorni ci sono delle scadenze e arrivo a casa troppo distrutto per mettermi a programmare.....
:muro:
Cionci se ti offri te bene, altrimenti se vi va bene facciamo con thebol mercoledì oppure intanto faccio di refactoring per GemsPair poi si vede
Fallo con thebol... Io ho problemi di connessione...
GemsPair imho conviene farlo insieme al Pair Programming al momento in cui ne sentirete l'esigenza...
Tanto per farvi capire guardate fek nel pair programming con me quando ha inserito la classe Frame... In pratica complicando leggermente un test precedente sarebbero state necessarie troppe modifiche per soddisfarlo...a questo punto ha introdotto la classe Frame fatto il refactoring del codice esistente e di fatto è bastata una sola nuova istruzione per far passare il test in questione...
Seguirò il tuo consiglio :)
thebol se vuoi iniziare già a pubblicare il primo test io domani vedo cosa riesco a fare dall'univ :)
A questo punto ritengo giusto che la situazione si presentasse in questo modo:
- Grid: gestisce (inserimento / rimozione) gemme e fornisce informazioni sullo stato della griglia (solo lo strettamente necessario).
- GridController: gestisce spostamento gemme (moveLeft, moveRight), possiede informazioni sulle gemme sotto il controllo dell'utente.
Ovviamente gli EventHandler agiranno su GridController e non + su Grid direttamente...
In pratica così però sposteremmo tutto Grid in GridController...
Io continuerei a far gestire a Grid tutto quello che fa ora...anche perchè di fatto si andrà sempre ad agire sulla griglia...
L'unica modifica che andrebbe fatta in Grid credo che sia di portare questo codice:
if(gemCantMoveDown(getGemUnderControl()))
{
alignGemToCellUpperBound(getGemUnderControl());
getGemUnderControl().dropGem();
if(gemIsSurroundedBySameType(getGemUnderControl()))
{
getGemUnderControl().useBrighterImage();
}
}
else
{
moveGem(getGemUnderControl());
}
in un altro metodo sempre di Grid (ad esempio potrebbe essere chiamato updateGemUnderGravity(Gem gem))...in modo da permettere l'update di tutta la coppia di gemme...
Per il resto basterà comunque passare GridCotnroller agli handlers che tramite un metodo (potrebbe essere getGemsPairUnderControl) potranno risalire alla coppia di gemme e potranno applicare il movimento direttamente alla coppia di gemme... Ovviamente GemsPair avrà un membro Grid che gli permetterà di applicare i movimenti ad entrambe le gemme...
in un altro metodo sempre di Grid (ad esempio potrebbe essere chiamato updateGemUnderGravity(Gem gem))...in modo da permettere l'update di tutta la coppia di gemme...
Per il resto basterà comunque passare GridCotnroller agli handlers che tramite un metodo (potrebbe essere getGemsPairUnderControl) potranno risalire alla coppia di gemme e potranno applicare il movimento direttamente alla coppia di gemme... Ovviamente GemsPair avrà un membro Grid che gli permetterà di applicare i movimenti ad entrambe le gemme...
Questa mi sembra una buona line guida per scrivere il task.
A questo punto allora gemUnderControl non ha piu` senso dentro Grid...
In pratica così però sposteremmo tutto Grid in GridController...
Io continuerei a far gestire a Grid tutto quello che fa ora...anche perchè di fatto si andrà sempre ad agire sulla griglia...
Secondo me non e` propriamente vero... Forse non mi sono spiegato bene, collisioni con gemme, fondo e bordi verrebbero ancora gestite da Grid... Sarebbero i Controlli sulle gemme (movimenti) a passare dentro GridController...
Comunque ora cerco la soluzione + semplice per la risoluzione del task (probabilmente la soluzione del metodo che proponi potrebbe aiutare)...
A questo punto allora gemUnderControl non ha piu` senso dentro Grid...
Certamente no...
Secondo me non e` propriamente vero... Forse non mi sono spiegato bene, collisioni con gemme, fondo e bordi verrebbero ancora gestite da Grid... Sarebbero i Controlli sulle gemme (movimenti) a passare dentro GridController...
Ma i movimenti vanno ad agire anche sulla griglia...
Non ho il codice sotto mano pero` cerco di spiegarmi...
Come ti ho detto Grid gestirebbe inserimento e cancellazione di gemme.
Gli spostamenti sono tranquillamente gestibili da GridController con una semplice rimozione, cambio di coordinate, reinserimento (come gia` fa Grid).
Comunque so che viene prima il task e credo di poter gestire la situazione con pochissimi refactoring :)
Ma grid deve gestirebbe ancora lo spostamento della gemme (update) quindi o si toglie tutto (e quindi anche la gestione della gravità) o si lascia tutto ;) In pratica non rimarrebbe più niente dentro a Grid... Solo la gestioend elel collisioni...
Ho una vagonata di test che diventano incompatibili con gemsPair... Riscrivo i test per adattarli a gemsPair (prima di implementare la relativa parte testata ovviamente) o cerco di tenere quelli attuali e trovo un modo per farli funzionare?
Io lascerei la possibilità a Grid e GridController di gestire anche una gemma da sola... In tal caso tutti i test continuano a valere... Comunque credo che se bisogna lasciare questa possibilità te lo dovrebbero dire VICIUS e Jocchan...
avendo gia fatto questo refactoring, do qualche mia impressione su quello che ho fatto e che andra fatto:
-sposterei gemUnderControll da grid a gridController, spostando solo la gestione dell'update e relativi get & set di gemUnderControll, questo perche nella mia idea il Gridcontroller faceva muovere le gemme sotto controllo(dicendo a grid di spostare la gemma X a sx di 1, poi e grid che fisicamente :asd: la sposta).
- i movimenti di una singola gemma(con annessi check dei bordi, gemme, etc) li lascerei in grid, che cercherei di far essere una semplice griglia dove mettere gemme, spostarle, etc
-introduzione della seconda gemma, test, e poi refactoring di gemPair. Si guarderà se gridController gestirà 2 casi (2 gemme e 1 gemma) o questo lavoro possa essere fatto da gemPair, che settata in maniera opportuna funzioni anche come gemma(forse non avrebbe molto senso logico).
-tutto il resto da fare come task.
Altra cosa carina da fare alla fine del task(o anche prima in parallelo), sarebbe astrarre una classe di test, con una setup che definisca grid, gridController, input, inputReactor, timer, etc di test. In questa maniera, refactoring di questo tipo, avrebbero un minore impatto sui test.
a stasera, ora vado a lavoro(e niente internet :| )
-introduzione della seconda gemma, test, e poi refactoring di gemPair. Si guarderà se gridController gestirà 2 casi (2 gemme e 1 gemma) o questo lavoro possa essere fatto da gemPair, che settata in maniera opportuna funzioni anche come gemma(forse non avrebbe molto senso logico).
In teoria GemsPair dovrebbe continuare a lavorare anche quando c'è una sola gemma al suo interno... Vedi il caso di separazione delle gemme, ma non so se sia ancora arrivato il momento per gestire la separazione delle gemme (anzi, non credo, se una delle due gemme si arresta deve arrestarsi anche l'altra)... In ogni caso credo che semplicemente dovete controllare che, se c'è una sola gemma sotto controllo (e attualmente sarà solo la gemma Pivot), gemsPair continui a funzionare...
Io in teoria avrei già quasi finito il task :p
Però forse meglio farlo in pair... Comunque quando riapre il SVN committo un paio di refactoring utili :)
cdimauro
21-12-2005, 10:26
:fiufiu:
http://www.hwupgrade.it/forum/showpost.php?p=10596042&postcount=16
Non me n'ero accorto. Chissà dove avevo la testa... :muro:
cmq mi sa ke te lo devo lasciare...
in questi giorni ci sono delle scadenze e arrivo a casa troppo distrutto per mettermi a programmare.....
:muro:
A chi lo dici. Venerdì pomeriggio vado in ferie per una decina di giorni (a Roma), e in questo periodo sto lavorando come un matto... :cry:
A chi lo dici. Venerdì pomeriggio vado in ferie per una decina di giorni (a Roma), e in questo periodo sto lavorando come un matto... :cry: che zona di Roma? :p Eur? Roma 70? Torrino? Mostacciano? Spinaceto? ...?
Intanto ho committato un paio di refactoring... domani ho due esami e non posso fare molto :)
cdimauro
22-12-2005, 08:41
che zona di Roma? :p Eur? Roma 70? Torrino? Mostacciano? Spinaceto? ...?
Francamente non lo so. Ricordo soltanto che di recente nella zona hanno costruito un Ikea, e che hanno aggiunto una bretella al raccordo anulare.
Comunque se c'è da vedersi, qualunque sia la zona, non penso che ci siano problemi. ;)
Io avrò soltanto la possibilità di leggere la posta, per cui se si organizza qualcosa dovrei essere disponibile. Contattatemi via e-mail (non PVT), nell'eventualità, che vi passo il numero del mio cellulare... :)
In questi giorni non sono stato molto presente e ho perso un po il file. Qual'è lo stato attuale dei task? Ne avete già completato qualcuno?
ciao ;)
Purtroppo no... Da stasera ho tutto il tempo per lavorarci (ho dato 2 esami oggi ed i giorni scorsi non ho avuto troppo tempo e quando lo avevo nessuno si era offerto per il pair...)
Ufo: InputReactor non deve contenere la definizione degli handlers !!! E' una classe generica...quindi la definizione degli handlers che servono a GridController deve stare dentro a GridController...
Questo si può sistemare senza problemi :)
Questo si può sistemare senza problemi :)
Per favore, mantenete InputReactor generico. InputReactor NON deve in nessun modo dipendere da alcuna classe definita al di fuori del package di input (classi di sistema escluse ovviamente).
sì, considera anche che GridController non deve fare da Factory per un oggetto InputReactor :)
A me ora non va il SVN...
Comunque il metodo grid() è non testato in GridController... Non andrebbe testato?
sì, considera anche che GridController non deve fare da Factory per un oggetto InputReactor :)
Per carità, quello che c'era era prima non era il massimo...ma secondo me non serve nemmeno il factory method per GridController, ma basta un nuovo costruttore...
InputReactor IMHO non deve avere un factory method per ogni classe che lo userà (visto che implica andare a modificare InputReactor per ogni classe che lo usa)...
Secondo me meglio trasferire tutto in un costruttore...
cdimauro
23-12-2005, 07:59
Ragazzi, tra qualche ora parto per Roma. Ci vediamo al mio ritorno. Ne approfitto per fare gli auguri di buone feste a tutti. :)
Per carità, quello che c'era era prima non era il massimo...ma secondo me non serve nemmeno il factory method per GridController, ma basta un nuovo costruttore...
InputReactor IMHO non deve avere un factory method per ogni classe che lo userà (visto che implica andare a modificare InputReactor per ogni classe che lo usa)...
Secondo me meglio trasferire tutto in un costruttore...
Non so se hai ben capito quello che dicevo io o se io ho ben capito quello che stai dicendo tu :p
Intendi dire che non serve il Factory Method in GridController e nemmeno in InputReactor e che sarebbe meglio portare tutto dentro il costruttore di GridController?
A me non piace ricorrere a Factory se non strettamente necessario/utile (vedi createForTesting)...
DanieleC88
23-12-2005, 09:21
Ragazzi, tra qualche ora parto per Roma. Ci vediamo al mio ritorno. Ne approfitto per fare gli auguri di buone feste a tutti. :)
Buon viaggio e grazie degli auguri, ricambio. :)
Intendi dire che non serve il Factory Method in GridController e nemmeno in InputReactor e che sarebbe meglio portare tutto dentro il costruttore di GridController?
Sì ;)
Aggiungendo un factory method a InputReactor non togli alcuna duplicazione, quindi imho è un refactoring non necessario... Il factory method serve proprio per eliminare le duplicazioni...
L'aggiunta degli handler necessari a Grid è compito di GridController...e quindi deve essere fatta nel costruttore...
Magari il factory method di GridController in futuro potrebbe essere necessario (anche se secondo me potrebbe benissimo andarci un costruttore al suo posto), ma quello di InputReactor in futuro non farà altro che complicare il design...visto che dovremmo aggiungere un factory method per ogni classe che usa handlers diversi (e applica handlers diversi a classi diverse)...
Comunque nell'ultima build ho spostato il contenuto del factory method di InputReactor nel costruttore di GridController...
Tra l'altro anche il fatto stesso che GridController astrae sia Grid che InputReactor giustificherebbe la loro allocazione all'interno di un costruttore...
Ragazzi, tra qualche ora parto per Roma. Ci vediamo al mio ritorno. Ne approfitto per fare gli auguri di buone feste a tutti. :)
Divertiti, e buone feste ;)
Sì ;)
Aggiungendo un factory method a InputReactor non togli alcuna duplicazione, quindi imho è un refactoring non necessario... Il factory method serve proprio per eliminare le duplicazioni...
L'aggiunta degli handler necessari a Grid è compito di GridController...e quindi deve essere fatta nel costruttore...
Magari il factory method di GridController in futuro potrebbe essere necessario (anche se secondo me potrebbe benissimo andarci un costruttore al suo posto), ma quello di InputReactor in futuro non farà altro che complicare il design...visto che dovremmo aggiungere un factory method per ogni classe che usa handlers diversi (e applica handlers diversi a classi diverse)...
Comunque nell'ultima build ho spostato il contenuto del factory method di InputReactor nel costruttore di GridController...
Tra l'altro anche il fatto stesso che GridController astrae sia Grid che InputReactor giustificherebbe la loro allocazione all'interno di un costruttore...
Si', proseguite su questa linea. Questo dovrebbe eliminare anche quell'orribile factory method di InputReactor in GridController (lo misi io).
Una piccola nota, cerchiamo durante queste vacanze di dare un po' di stabilita' alla codebase: la necessita di fare refactoring non e' una licenza a stare sempre in refactoring land e a cambiare il codice tanto per fare. Ogni refactoring deve avere uno scopo preciso per semplificare il codice, e' giusto fare tentativi ma e' altrettanto importante sapere quando fare il commit del refactoring e quando non farlo.
Visto che Xmas.2.1 è un task veramente lungo ho fatto un refactoring abbastanza grosso (figuriamoci come sarebbe stato il task) per avvantaggiare chi dovrà svolgere il task...ho portato fuori da Grid tutti i metodi *GemUnderControl ed ho modificato la signature di Grid.update...aggiungendo come parametro la gemma su cui dovranno essere applicati i cambiamenti... Ho spostato l'update delle animazioni delle gemme in update di GridController... In questo modo il metodo update di Grid potrà essere applicato anche a più gemme (una coppia ;)) con chiamate separate...
Ovviamente ho rimesso a posto la quintalata di test che davano errori...
sono sempre stato favorevole a questo refactoring(l'avevo fatto io steso, ma poi ero andato oltre e mi era stato revertato).
ma con ufo, stavamo ponderando una strada diversa, cioè mantenere in grid GemUnderControl. gridControll avrebbe settato la gemma pivot come gemUnderControl, l'avrebbe mossa, avrebbe settato la gemma slave, e l'avrebbe mossa(questa come idea generale).
La cosa aveva senso, non so quanto avrebbe potuto funzionare(ci stava guardando ufo), ma poteva essere interessante.
Comunque potrebbe funzionare anche avendo tirato fuori gemUnderControl..almeno da come hai descritto quello che volete fare...
Dopo tutto avere gemUnderControl in Grid presuppone che grid debba occuparsi anche dell'input cosa che invece non fa...IMHO era un controsenso lasciare gemUnderControl in grid...
Comunque potrebbe funzionare anche avendo tirato fuori gemUnderControl..almeno da come hai descritto quello che volete fare...
Dopo tutto avere gemUnderControl in Grid presuppone che grid debba occuparsi anche dell'input cosa che invece non fa...IMHO era un controsenso lasciare gemUnderControl in grid...
sì... Come avevo detto anche secondo me bisognava muoversi su questa strada :) grazie per il refactoring è stato un bel regalo :D
sì... Come avevo detto anche secondo me bisognava muoversi su questa strada :) grazie per il refactoring è stato un bel regalo :D
E' stato il tuo ultimo refactoring che mi ha ispirato ;) :D
Task Xmas.2.1 completato :)
aggiunta la classe gemsPair e test del caso(molti spostati da gridController)
Nota:
negli handler viene fatto un controllo se esiste la gemma pivot, questo controllo non sarebbe piu giusto farlo nella moveLeft/Right di gridController o di gemsPair?
cmq ora gli altri task possono andare avanti direi.
Ciao
sì direi che ormai si può fare da move :)
Hai lasciato di nuovo codice commentato.. cancello :p
Ottimo ;) Io direi di togliere moveLeft e moveRight da GridController...
DanieleC88
26-12-2005, 16:53
cmq ora gli altri task possono andare avanti direi.
Stasera/domani mi metto al lavoro e comincio il task 2.2. :)
Ottimo ;) Io direi di togliere moveLeft e moveRight da GridController...
fatto, ho tolto anche il controllo sulla gemma pivot negli handler e l'ho messo nelle moveleft/right di gemspair.
la chiamata negli handler ora risulta però un po prolissa..
gridController.getGemsPair().moveRight(gridController.getGrid());
era per questo che l'avevo lasciata in gridController, ma in effetti era una dupicazione inutile.
thebol avevo già fatto io hai fatto update prima di commitare?
thebol avevo già fatto io hai fatto update prima di commitare?
durante il commit ho visto le differenze :)
Jocchan, non mi è chiaro cosa deve succedere quando una rotazione della mia (quella del tasto C) non è possibile... Ripetendo la rotazione semplicemente avrei un ritorno alla situazione attuale :p
P.S. Il task 2.3 non lo ha preso nessuno?
Jocchan, non mi è chiaro cosa deve succedere quando una rotazione della mia (quella del tasto C) non è possibile... Ripetendo la rotazione semplicemente avrei un ritorno alla situazione attuale :p
Stavo per scrivere "esatto", ma in effetti mi hai fatto venire in mente un caso limite, per cui dobbiamo agire in maniera differente.
Normalmente, se la pivot è a sinistra/destra della slave, e non c'è spazio di movimento, è normale che il comando venga ignorato.
Idem se la pivot è sotto la slave (se è sopra, non ci saranno problemi in nessun caso), vuol dire che sta per collidere e non c'è lo spazio per ruotare.
In questo caso, però, se l'utente preme il tasto quando la pivot è appena entrata nell'ultima casella libera prima della collisione, una non risposta ai comandi potrebbe essere frustrante.
Quindi, in questo caso (e solo in questo) direi che possiamo fare un'eccezione alla "regola di spostamento" (al contrario di come ti ho detto ieri su msn, cioè che per coerenza dovevamo mantenere lo stesso tipo di comportamento), e consentire che le due gemme vengano scambiate di posizione tra di loro.
quindi è valido solo nel caso in cui pivot è sotto, slave è sopra e sta per collidere?
Aspetta, ci sto riflettendo ancora su, ed in effetti questa eccezione non va bene, perchè - appunto - va evidentemente contro le altre regole di spostamento, e quindi creerebbe delle situazioni poco coerenti. Vediamo di impostare la cosa con una certa "permissività".
Quando la pivot è sotto la slave, ed è appena entrata nella casella libera più in basso (diciamo che ne ha occupati al max 10 pixel), se il giocatore preme il tasto C faremo in modo di forzare lo spostamento al solito modo (insomma, la slave si piazza sotto la pivot, e quest'ultima - in pratica - torna su fino ai bordi della casella)... in pratica, la facciamo entrare con la forza.
Se si supera questo valore limite, lo spostamento sarà impossibile e verrà ignorato.
Siamo costretti a dividere il tutto in questi due casi per consentire lo stesso al giocatore spostamenti "all'ultimo secondo", senza generare incoerenze ;)
Aspetta, ci sto riflettendo ancora su, ed in effetti questa eccezione non va bene, perchè - appunto - va evidentemente contro le altre regole di spostamento, e quindi creerebbe delle situazioni poco coerenti. Vediamo di impostare la cosa con una certa "permissività".
Quando la pivot è sotto la slave, ed è appena entrata nella casella libera più in basso (diciamo che ne ha occupati al max 10 pixel), se il giocatore preme il tasto C faremo in modo di forzare lo spostamento al solito modo (insomma, la slave si piazza sotto la pivot, e quest'ultima - in pratica - torna su fino ai bordi della casella)... in pratica, la facciamo entrare con la forza.
Se si supera questo valore limite, lo spostamento sarà impossibile e verrà ignorato.
Siamo costretti a dividere il tutto in questi due casi per consentire lo stesso al giocatore spostamenti "all'ultimo secondo", senza generare incoerenze ;)
Hmmm quindi bisogna impostare un valore limite per i riposizionamenti in extremis?
Anche Super Puzzle Fighter fa una cosa del genere...
Comunque IMHO per non complicare troppo questi task (e studiare un'architettura unificata per svolgere questi compiti) credo che sia meglio gestire questa cosa in un task futuro...
Hmmm quindi bisogna impostare un valore limite per i riposizionamenti in extremis?
Esatto :)
Anche Super Puzzle Fighter fa una cosa del genere...
In questo momento non ho presente l'approccio di Puzzle Fighter, ma andando a logica credo sia la cosa migliore.
Comunque IMHO per non complicare troppo questi task (e studiare un'architettura unificata per svolgere questi compiti) credo che sia meglio gestire questa cosa in un task futuro...
Sono d'accordo. Ufo, per ora puoi limitarti ad ignorare lo spostamento sempre e comunque. Questo caso limite lo definiremo in seguito, e con calma ;)
Addirittura considererei la coppia come inseparabile... Almeno per ora...
Altra cosa...il generatore casuale deve essere modificato per ritornare a gestire anche gemme uguali consecutive..
Addirittura considererei la coppia come inseparabile... Almeno per ora...
Oddio questa credo sia una cosa che possiamo gestire fin da ora ;)
Altra cosa...il generatore casuale deve essere modificato per ritornare a gestire anche gemme uguali consecutive..
Invece direi di no, dato che questo ci consente di avere una maggiore differenziazione di pezzi in gioco... in caso poi venga fuori una complessità troppo elevata in termini di gameplay (ne dubito) allora vedremo di togliere questa limitazione ;)
Invece direi di no, dato che questo ci consente di avere una maggiore differenziazione di pezzi in gioco... in caso poi venga fuori una complessità troppo elevata in termini di gameplay (ne dubito) allora vedremo di togliere questa limitazione ;)
Ma in questo modo non si avranno mai due gemme dello stesso tipo nella stessa coppia... Allora farei una cosa diversa... Due generatori casuali (sempre con la stessa fomula della gemma corrente che agiscono alternativamente)... Giocando con il generatore corrente sinceramente le gemme mi sembrano ben poco casuali, anche perchè si possono avere 2 coppie di gemme identiche consuctive, ma non una coppia con due gemme uguali...
Allora in questo caso vedrei bene una piccola modifica al generatore attuale, che valuti l'uguaglianza di una gemma NON con la successiva, ma con quella che si trova due posizioni dopo nella coda.
In questo modo, sarà possibile anche avere due gemme uguali nella stessa coppia, ma non due coppie uguali.
A me sembra che manchino dei test... Non riesco a trovare il metodo che testava la non ripetizione in due estrazioni successive :confused:
cionci se non erro non è mai stato previsto un task per l'estrazione casuale, indi niente test
L'avevo fatto io il test...non era nei task, era extra task... Tra l'altro era in TestGemFactory
Mmmmhhh...boh... Doveva essere lì, ma non lo trovo...
C'è sempre il test :muro: Che testa che ho :stordita:
Allora in questo caso vedrei bene una piccola modifica al generatore attuale, che valuti l'uguaglianza di una gemma NON con la successiva, ma con quella che si trova due posizioni dopo nella coda.
In questo modo, sarà possibile anche avere due gemme uguali nella stessa coppia, ma non due coppie uguali.
Modifica fatta... Ho rivisto un po' l'algoritmo per l'estrazione casuale... In questo modo le gemme sono equiprobabili (esclusa quella che non è possibile estrarre)...
Modifica fatta... Ho rivisto un po' l'algoritmo per l'estrazione casuale... In questo modo le gemme sono equiprobabili (esclusa quella che non è possibile estrarre)...
Benissimo, grazie :)
ragazzi, per fare il mio task attendo che almeno il task Xmas.2.2 sia completato, così posso rendermi meglio conto di cosa succede quando una delle due gemme collide e di cos'è che va testato e modificato nel programma.
ma devo anche riprodurre l'effetto presente nell'originale, cioè che a gemma che non collide cade rapidamente a terra, o per meglio dire, finché non collide anch'essa?
ragazzi, per fare il mio task attendo che almeno il task Xmas.2.2 sia completato, così posso rendermi meglio conto di cosa succede quando una delle due gemme collide e di cos'è che va testato e modificato nel programma.
ma devo anche riprodurre l'effetto presente nell'originale, cioè che a gemma che non collide cade rapidamente a terra, o per meglio dire, finché non collide anch'essa?
Sì, in effetti nella storia non è chiarissimo ma il senso è quello.
Basta attivare il multiplier ed il gioco è fatto ;)
DanieleC88
28-12-2005, 15:36
Bene, ho buttato giu' un primo test per il task 2.2:
public void testGemsPairCanRotateCounterclockwise()
{
int old_row = gridController.getGemsPair().getSlaveGem().getCellRow();
int old_col = gridController.getGemsPair().getSlaveGem()
.getCellColumn();
gridController.getGemsPair().rotateCounterclockwise();
int new_row = gridController.getGemsPair().getSlaveGem().getCellRow();
int new_col = gridController.getGemsPair().getSlaveGem()
.getCellColumn();
boolean has_moved_down = (new_row == (old_row + 1));
boolean has_moved_left = (new_col == (old_col - 1));
assertTrue("slaveGem didn't rotate", (has_moved_down && has_moved_left));
}
Il problema e' che, per ora, questo test contempla solo il Caso 1 (http://www.hwupgrade.it/forum/showpost.php?p=10547371&postcount=2) illustrato da Jocchan. Quindi mi chiedevo:
- basta che il test verifichi la rotazione oppure deve gestire tutti e quattro i casi?
- quando la gemma slave ha un ostacolo che le impedisce la rotazione, deve "saltare" al prossimo spazio libero o fare qualche altra cosa?
Quando non è possibile assumere la nuova posizione imho per ora la rotazione deve fallire, quindi non deve accadere niente...
DanieleC88
28-12-2005, 16:21
Quando non è possibile assumere la nuova posizione imho per ora la rotazione deve fallire, quindi non deve accadere niente...
Ok, capito. Deve semplicemente non fare nulla. :)
Colgo l'occasione per riscrivere il test di prima, come suggeritomi dal buon VICIUS:
public void test()
{
assertTrue(gridController.getGemsPair().slaveIsUp());
gridController.getGemsPair().rotateCounterclockwise();
assertTrue(gridController.getGemsPair().slaveIsLeft());
}
In effetti e' una soluzione molto piu' ovvia. ;)
Questa soluzione mi permette anche di verificare con facilita' tutte e quattro le condizioni:
public void testGemsPairCanRotateCounterclockwise()
{
assertTrue("slaveGem should have been up", gridController.getGemsPair()
.slaveIsUp());
gridController.getGemsPair().rotateCounterclockwise();
assertTrue("slaveGem didn't rotate", gridController.getGemsPair()
.slaveIsLeft());
gridController.getGemsPair().rotateCounterclockwise();
assertTrue("slaveGem didn't rotate", gridController.getGemsPair()
.slaveIsDown());
gridController.getGemsPair().rotateCounterclockwise();
assertTrue("slaveGem didn't rotate", gridController.getGemsPair()
.slaveIsRight());
gridController.getGemsPair().rotateCounterclockwise();
assertTrue("slaveGem didn't rotate", gridController.getGemsPair()
.slaveIsUp());
}
Ok, la smetto di inquinare il thread e torno al lavoro. :D
Non credo che finiro' entro le 18:00... al massimo committo domani. ;)
Guarda in Grid...ora c'è una funzione isValidCell che sicuramente ti può tornare utile...
Io devo rinunciare al mio task... Domattina parto e non ci sarò fino al 10...
Colgo l'occasione per augurarvi buon anno! Ci vediamo l'11 :)
DanieleC88
29-12-2005, 09:35
Guarda in Grid...ora c'è una funzione isValidCell che sicuramente ti può tornare utile...
Sto prima cercando di far semplicemente passare il test... ebbene, con il nuovo test (avevo dimenticato un passaggio, ho editato quello di prima), l'asserzione fallisce sull'ultima condizione: pare che ci sia una gemma in (x:4,y:0), che poi dovrebbe essere la posizione iniziale di slaveGem. Temo quindi che il metodo che ho usato per muovere la gemma (setCellPosition) non l'abbia spostata nella relativa Grid.
Il codice e' questo:
public void rotateCounterclockwise()
{
int row = pivotGem.getCellRow();
int column = pivotGem.getCellColumn();
if(slaveIsUp())
{
if(grid.isGemAt(row, column - 1) == false)
column--;
}
else if(slaveIsLeft())
{
if(grid.isGemAt(row + 1, column) == false)
row++;
}
else if(slaveIsDown())
{
if(grid.isGemAt(row, column + 1) == false)
column++;
}
else if(slaveIsRight())
{
if(grid.isGemAt(row - 1, column) == false)
row--;
}
slaveGem.setCellPosition(row, column);
}
DanieleC88: devi partire da piccoli passi:
Fai prima un test posizionando la gemma pivot sopra...le altre condizioni guardale una per una...
IMHO non servono nemmeno quelle isSlaveXX... Comincia facendo le verifiche semplicemente tramite la getColumn e la getRow delle varie gemme...
Per muovere la gemma devi usare grid.moveRight, grid.moveLeft e altre due: grid.moveDown e grid.moveUp che vanno perà scritte...
DanieleC88
30-12-2005, 09:40
Be', dopo molta fatica e dopo aver scassato i cosiddetti a cionci per una giornata (:D) e un po' anche a vic, posso dire che... il task e' tecnicamente concluso. C'e' solo un problema: non so perche', ma le gemme hanno un comportamento strano... se le faccio ruotare piu' volte mentre stanno cadendo, a volte "atterrano" a mezz'aria e si fermano li'. Non capisco dove sta l'errore.
In ogni caso, il task e' praticamente finito, i test passano e Ant non mi da' alcun errore. Faccio il commit? Cosi' magari avete anche voi la possibilita' di cercare l'errore.
Chi lo sa...bisognerebbe implemetare un test che riproduca los tesso effetto... Vediamo ;)
DanieleC88
30-12-2005, 10:08
Chi lo sa...bisognerebbe implemetare un test che riproduca los tesso effetto... Vediamo ;)
Ok, allora faccio il commit appena risolvo un'altro problema (ho notato che, ruotando le gemme, queste poi si rifiutano di muoversi a sinistra o a destra perche' "la cella e' occupata"... dalla gemma compagna). Come dicevo anche nel thread dei problemi, ho scritto anche un test e il relativo codice per l'inserzione di un GemsPair in una colonna con una sola cella libera. Ah, dimenticavo: alla fine ho deciso che se la posizione di destinazione della gemma e' occupata, la slave non ruota per niente.
Ok, allora faccio il commit appena risolvo un'altro problema (ho notato che, ruotando le gemme, queste poi si rifiutano di muoversi a sinistra o a destra perche' "la cella e' occupata"... dalla gemma compagna). Come dicevo anche nel thread dei problemi, ho scritto anche un test e il relativo codice per l'inserzione di un GemsPair in una colonna con una sola cella libera.
Per eliminare questo problema dovrebbe bastare una piccola modifica al codice che verifica se la cella è occupata.
Ah, dimenticavo: alla fine ho deciso che se la posizione di destinazione della gemma e' occupata, la slave non ruota per niente.
E perchè? Nella storia c'era scritto che, se la posizione di destinazione è occupata, la slave dovrà continuare a ruotare fino a trovarne una libera.
E perchè? Nella storia c'era scritto che, se la posizione di destinazione è occupata, la slave dovrà continuare a ruotare fino a trovarne una libera.
Così diventa molto complicato da gestire...al massimo si potrebbe "provare" la posizione successiva...sicuramente non fino a quando non ne trova una libera...
Ho risolto il bug dell'update, ma se ne è ripresentato un altro che non sono riuscito a replicare con i test...
omg che casino O_O
il task di Daniele funziona, solo che se provo ad incasinare un po' la situazione (cioè a dropparne un po' "separandole", cioè facendone collidere una e aspettando che caschi anche l'altra) a un certo punto non so perché le gemme iniziano a collidere a mezz'aria, ma non tutte solo alcune... O_o'
Quello dovrebbe essere il bug che ho risolto, devo ancora fare il commit...
Ora ce n'è uno simile ma che si ha quando due gemme si separano...ed è stranissimo...
sgamato il bug!! le gemme collidono a mezz'aria solo quando le si capovolge di 180 gradi, cioè quando quella che sta giù se ne va su (quando la ruoto due volte insomma); quando questo succede, la gemma che se n'è appena andata su (che dovrebbe essere la slave) collide non appena tocca il fondo della cella corrente, mentre la gemma pivot continua a cadere; nessuna delle due però naturalmente perde il controllo, perciò se io le sposto lateralmente continuano a cadere entrambe.
Quello è il bug che ho risolto, devo ancora fare il commit...
Ora ce n'è uno simile ma che si ha quando due gemme si separano...ed è stranissimo... ah, non avevo letto ^^
Ok... Sono riuscito a riprodurre il bug...
Fate l'update con l'utima revisione...
Prendete la prima coppia... Premete Z e lasciate cadere orizzontalmente...
Premete Z sulla nuova coppia spostate a sinistra e lasciate cadere...
btw, è normale che il tasto Z (e quindi suppongo prossimamente anche X e C) non abbia(no) la gestione della ripetizione? il Customer cosa vuole in proposito? dovremo gestire le ripetizioni o no?
Prendete la prima coppia... Premete Z e lasciate cadere orizzontalmente...
Premete Z sulla nuova coppia spostate a sinistra e lasciate cadere... intendi dire questo? ^^'
Fai solo el mosse che ti ho detto...si vede benissimo...
Fai solo el mosse che ti ho detto...si vede benissimo... veramente facendo precisamente come dici da me non succede niente di strano... alla fine si hanno 4 gemme, 3 in basso e 1 sopra, a mo' di podio :D
Riprova un po' senza giochicchiare troppo con i tasti...e senza premere verso il basso quando fai andare giù la seconda gemma...
veramente facendo precisamente come dici da me non succede niente di strano... alla fine si hanno 4 gemme, 3 in basso e 1 sopra, a mo' di podio :D no, errata corrige: cionci, prova a fare le stesse mosse che hai detto però tenendo premuto il tasto freccia giù: con la gravità aumentata tutto funziona regolarmente, con la gravità normale invece no...
Riprova un po' senza giochicchiare troppo con i tasti...e senza premere verso il basso quando fai andare giù la seconda gemma... appunto ^^
Io devo andare a pappare... 71104 se vuoi risovlerlo te fai pure... Guarda l'update di gridController cosa controlla ;)
Ovviamente fai il relativo test stoppando la gemma pivot e facendo trascorrere il tempo per la generazione di una nuova gemma...
Attualmente vengono riprodotti due suoni quando le gemme arrivano in fondo... Se non va bene pensiamoa risolverlo...
DanieleC88
31-12-2005, 13:12
Per eliminare questo problema dovrebbe bastare una piccola modifica al codice che verifica se la cella è occupata.
Si, questo l'avevo gia' corretto nel frattempo. ;)
E perchè? Nella storia c'era scritto che, se la posizione di destinazione è occupata, la slave dovrà continuare a ruotare fino a trovarne una libera.
Si, quello era il copmortamento iniziale, poi l'ho modificato: in quel modo si spezza troppo facilmente la coppia e si puo' "barare". In ogni caso, questo problema si puo' risolvere lasciando che la slave divenga dropped appena tocca un'altra gemma o il fondo, altrimenti seguira' ancora i movimenti della pivot finche' questa non tocchera' terra.
btw, è normale che il tasto Z (e quindi suppongo prossimamente anche X e C) non abbia(no) la gestione della ripetizione? il Customer cosa vuole in proposito? dovremo gestire le ripetizioni o no?
La gestione dovrebbe esserci... ricontrollo... :wtf:
Sto dando un'occhiata alla codebase dopo la mia pausa di natale e complimenti a tutti per come avete gestito il progetto in mia assenza :)
Ora mi avete reso inutile... :(
DanieleC88
31-12-2005, 14:56
Ora mi avete reso inutile... :(
Il compito di ogni maestro e' di mettere l'allievo in condizione di superarlo. :D
Scherzo... abbiamo bisogno di un coach!! non lasciarci nelle mani di VICIUS! :asd: :asd: :asd:
Il compito di ogni maestro e' di mettere l'allievo in condizione di superarlo. :D
shhhhhhhhh, non dire così che poi come scusa di task di diamonds ci sfrutta con cose riguardanti fable 2 :asd:
DanieleC88
01-01-2006, 12:14
shhhhhhhhh, non dire così che poi come scusa di task di diamonds ci sfrutta con cose riguardanti fable 2 :asd:
LOOOL :asd: :asd: :asd:
Si, quello era il copmortamento iniziale, poi l'ho modificato: in quel modo si spezza troppo facilmente la coppia e si puo' "barare". In ogni caso, questo problema si puo' risolvere lasciando che la slave divenga dropped appena tocca un'altra gemma o il fondo, altrimenti seguira' ancora i movimenti della pivot finche' questa non tocchera' terra.
Ma questa modifica è solo temporanea, dovuta a problemi di sviluppo del task? Certe decisioni vanno discusse PRIMA di implementare una sola riga di codice, dato che è comunque un elemento di game design, ed ha un suo peso nell'equilibrio della meccanica di gioco.
Non possiamo assolutamente permetterci di andare tutti in autonomia, cambiando dettagli qui e là: abbiamo una storia e dei task, e bisogna rispettarli.
Poi, basta discutere le varie idee: 71104, Cionci e Ufo13 ad esempio hanno contribuito parecchio per definire alcuni dettagli, quindi figuriamoci se ci sono problemi.
Così diventa molto complicato da gestire...al massimo si potrebbe "provare" la posizione successiva...sicuramente non fino a quando non ne trova una libera...
Ops, questo post mi era sfuggito... comunque le destinazioni possibili sono in tutto tre, basterebbe verificare via via la disponibilità delle celle (e, in caso di impossibilità, ignorare il movimento) :)
btw, è normale che il tasto Z (e quindi suppongo prossimamente anche X e C) non abbia(no) la gestione della ripetizione? il Customer cosa vuole in proposito? dovremo gestire le ripetizioni o no?
Se il tasto rimane premuto (X,Z o C che sia), la slave deve continuare a ruotare... ovviamente non a velocità folli ;)
Questo comunque ancora non rientra strettamente nei task, quindi possiamo pensarci poi :)
Mi sono messo e in 5 minuti ho fatto anche gli altri due Task rimasti. Quindi ora rimane solo quello di 71104.
ciao ;)
Mi sono messo e in 5 minuti ho fatto anche gli altri due Task rimasti. Quindi ora rimane solo quello di 71104. metà me l'ha già fatta cionci :D
ora faccio l'altra metà, ecco i test:
public void testPivotFinishesFallingFast()
{
gemsPair.getSlaveGem().dropGem();
gridController.update(new MockTimer());
assertEquals(1.0, grid.getActualGravity(), 0.001f);
}
public void testSlaveFinishesFallingFast()
{
gemsPair.getPivotGem().dropGem();
gridController.update(new MockTimer());
assertEquals(1.0, grid.getActualGravity(), 0.001f);
}
public void testGravityRestoredAfterPivotHasFallen()
{
gemsPair.getSlaveGem().dropGem();
gridController.update(new MockTimer());
gemsPair.getPivotGem().dropGem();
assertEquals(0.5, grid.getActualGravity(), 0.001f);
}
public void testGravityRestoredAfterSlaveHasFallen()
{
gemsPair.getPivotGem().dropGem();
gridController.update(new MockTimer());
gemsPair.getSlaveGem().dropGem();
assertEquals(0.5, grid.getActualGravity(), 0.001f);
}
chiaramente ora passano solo gli ultimi due.
uff, il programma funziona correttamente ma adesso un sacco di test mi stanno dando problemi a causa della gravità accelerata... :-\
sono riuscito a sistemare tutti i test tranne uno, che a questo punto non so se va ancora bene; ha ancora senso secondo voi?
public void testSameGravityOnSecondGem()
{
grid.insertGem(13, 4, gem);
gemsPair.setPivotGem(gem);
input.generateKey(Input.KeyCode.vk_Down);
controller.reactToInput(timer);
float actualGravity = grid.getActualGravity();
controller.update(timer);
assertEquals("gravity is not the same", actualGravity, grid
.getActualGravity(), 0.001);
}
per ora ho committato il task lasciando quel test commentato.
non ce la faccio più, mi prudono le mani, VOGLIO PROGRAMMARE!! O.o'
preparate al più presto un'altra storia pleeeeeease!! :cry:
non ce la faccio più, mi prudono le mani, VOGLIO PROGRAMMARE!! O.o'
preparate al più presto un'altra storia pleeeeeease!! :cry:
C'è sempre lo spike per l'online ;)
La storia si può considerare chiusa? Tutti i requisiti sono stati soddisfatti? E soprattutto... chi mi passa una build per testare i risultati? :Prrr:
C'è la questione della posizione in caso la slave non possa ruotare...ci sto pensando in questo momento...
ma quella questione immagino vada risolta in un altro ciclo: non fare tutto da solo, bisogna pensare insieme a come reagire nei casi particolari :Prrr:
Già fatto :D Ho fatto come aveva detto Jocchan...se la rotazione non è possibile mi posiziono sulla prima libera...se non c'è resto fermo...
C'è la questione dell'operazione mirror...se la destinazione è occupata IMHO può solo stare ferma (così fa ora perchè è venuto con la gestione delel altre rotazioni)... Per chiarire...la slave è sopra alla pivot in [3,4], quindi la pivot è in [4,4]... La [5,4] è oocupata...secondo me la slave non deve andare a destra o a sinistra...ma deve stare ferma... Se andasse dai lati non rispetterebbe l'operazione di "mirror"...
Faccio il commit...andate di refactoring e siate impietosi :D ;)
C'è la questione dell'operazione mirror...se la destinazione è occupata IMHO può solo stare ferma (così fa ora perchè è venuto con la gestione delel altre rotazioni)... Per chiarire...la slave è sopra alla pivot in [3,4], quindi la pivot è in [4,4]... La [5,4] è oocupata...secondo me la slave non deve andare a destra o a sinistra...ma deve stare ferma... Se andasse dai lati non rispetterebbe l'operazione di "mirror"...
Esattamente, il comportamento da tenere è questo.
Nella versione attuale la cosa funziona in questo modo?
Chi mi passa questa build? :Prrr:
Te la passo io... Nella versione attuale fa proprio questo... Unificando tutte le rotazioni è diventato semplicissimo fare questa cosa...
-_-'
a-hem, dunque:
* Mai fare a gara a chi finisce il task per primo, meglio procedere con calma, altrimenti perderemo molto più tempo in seguito
* Evitiamo di complicarci la vita, esiste di certo una soluzione più semplice di quella che abbiamo pensato di implementare
* MAI aggiungere elementi non richiesti esplicitamente dai task: se mai serviranno, se ne parlerà nelle prossime storie
* Comunichiamo il più possibile, se qualcosa non è chiaro discutiamone tutti i dettagli fino ad eliminare ogni dubbio, anche il più insignificante
* Postare sempre la test list PRIMA di mettere mano al codice
messe in evidenza un paio di regole vorrei chiederti caro cionci: quale task chiedeva di gestire i casi particolari di cui hai parlato? -.-'
e poi almeno potresti postare i test che hai fatto prima di aggiungere questo codice? -.-'
thx
Li richiedeva Jocchan...e secondo lui erano parte dei task 2, 3 e 4...
DanieleC88 aveva ritenuto (giustamente per come si erano messe le cose, visto che questa era una cosa da sviluppare con le rotazioni unificate) di impedire il movimento nel caso la cella did estinazione fosse occupata...
Se non sbaglio ne avevano già discusso Jocchan e DanieleC88...
Insomma questa era una cosa richiesta da tutti i task...ma che non era possibile inserirla in maniera agevole prima di aver unificato le rotazioni...
Se vuoi i test...eccoli:
public void testRotationWithFirstDestinationOccupied()
{
grid.insertGem(1, 5, Gem.createForTesting());
gemsPair.rotateClockwise();
assertSame("slave should be down", gemsPair.getSlaveGem(), grid.getGemAt(2, 4));
}
public void testRotationWithSecondDestinationOccupied()
{
grid.insertGem(1, 5, Gem.createForTesting());
grid.insertGem(2, 4, Gem.createForTesting());
gemsPair.rotateClockwise();
assertSame("slave should be down", gemsPair.getSlaveGem(), grid.getGemAt(1, 3));
}
public void testRotationWithThirdDestinationOccupied()
{
grid.insertGem(1, 5, Gem.createForTesting());
grid.insertGem(2, 4, Gem.createForTesting());
grid.insertGem(1, 3, Gem.createForTesting());
gemsPair.rotateClockwise();
assertSame("slave should be down", gemsPair.getSlaveGem(), grid.getGemAt(0, 4));
}
Appunto, l'elemento era parte dei task (probabilmente però andava specificato meglio), ed era esplicitamente presente nella storia.
Ci saremmo passati anche su per eventuali difficoltà implementative, e quindi avremmo rinviato il dettaglio a storie successive, ma effettivamente era una cosa che andava fatta subito ;)
Io sinceramente l'ho visto come se fosse stato un bug... Infatti alla fine della storia il comportamento era diverso da quello richiesto...
:mbe:
vabbè però i prossimi task scriveteli meglio... :mbe:
e ricordatevi la quinta regola :mbe:
vabbè però i prossimi task scriveteli meglio... :mbe:
Vero, ma per quanto ci si impegni per scrivere dei task dettagliati alla fine qualche incompletezza può sempre esserci.
Per questo basta guardare la storia, che li complementa, e se notate qualcosa che contrasta con i task (o che non è presente) per favore scrivetelo subito, così vediamo di agire di conseguenza.
In questo caso particolare, il task non esprimeva esplicitamente un dettaglio richiesto nella storia: bene, allora bisognava discutere (qui) esattamente in quale (o quali) task questo dettaglio rientrasse, dato che l'obiettivo finale è appunto completare la storia in ogni sua parte ;)
Per la test list vero, cercate di scriverla sempre prima :)
e insomma, a quando il nuovo ciclo??? :D :D :D
e insomma, a quando il nuovo ciclo??? :D :D :D
Lunedi' iniziamo il nuovo Ciclo. Questo si conclude Venerdi'. Nel frattempo hai ben due Spike e tanto lavoro di refactoring a disposizione :)
Fra oggi e domani Jocchan guarda la build, si chiude questo Ciclo e si passa al successivo. Lunedi' i task nuovi.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.