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]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à.
[/!]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()[/!]
I Buggle possono marchiare graffiti sul terreno del proprio mondo. Per questo essi usano i seguenti quattro metodi:
[!c]int[/!][!java]boolean[/!]
isOverMessage()[!scala]:Boolean[/!]
: returns
[!c]1[/!][!java|scala]true[/!][!python]True[/!]
if and only if
there is a message on the ground.[!c]char*[/!][!java]String[/!] readMessage()[!scala]:
String[/!]
: returns the message written on the ground (or an empty
string if nothing is written).[!java|c]void[/!] writeMessage([!c]char*[/!][!java]String
[/!]msg[!scala]: String[/!])
: writes the specified message down on
the ground. If there is already a message on the ground, the new content is
added at the end of the existing message.[!java|c]void [/!]clearMessage()
: clears what is written on the
ground.Messaggi | Cosa fa | Mnemonico |
[!java|c]'R'[/!][!scala|python]"R"[/!] | Gira a destra e muoviti un passo in avanti | Right |
[!java|c]'L'[/!][!scala|python]"L"[/!] | Gira a sinistra e muoviti un passo in avanti | Left |
[!java|c]'I'[/!][!scala|python]"I"[/!] | Gira indietro (curva a U) e muoviti un passo in avanti | Inverse |
[!java|c]'A'[/!][!scala|python]"A"[/!] | Muoviti un passo avanti | Prima lettera dell'alfabeto |
[!java|c]'B'[/!][!scala|python]"B"[/!] | Muoviti due passi in avanti | Seconda lettera dell'alfabeto |
[!java|c]'C'[/!][!scala|python]"C"[/!] | Muoviti tre passi in avanti | Terza lettera dell'alfabeto |
[!java|c]'Z'[/!][!scala|python]"Z"[/!] | Muoviti un passo indietro | Ultima lettera dell'alfabeto |
[!java|c]'Y'[/!][!scala|python]"Y"[/!] | Muoviti due passi indietro | Penultima lettera dell'alfabeto |
[!java|c]'X'[/!][!scala|python]"X"[/!] | Muoviti tre passi indietro | Terzultima lettera dell'alfabeto |
(qualsiasi altra cosa) | Fine delle danze |
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.
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].
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.