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.