Oggi è un grande giorno: noi insegneremo a ballare la Dance Revolution ai buggle, questo gioco è amato da molti studenti, i partecipanti devono muovere i propri piedi sul tappeto in accordo con le istruzioni presentate sullo schermo e seguendo la musica. Ma prima di questo dobbiamo studiare alcuni dettagli.
[!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 // Do not write it this way, it's misleading! right(); [!c]stepForward();[/!][!java|scala]forward();[/!]
You think that right()
refers to the first if
and
get executed when isOverBaggle()
returns false, but in fact, it
refers to the second one if
and will be executed when
isOverBaggle()
returns true and x != 5
. Yes,
despite the indentation, the buggle understands the previous code as
follows:
if (isOverBaggle()) if (x == 5) left(); else right(); [!c]stepForward();[/!][!java|scala]forward();[/!]
In [!thelang] the computer connects a else branch to the closest if. If you find it ambiguous, you should add more braces than strictly necessary. Computers don't even look at the indentation in [!thelang]. The previous code could even be written as follows and lead to the same result.
if (isOverBaggle()) if (x == 5) left(); else right(); [!c]stepForward();[/!][!java|scala]forward();[/!]
But for humans, you really want to indent your code correctly correctly. For example if you want a professor to review or even grade your code, if you want to reuse your own code later, or even if you need to debug it. That is right: you need to write readable code for your own comfort.
[/!]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.