## Buggle Dance Revolution 2 (BDR2)

[!java|scala|c]

BDR é legal, mas um pouco caótico. Primeiro, os buggles balançam em todas as direções, o que faz com que o código que você tenha que escrever para fazê-los se mover seja um pouco difícil de ler. Apresentamos agora um novo mundo DBR onde os buggles dançam num suave círculo. Vamos aproveitar esta tranquilidade para limpar um pouco nosso código graças a novas construções que vamos introduzir.

### [!java|c]condicionais `switch`[/!][!scala]busca de padrões[/!]

A parte mais difícil do código anterior é comn certeza a cascata de condicionais. Em algum ponto do seu código, você certamente tem algo como isto:

    if ([!java|c]getIndicação() == 'R'[/!][!scala]lerMensagem() == "R"[/!]) {
      direita();
      [!c]avançarUmPasso()[/!][!java|scala]avançar()[/!];
    } else if ([!java|c]getIndicação() == 'L'[/!][!scala]lerMensagem() == "L"[/!]) {
      esquerda();
      [!c]avançarUmPasso()[/!][!java|scala]avançar()[/!];
    } else if ([!java|c]getIndicação() == 'I'[/!][!scala]lerMensagem() == "I"[/!]) {
      voltar();
      [!c]avançarUmPasso()[/!][!java|scala]avançar()[/!];
    /* other else if */
    } else {
      terminou = [!c]1[/!][!java|scala]true[/!];
    }

Quando você revisa este código, não fica claro à primeira vista que ele é simplesmente a escolha entre quatro ramos dependendo do valor de [!java|c]getIndicação()[/!][!scala]lerMensagem()[/!]. Para melhorar ele, vamos usar uma construção [!java|c]`switch`, que na sintaxe de Java é o seguinte:[/!] [!scala] de busca de padrões, que é bastante poderosa e generaliza muito o `if`. É com certeza uma das maiores vantagens de Scala quando comparada com linguagens como Java ou python. E nem é tão nova assim, já que outras linguagens como OCaml e Haskell já tem esta funcionalidade a muito tempo. Ela é bem legal![/!]

[/!] [!java|c]

    switch (expression) {
      case firstValue:
        whatToDoIfExpressionEqualsFirstValue();
        break;
      case secondValue:
        whatToDoIfExpressionEqualsSecondValue();
        break;
      case thirdValue:
        whatToDoIfExpressionEqualsThirdValue();
        break;
        /* as much similar cases as you want */
      default:
        whatToDoIfExpressionDoesNotEqualsAnySeenValues();
    }

Observe que cada ramo de um `switch` deve terminar com um `break`. se você esquecer dele, a máquina continua e executa o próximo ramo na lista depois do ramo para o qual ele pulou. Existem na verdade uns raros casos onde este comportamento é útil.

É então possível reescrever o código do BDR anterior numa forma mais clara usando a construção `switch`:

    switch (getIndicação()) {
      case 'R':
        direita();
        [!c]avançarUmPasso()[/!][!java]avançar()[/!];
        break;
      case 'L':
        esquerda();
        [!c]avançarUmPasso()[/!][!java]avançar()[/!];
        break;
      case 'I':
        voltar();
        [!c]avançarUmPasso()[/!][!java]avançar()[/!];
        break;
      default:
        return;
    }

[/!] [!scala]

    expressão match {
      case um valor possível => instruções
      case um outro valor     => outras instruções
      case mais outro valor => e outras instruções
      case _                 => instruções padrão
    }

A espressão fornecida antes da palavra-chave `match`, e os ramos seguintes são avaliados um após o outro até encontrarmos um cujo valor fornecido entre `case` e `=>` seja igual ao valor da expressão. O símbolo `_` age como um coringa, logo o ramo `_` sempre casa. Aqui está um exemplo de onde uma variável `name` casa.

    name match {
      case "Martin" => println("Oi Martin, como vai?")
      case "Gerald" => println("Oi Gerald! como vai você?")
      case _            => println("Olá estranho.")
    }

é possível ter mais que uma instrução por ramo, e mesclar ramos quando os valores são separados por um símbolo | .

    name match {
      case "Martin" | "Gerald" => println("Oi "+name+", como vai?"); openTheDoor()
      case _                            => println("Oi estranho. Favor não passar."); lockTheDoor()
    }

Você sempre pode adicionar guardas aos seus ramos. Estes são condições extra que devem ser respeitadas para que o ramo seja feito. São úteis se você quiser casar em intervalos de valores, como segue.

    age match {
      case i if i<10 => println("Oi menino!")
      case i if i<20 => println("Oi cara!")
      case i if i<30 => println("Oi, meu caro")
      case _           => println("Oi senhor")
    }

Observe que não há necessidade de verificar se o valor é maior que 10 na segunda linha por que o primeiro ramo "foi verificado". Então, se o segundo ramo está sendo verificado, o primeiro não aprovou.

Finalmente, é possível também aprovar várias variáveis de uma vez!

    (x,y) match {
     case (0,0) => println("Esta é a origem")
     case (_,0) => println("nas ordenadas")
     case (0,_) => println("nas abscissas")
     case (_,_) => println("algum ponto qualquer")
    }

Eu disse que reconhecimentod e padrões em scala é muito poderoso! Eu adoro esta funcionalidade!

[/!]

### Objetivo do exercício

[!java|scala|c]"Aplique" a melhoria que acabamos de ver para reescrever seu código do buggle com os seguintes passos de dança. [/!] [!python]Vamos ensinar um novo passo de dança para os buggles. É um pouco mais complexo mas na verdade vai ficar mais legal. Apesar disto, é a mesma história de sempre.[/!] Observe que nósagora vamos subir seis células em um passo de dança.

Mensagem | O que fazer
[!java|c]'R'[/!][!scala|python]"R"[/!] | Vire a direita (R de right) e mova um passo a frente
[!java|c]'L'[/!][!scala|python]"L"[/!] | Vire a esquerda e mova um passo a frente
[!java|c]'I'[/!][!scala|python]"I"[/!] | Vire e dê um passo para frente
[!java|c]'A'[/!][!scala|python]"A"[/!] | Mova um passo a frente
[!java|c]'B'[/!][!scala|python]"B"[/!] | Mova dois passos a frente
[!java|c]'C'[/!][!scala|python]"C"[/!] | Mova três passos a frente
[!java|c]'D'[/!][!scala|python]"D"[/!] | Mova quantro passos para frente
[!java|c]'E'[/!][!scala|python]"E"[/!] | Mova cinco passos para frente
[!java|c]'F'[/!][!scala|python]"F"[/!] | Mova seis passos para frente
[!java|c]'Z'[/!][!scala|python]"Z"[/!] | Mova um passo para trás
[!java|c]'Y'[/!][!scala|python]"Y"[/!] | Mova dois passos para trás
[!java|c]'X'[/!][!scala|python]"X"[/!] | Mova três passos para trás
[!java|c]'W'[/!][!scala|python]"W"[/!] | Mova quatro passos para trás
[!java|c]'V'[/!][!scala|python]"V"[/!] | Mova cinco passos para trás
[!java|c]'U'[/!][!scala|python]"U"[/!] | Mova seis passos para trás
(qualquer outra coisa) | Parar de dançar.

Quando seu programa funcionar de novo, vá para o próximo exercício.