Depois destas corridas, é hora de festejar! Para isto, vamos ensinar os buggles a jogar Dance Revolution, este jogo amado por alguns estudantes: O jogador tem que mover os pés num carpete de acordo com as instruções apresentadas no ecrã e seguir a música. Mas antes disto, temos alguns detalhes para estudar primeiro.
[!java|scala|c]Existe um detalhe que omitimos sobre a sintaxe do condicional: se um ramo contém apenas uma instrução, então o colchetes se torna opcional. Portanto, estes dois pedaços de código são equivalentes:
if (condição) {
oQueFazerSeACondiçãoÉVerdadeira();
} else {
oQueFazerCasoContrário();
}
if (condição)
oQueFazerSeACondiçãoÉVerdadeira();
else
oQueFazerCasoContrário();
Na verdade, pode fazer o mesmo em corpos de loop que se reduzem a apenas uma instrução. Mas cuidado, isto torna-se perigoso se cadeiar as instruções if como a seguir:
if (isOverBaggle())
if (x == 5)
left();
else // Não escreva desta forma, é enganoso!
right();
[!c]stepForward();[/!][!java|scala]forward();[/!]
Pensa que right() se refere ao primeiro if e será
executado quando isOverBaggle() retorna false, mas, na verdade,
refere-se ao segundo if e será executado quando
isOverBaggle() retorna true e x != 5. Sim, apesar
da indentação, o buggle entende o código anterior da seguinte forma:
if (isOverBaggle())
if (x == 5)
left();
else
right();
[!c]stepForward();[/!][!java|scala]forward();[/!]
Em [!thelang] o computador conecta um ramo else ao if mais próximo. Se o achar ambíguo, deve adicionar mais aspas do que estritamente necessário. Os computadores nem sequer olham para a indentação em [!thelang]. O código anterior pode até ser escrito da seguinte forma e levar ao mesmo resultado.
if (isOverBaggle()) if (x == 5) left(); else right(); [!c]stepForward();[/!][!java|scala]forward();[/!]
Mas para humanos, realmente é melhor indentar o seu código corretamente. Por exemplo, se quer que um professor reveja ou mesmo avalie o seu código, se quer reutilizar o seu próprio código mais tarde, ou mesmo se precisa depurá-lo. Isso é certo: precisa escrever um código legível para o seu próprio conforto.
[/!]Algumas vezes quer perguntar o buggle algo similar a:
se está a chover, leve um guarda-chuva; se não e se está quente, leve uma garrafa de água; se não e se hoje é 4 de Julho, leve uma bandeira dos estados unidos
A armadilha é que queremos que pelo menos uma destas ações sejam feitas. É como dizer, se está a chover num 4 de Julho quente, não queremos que o buggle vá para fora com um guarda-chuva, água e um bandeira, mas simplesmente com um guarda-chuva. O código seguinte está, então, ERRADO.
[!scala|c|java]if (chuvoso())
pegueGuarda-Chuva();
if (quente())
pegueAgua();
if (hoje4Julho())
pegueBandeira();[/!][!python]if aChover():
pegueGuarda-Chuva()
if quente():
pegueAgua()
if hoje4Julho():
pegueBandeira()[/!]
Na verdade, já que as condições são calculadas uma depois da outra, existe um risco de que vá sair no die 4 de Julho num dia chuvoso. Na verdade, devemos usar algo como isto para garantir que uma vez que encontremos a condição verdadeira, não passemos às próximas.
[!java|scala|c]if (chuvoso()) {
levarGuardaChuva();
} else {
if (diaQuente()) {
levarAgua();
} else {
if (jogoDaCopa()) {
levarBandeira();
}
}
}[/!][!python]if chuvoso():
levarGuardaChuva()
else:
if diaQuente():
levarAgua()
else:
if jogoDaCopa():
levarBandeira()[/!]
Infelizmente, tal cascata de condicionais é bastante difícil de ler. É
melhor [!java|scala|c]omitir as chaves para as assertivas
else. Algumas linguagens até mesmo introduzem uma construção
específica para estes else if, mas não [!thelang].[/!]
[!python]mudar os sub-blocos a usar a palavra-chave elif para
marcar explicitamente estes ramos "else if".[/!]
[!c|java|scala]if (chuvoso()) {
levarGuardaChuva();
} else if (diaQuente()) {
levarAgua();
} else if (jogoDaCopa()) {
levarBandeira();
}[/!][!python]if chuvoso():
levarGuardaChuva()
elif diaQuente():
levarAgua()
elif jogoDaCopa():
levarBandeira()[/!]
Os buggles podem grafitar no chão do mundo deles. Para isto, use os quatro métodos seguintes:
[!c]int[/!][!java]boolean[/!]
isOverMessage()[!scala]:Boolean[/!]: returns
[!c]1[/!][!java|scala]true[/!][!python]True[/!] se e somente se
existe uma mensagem no chão.[!c]char*[/!][!java]String[/!] readMessage()[!scala]:
String[/!]: retorna a mensagem lida no chão (ou uma cadeia vazia se
não há nada escrito).[!java|c]void[/!] escreverMensagem([!c]char*[/!][!java]String
[/!]msg[!scala]: String[/!]): escreve a mensagem especificada no
chão. Se já existe uma mensagem no chão, a nova é adicionada no final da
mensagem existente.[!java|c]void [/!]clearMessage(): limpa o que está escrito no
chão.| Mensagem | O que fazer | Mnemônico |
| [!java|c]'R'[/!][!scala|python]"R"[/!] | Vire a direita (R de right) e mova um passo a frente | Direita |
| [!java|c]'L'[/!][!scala|python]"L"[/!] | Vire a esquerda e mova um passo a frente | Esquerda |
| [!java|c]'I'[/!][!scala|python]"I"[/!] | Vire para trás (meia-volta) e mova um passo a frente | Inversa |
| [!java|c]'A'[/!][!scala|python]"A"[/!] | Mova um passo a frente | Primeira letra do alfabeto |
| [!java|c]'B'[/!][!scala|python]"B"[/!] | Mova dois passos a frente | Segunda letra do alfabeto |
| [!java|c]'C'[/!][!scala|python]"C"[/!] | Mova três passos a frente | Terceira letra do alfabeto |
| [!java|c]'Z'[/!][!scala|python]"Z"[/!] | Mova um passo para trás | última letra do alfabeto |
| [!java|c]'Y'[/!][!scala|python]"Y"[/!] | Mova dois passos para trás | penúltima letra do alfabeto |
| [!java|c]'X'[/!][!scala|python]"X"[/!] | Mova três passos para trás | Antepenúltima letra do alfabeto |
| (qualquer outra coisa) | Parar de dançar. |
Tem que se manter a dançar enquanto houverem passos de dança para fazer,
p.ex., enquanto estivermos numa célula cujo conteúdo esteja contido na
tabela. a forma mais fácil de fazer isto é a usar uma variável booleana
(terminou) como condição de término para o loop
while. Ela deve ser iniciada como
[!c]0[/!][!java|scala]false[/!][!python]False[/!] e trocada
para [!c]1[/!][!java|scala]true[/!][!python]True[/!] assim que
o buggle encontre uma célula com um valor não descrito na tabela. Assim, o
loop pára e o programa termina.
Outro detalhe é que detetar se cadeias são iguais é um pouco chato em
Java. Então, usamos o char getIndication[!c]Bdr[/!]() ao invés
do [!java]String[/!][!c]char*[/!] readMessage(). Este método,
conhecido apenas pelos buggles deste exercício, retorna o primeiro caractere
da mensagem escrita no chão (ou ' ' -- o caractere para espaço -- se não tem
nada escrito). Ele ativa que se trabalhe com caracteres ao invés de cadeias,
que é muito mais simples em [!thelang].
brushDown() no seu método. Isto pede ao buggle para
abaixar um pincel a deixar um rastro por onde passar. Isto pode ajudá-lo a
entender a trajetória dele, mas não se esqueça de remover esta chamada
quando quiser testar se o seu código é uma solução válida para o exercício:
pode fazer o buggle dançar, mas não pichar a pista de dança.
Quando seu programa finalmente funcionar, vá ao próximo exercício.