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 na tela, e seguir a música. Mas antes disto, temos alguns detalhes para estudar primeiro.
[!java|scala|c]Existe um detalhe que nós 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 (condition) { whatToDoIfTheConditionIsTrue(); } else { whatToDoElse(); }
if (condição) oQueFazerSeACondiçãoÉVerdadeira(); else oQueFazerCasoContrário();
Na verdade, você pode fazer o mesmo em corpos de loop que se reduzem a apenas uma instrução. Mas cuidado, isto se torna perigoso se sua cadeia de instruções if parece com isto:
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 (estáSobreBaggle()) if (x == 5) esquerda(); else direita(); avançar();
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 (estáSobreBaggle()) if (x == 5) esquerda(); else direita(); [!c]avançarUmPasso();[/!][!java|scala]avançar();[/!]
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.
[/!]Algumas vezes você quer perguntar ao buggle algo similar a:
se está chovendo, pegue um guarda-chuva; se não, e se está quente, pegue uma garrafa de água; se não e se hoje é 4 de Julho, pegue uma bandeira dos estados unidos
O armadilha é que nós queremos que pelo menos uma destas ações sejam feitas.É como dizer, se está chovendo 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 (chovendo()) pegueGuarda-Chuva(); if (quente()) pegueAgua(); if (hoje4Julho()) pegueBandeira();[/!][!python]if chovendo(): 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 você vá para a marcha de 4 de Julho num dia chuvoso. Na verdade, nós devemos usar algo como isto para garantir que uma vez que encontremos a condição verdadeira, não passemos para as próximas.
[!java|scala|c]if (chuvoso()) { pegarGuardaChuva(); } else { if (diaQuente()) { pegarAgua(); } else { if (jogoDaCopa()) { pegarBandeira(); } } }[/!][!python]if chuvoso(): pegarGuardaChuva() else: if diaQuente(): pegarAgua() else: if jogoDaCopa(): pegarBandeira()[/!]
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 usando a palavra-chave elif
para
marcar explicitamente estes ramos "else if".[/!]
[!c|java|scala]if (chuvoso()) { pegarGuardaChuva(); } else if (diaQuente()) { pegarAgua(); } else if (jogoDaCopa()) { pegarBandeira(); }[/!][!python]if chuvoso(): pegarGuardaChuva() elif diaQuente(): pegarAgua() elif jogoDaCopa(): pegarBandeira()[/!]
Os buggles podem grafitar no chão de seu mundo. Para isto, use os quatro métodos seguintes:
[!c]int[/!][!java]boolean[/!]
estaSobreMensagem()[!scala]:Boolean[/!]
: returns
[!c]1[/!][!java|scala]true[/!][!python]True[/!]
se e somente se
existe uma mensagem no chão.[!c]char*[/!][!java]String[/!] lerMensagem()[!scala]:
String[/!]
: retorna a mensagem lida no chão (ou uma string 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 [/!]limparMensagem()
: 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. |
Você tem que se manter dançando enquanto houverem passos de dança para
fazer, i.e., enquanto estivermos numa célula cujo conteúdo esteja contido na
tabela. a forma mais fácil de fazer isto é usando 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 detectar se strings são iguais é um pouco chato em
Java. Então, usamos o char getIndication[!c]Bdr[/!]()
ao invés
do [!java]String[/!][!c]char*[/!] lerMensagem()
. 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 habilita que se trabalhe com caracteres ao invés de
strings, que é muito mais simples em [!thelang].
abaixarPincel()
no seu método. Isto pede ao buggle
para abaixar um pincel deixando um rastro por onde passar. Isto pode ajudar
você a entender a trajetória dele, mas não esqueça de remover esta chamada
quando você quiser testar se seu código é uma solução válida para o
exercício: você pode fazer o buggle dançar, mas não pichar a pista de dança.
Quando seu programa finalmente funcionar, vá para o próximo exercício.