## Buggle Dance Revolution (BDR)

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]

### Condicionais sem colchetes

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 (estáSobreBaggle())
         if (x == 5)
              esquerda();
    else
         direita();
    [!c]avançarUmPasso();[/!][!java|scala]avançar();[/!]

De fato, não é para virar à direita quando não existe baggle no chão E x é igual a 5, mas quando o buggle encontra um baggle no chão e x é diferente de 5. Colocando de outra forma, o buggle entende o código anterior como se ele fosse escrito da seguinte forma (note que o `else` foi movido para a direita):

    if (estáSobreBaggle())
            if (x == 5)
                esquerda();
            else
                direita();
    avançar();

A primeira lição a tirar daí é que identação é muito importante para ajudar os humanos a entender, mesmo que não mude o significado do código. Nós poderíamos ter escrito o seguinte código e teríamos obtido o mesmo resultado. Mas se você quer que um humano leia e revise seu código, você vai com certeza querer indentar ele corretamente. Este é o caso, por exemplo, se você quer que um professor leia ele (para dar nota ou tirar uma dúvida), ou se você quiser reutilizar seu código mais tarde, ou mesmo se você quiser depurar você mesmo seu código.

    if (estáSobreBaggle()) if (x == 5) esquerda(); else direita(); [!c]avançarUmPasso();[/!][!java|scala]avançar();[/!]

A segunda lição é que o ramo do `else` sempre se conecta ao `if` mais próximo. Isto pode se tornar confuso em alguns casos, e torna-se mais fácil adicionar mais chaves do que o estritamente necessário para remover quaisquer ambiguidades.

[/!]

### Encadeando condicionais

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()[/!]

### Grafitagem no mundo dos Buggles

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.

### Objetivo do exercício

O objetivo é então organizar um jogo de BDR entre os buggles ensinando eles a se mover de acordo com as instruções escritas no chão. Estas instruções são mensagens escritas no chão, com o seguinte significado:

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. |

### Indicações

Este exercício pode parecer um pouco complexo à primeira vista, mas ele vem para resumir a informação na tabela numa sequência de condicionais.

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.

[!java|c]

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].

[/!]

### Dicas

Se você não entendeu por que o buggle não fez os passos esperados, tente adicionar `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.