PDA

View Full Version : [BUG #6] Gemma Solitaria


BlueDragon
28-04-2006, 22:25
A volte è possibile ottenere e muovere una gemma solitaria:

mi sono accorto di una cosa

faccio un esempio... mettiamo caso che escano 2 gemme, una rossa e, quella inferiore (che ne sò) di colore verde
la pila esattamente sotto a dove escono è alta 2 righe meno del massimo (del game over) e come primo elemento in alto ha un box verde

di solito capita che la gemma inferiore della coppia e il box che si trova in cima alla pila (dello stesso colore) spariscono immediatamente (questo perchè a quanto vedo la coppia entra direttamente nelle prime due righe della griglia, non parte da "fuori" dalla griglia, vale a dire dall'imbutino che si vede in alto)... mentre la seconda (quella in alto) gemma della coppia uscita (che è rimasta da sola essendo sparita l'altra assieme al primo elemento della pila) cade ad una velocità un po' superiore al normale verso la pila e qui si ferma

e fin qui credo che sia giusto, insomma che sia il comportamento corretto

una (sola) volta però mi è capitato di riuscire a spostare la gemma "supersite" della coppia verso destra...
in poche parole avevo una sola gemma che cadeva e che potevo controllare spostando a dx o sx come volevo (non ho provato a ruotarla per vedere cosa succedeva purtroppo)

ecco, in questo caso non so se il comportamento sia corretto

spero di essere riuscito a spiegarmi


Direi che il seguente codice in GridController ha buone possibilità di esserne la causa...che ne dite? :)

public void insertNewGemsPair()
{
Droppable gem;

if(!grid.isGemAt(1, 4))
{
gem = gemGenerator.extract();
grid.insertGem(1, 4, gem);
gemsPair.setPivotGem(gem);

gem = gemGenerator.extract();
grid.insertGem(0, 4, gem);
gemsPair.setSlaveGem(gem);
}
else
{
gem = gemGenerator.extract();
grid.insertGem(0, 4, gem);
gemsPair.setPivotGem(gem);
gemsPair.setNoSlaveGem();
}

++numberOfPairInserted;
}



Il codice permette l'inserimento di una gemma solitaria, poi sfruttando il lasso di tempo che intercorre tra la creazione della gemma solitaria ed il riconoscimento del GameOver, un giocatore molto rapido (o con delle mosse già bufferizzate dalla tastiera) potrebbe muovere via la gemma....regge come ipotesi? :)

Ho anche appena riprodotto il baco..è bastato impilare tutte le gemme lasciando solo 1 riga libera in alto e tenendo premuto sinistra non appena l'ultima gemspair regolare si è posata.
EDIT: Ho anche riprovato e non ci sono riuscito...ora tocca trovare perché riesce solo a volte :)

BlueDragon
28-04-2006, 22:44
Per riprodurre in scioltezza il baco, basta inserire un Thread.sleep(3000)
nel ramo che produce la gemma singola, così avete tutto il tempo di premere il tasto per spostarla :D

Es:

else
{
System.out.println("Creata gemma unica!");
try
{
Thread.sleep(3000);
}
catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
gem = gemGenerator.extract();
grid.insertGem(0, 4, gem);
gemsPair.setPivotGem(gem);
gemsPair.setNoSlaveGem();
}

BlueDragon
28-04-2006, 22:50
Un possibile fix è stabilire che quando viene inserita una sola gemma, essa viene messa subito messa in stato dropped.

else
{
gem = gemGenerator.extract();
grid.insertGem(0, 4, gem);
gemsPair.setPivotGem(gem);
gemsPair.setNoSlaveGem();
gem.drop();
}

Vi piace? :)

fek
28-04-2006, 23:09
Riesci a scrivere un test che esercita il bug?

Manp
28-04-2006, 23:25
ehi, sembra che per una volta sia stato utile nel trovare un baco così imboscato :D

:)

BlueDragon
28-04-2006, 23:51
ehi, sembra che per una volta sia stato utile nel trovare un baco così imboscato :D
:)
Decisamente :)

Riesci a scrivere un test che esercita il bug?
In TestGemsPair esiste testInsertionOnFullColumn() che testa che in una colonna in cui rimane vuota solo la prima casella, venga inserita una sola gemma nella cella 0,4 senza dare errore.
Ci potrei aggiungere:
assertFalse("gemspair shouldn't be able to move",gemsPair.canReactToInput());
in modo da dichiarare che la gemma solitaria deve essere inserita bloccata e non può essere portata in giro.

BlueDragon
29-04-2006, 19:33
assertFalse("gemspair shouldn't be able to move",gemsPair.canReactToInput());
in modo da dichiarare che la gemma solitaria deve essere inserita bloccata e non può essere portata in giro.
Ok, aggiungo il test quotato sopra.
Lancio Ant, fallisce. Bene, cerchiamo la via più semplice.
Andiamo a gemsPair.canReactToInput.

public boolean canReactToInput()
{
if(slaveGem == null)
{
return null != pivotGem;
}
return slaveGem.isFalling() && pivotGem.isFalling();
}

Ok, l'ultimo return è molto chiaro: la gemPair si può muovere se tutte e due le gemme stanno cadendo. Se una delle due non sta cadendo, significa che si sono divise e non si può controllare la rimanente, mi sembra giusto.

Il return sopra invece dice: se la slaveGem non esiste, allora il poter muovere o meno la gemsPair dipende dall'esistenza della gemma Pivot. Se esiste almeno la gemma Pivot, puoi muovere, altrimenti se è null anch'essa, non puoi muovere.
La cosa mi lascia un po' perplesso...in che occasione dovrei poter muovere la gemma Pivot senza la gemma Slave?
Io metterei piuttosto un if (pivotGem == null || slaveGem == null) return false.
Ossia, se una delle due non c'è, non puoi muovere il paio.

Proviamo...lancio il test, fallisce. Perché? Ci sono dei test di Grid che usano una gemma sola in griglia e che si aspettano che venga mossa dagli handler, che però considerano sempre GemsPair.canReactToInput.
Uhm...se pensiamo a Grid fuori dal contesto del gioco come una griglia in cui muovere le gemme, è vero che potrebbe muoversi una gemma da sola.
Confesso che mi lascia qualche dubbio ma andiamo avanti.

Allora diciamo che è possibile muovere una gemma da sola, però direi di applicargli comunque la condizione "isFalling()".
Se non sta cadendo, cioè si è fermata, non dovrebbe essere possibile muoverla, anche se è da sola.

Modifichiamo quindi il metodo canReactToInput per farlo diventare così:

public boolean canReactToInput()
{
if(slaveGem == null)
{
return null != pivotGem && pivotGem.isFalling();
}
return slaveGem.isFalling() && pivotGem.isFalling();
}

Lanciamo la build, i test di Grid passano ma fallisce il nostro test per tenere ferma la gemma solitaria.
Infatti la gemma solitaria che viene inserita in testa alla colonna è in stato falling = true quando viene inserita.
Quello che vogliamo ottenere non è che la gemma sia in caduta ma che sia semplicemente inserita per riempire l'ultima cella disponibile e poi mostrare gameover. Se non c'entra l'intera gemspair, la singola gemma inserita va appoggiata ferma sulla colonna piena.
Modifichiamo l'inserimento della singola gemma da parte del GridController, aggiungendo il drop:

public void insertNewGemsPair()
{
Droppable gem;

if(!grid.isGemAt(1, 4))
{
gem = gemGenerator.extract();
grid.insertGem(1, 4, gem);
gemsPair.setPivotGem(gem);

gem = gemGenerator.extract();
grid.insertGem(0, 4, gem);
gemsPair.setSlaveGem(gem);
}
else
{
gem = gemGenerator.extract();
grid.insertGem(0, 4, gem);
gem.drop();
gemsPair.setPivotGem(gem);
gemsPair.setNoSlaveGem();
}

++numberOfPairInserted;
}

Ok, così la gemma è droppata ferma sulla colonna piena.
Lanciamo la build....funziona tutto :)

BlueDragon
29-04-2006, 19:42
Dopo un'ultimo controllo lanciando il gioco, committato il tutto sul repository :)

EDIT:Build successfull :)

Bonfo
29-04-2006, 20:10
:mano:

fek
30-04-2006, 11:15
Ma sei stato bravissimo BD :)

Anche questo e' andato. Aggiorniamo la bug list.

VICIUS
01-05-2006, 01:43
Bug Closed. :)