Buggle Dance Revolution (BDR)

After these races, it's time to party! For that, we will learn the buggles to play Dance Revolution, this game beloved of some students: The player has to move the feet on the carpet according to the instructions presented on the screen, and following the music. But before that, we have some details to study first.

[!java|scala|c]

Condizioni senza parentesi graffe

C'è un dettaglio che abbiamo omesso sulla sintassi delle condizioni: se il blocco di una delle alternative di una condizione contiene una sola istruzione le parentesi graffe diventano opzionali. Quindi, questi due pezzi di codice sono equivalenti:

if (condizione) {
    cosaFareACondizioneTrue();
} else {
    cosaFareAltrimenti();
}
if (condizione) 
    cosaFareACondizioneTrue();
else
    cosaFareAltrimenti();

È possibile fare lo stesso per il corpo dei cicli contenenti una sola istruzione. Fate attenzione, questo diventa pericoloso se connettete più istruzioni if come in questo esempio:

if (isOverBaggle())    
     if (x == 5)
          left();
else
     right();
[!c]stepForward();[/!][!java|scala]forward();[/!]

Infatti, il buggle non gira a destra quando non ci sono baggle a terra ma quando il buggle trova un baggle a terra e x è diverso da 5. In altre parole, il buggle capisce il precedente codice come quello scritto quì sotto (nota che l'else è spostato più a destra):

if (isOverBaggle())    
        if (x == 5)
            left();
        else
            right();
[!c]stepForward();[/!][!java|scala]forward();[/!]

La prima lezione da imparare è che l'indentazione è molto importante per aiutare le persone a capire anche se non cambia il significato del codice. Avremmo potuto scrivere il codice seguente ottenendo lo stesso risultato. Ma se volete che un umano legga e revisioni il vostro codice lo dovete indentare correttamente. Ad esempio se voleste che un professore legga il vostro codice (per valutarlo oppure rispondere ad una domanda su di esso) oppure se voleste riusarlo più tardi o doveste debuggarlo (correggerlo) da soli.

if (isOverBaggle()) if (x == 5) left(); else right(); [!c]stepForward();[/!][!java|scala]forward();[/!]

La seconda lezione da imparare è che l'alternativa else è sempre connessa alla if più vicina. Questo potrebbe essere un po' fastidioso in certi casi e potrebbe essere meglio aggiungere più parentesi di quelle che sono strettamente necessarie per rimuovere ogni ambiguità.

[/!]

Concatenamenti delle condizioni

A volte vorrete chiedere al buggle qualcosa come questo:

se piove prendi l'ombrello;
altrimenti se è un giorno caldo prendi una bottiglia d'acqua;
altrimenti se è il 4 luglio prendi la bandiera americana

Il punto è che vogliamo che solo una di queste azioni venga intrapresa. Vale a dire che se sta piovendo in un 4 luglio veramente caldo noi non vogliamo che il buggle esca con un ombrello, dell'acqua ed una bandiera ma solo con l'ombrello. Il seguente codice è quindi SBAGLIATO

[!scala|c|java]if (rainy())
    takeUmbrella();
if (hot())
    takeWater();
if (todayIsJuly4th())
    takeFlag();[/!][!python]if rainy():
    takeUmbrella()
if hot():
    takeWater()
if todayIsJuly4th():
    takeFlag()[/!]

Poiché le condizioni sono valutate una dopo l'altra, c'è il rischio che si vada a marciare il 4 luglio sotto la pioggia. Invece dovremo utilizzare qualcosa come questo per assicurarci che quando avremo trovato una condizione vera non venga valutata la successiva.

[!java|scala|c]if (rainy()) {
    takeUmbrella();
} else {
    if (hotDay()) {
        takeWater();
    } else {
        if (todayIsJuly4th()) {
            takeFlag();
        }
    }
}[/!][!python]if rainy():
    takeUmbrella()
else:
    if hotDay():
        takeWater()
    else:
        if todayIsJuly4th():
            takeFlag()[/!]

Unfortunately, such a cascade of conditionals is quite difficult to read. It is better to [!java|scala|c]omit the curly braces for the else statements. Some languages even introduce a specific construct for these else if, but not [!thelang].[/!] [!python]change the sub-blocks using the elif keyword to mark explicitly these "else if" branches.[/!]

[!c|java|scala]if (rainy()) { 
    takeUmbrella();
} else if (hotDay()) {
    takeWater();
} else if (todayIsJuly4th()) {
    takeFlag();
}[/!][!python]if rainy():
    takeUmbrella()
elif hotDay():
    takeWater()
elif todayIsJuly4th():
    takeFlag()[/!]

Graffiti nel Mondo dei Buggle

I Buggle possono marchiare graffiti sul terreno del proprio mondo. Per questo essi usano i seguenti quattro metodi:

Traguardo dell'esercizio

Lo scopo è quello di organizzare un gioco BDR fra i buggle insegnandogli a muoverein accordo con le isturzioni scritte a terra. Queste istruzioni sono messaggi scritti a terra con il seguente significato:
Messaggi Cosa fa Mnemonico
[!java|c]'R'[/!][!scala|python]"R"[/!]Gira a destra e muoviti un passo in avantiRight
[!java|c]'L'[/!][!scala|python]"L"[/!]Gira a sinistra e muoviti un passo in avantiLeft
[!java|c]'I'[/!][!scala|python]"I"[/!]Gira indietro (curva a U) e muoviti un passo in avantiInverse
[!java|c]'A'[/!][!scala|python]"A"[/!]Muoviti un passo avantiPrima lettera dell'alfabeto
[!java|c]'B'[/!][!scala|python]"B"[/!]Muoviti due passi in avantiSeconda lettera dell'alfabeto
[!java|c]'C'[/!][!scala|python]"C"[/!]Muoviti tre passi in avantiTerza lettera dell'alfabeto
[!java|c]'Z'[/!][!scala|python]"Z"[/!]Muoviti un passo indietroUltima lettera dell'alfabeto
[!java|c]'Y'[/!][!scala|python]"Y"[/!]Muoviti due passi indietroPenultima lettera dell'alfabeto
[!java|c]'X'[/!][!scala|python]"X"[/!]Muoviti tre passi indietroTerzultima lettera dell'alfabeto
(qualsiasi altra cosa)Fine delle danze

Indicazioni

Questo esercizio potrebbe sembrare un po' complesso ad una prima occhiata ma si tratta solo di riassumere le informazioni della tabella in una sequenza di istruzioni condizionali.

You have to keep dancing as long as there is some dancing steps to do, i.e., as long as we are in a cell which content is described in the table. The easier for that is to use a boolean variable (finished) as termination condition to a while loop. It should be initialized to [!c]0[/!][!java|scala]false[/!][!python]False[/!], and switched to [!c]1[/!][!java|scala]true[/!][!python]True[/!] as soon as the buggle find a cell with a value not described in the table. Thus, the loop will stop and the program will terminate.

[!java|c]

Another subtlety is that detecting if strings are equals is a bit annoying in [!thelang]. So, we use the char getIndication[!c]Bdr[/!]() instead of [!java]String[/!][!c]char*[/!] readMessage(). This method, only known by the buggles of this exercise, returns the first char of the message written on the ground (or ' ' -- the space char -- if nothing is written down). It enables to work with chars instead of strings, that is much simpler in [!thelang].

[/!]

Consigli e Suggerimenti

Se fallite nel capire perché il buggle non esegue i passi aspettati, provate ad aggiungere brushDown() nel vostro metodo. Questo chiede al buggle abbassare il pennello lasciando una traccia quando si muove. Questo dovrebbe aiutarvi a capire la sua traiettoria ma non dimenticate di rimuovere questa chiamata quando vorrete testare se il vostro codice è una soluzione valida all'esercizio: state chiedendo al buggle di danzare non di vandalizzare la pista da ballo!

Quando il vostro programma finalmente funzionerà, muovetevi nel prossimo esercizio.