## 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 no ecrã e seguir a música. Mas antes disto, temos alguns detalhes para estudar primeiro.

[!java|scala|c]

### Condicionais sem colchetes

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.

[/!]

### Encadear condicionais

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

### Grafitagem no mundo dos Buggles

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.

### Objetivo do exercício

O objetivo é então organizar um jogo de BDR entre os buggles a ensinar 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 a resumir a informação na tabela numa sequência de condicionais.

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.

[!java|c]

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

[/!]

### Dicas

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