Blackjack

Blackjack

Exercício de aprendizagem

Introdução

case (muitas vezes chamado de switch em outras linguagens) é uma forma de expressão de controle, como o if-else. O case permite encadear várias instruções if-else-if, pode ser mais legível e permite construções poderosas.

Um case é definido pela palavra-chave case seguida de uma expressão opcional. Depois, para cada caso, usa-se a palavra-chave when seguida de uma expressão que é comparada à expressão do case. A palavra-chave when não deve ser indentada em relação à palavra-chave case. Depois da palavra-chave when vem o código que deve ser executado se a expressão do case corresponder à expressão do when. O case permite uma cláusula else opcional, que é executada se nenhum outro caso corresponder.

A expressão do case é avaliada e depois comparada com cada expressão do when. A comparação é feita com o operador de subsunção do case (===).

case 1
when 1
  puts "One"
when 2
  puts "Two"
else
  puts "Other"
end
# => One

# This is the same as:
tmp = 1
if 1 === tmp
  puts "One"
elsif 2 === tmp
  puts "Two"
else
  puts "Other"
end

Operador de subsunção do case (===)

O operador de subsunção do case (===) é um pouco diferente do operador de igualdade (==). O operador verifica se o lado direito é um membro do conjunto descrito pelo lado esquerdo. Isso significa que a posição de cada operando faz diferença. Como isso funciona depende do tipo do lado esquerdo. Por exemplo, um Range verificaria se o lado direito está no intervalo, ou um Object verificaria se o lado direito é uma instância de Object.

(1..3) == 1  # => false
(1..3) === 1 # => true

String == "foo"  # => false
String === "foo" # => true

case com várias expressões

O case permite corresponder várias expressões em um único caso, com cada valor possível separado por vírgula. O código será executado se qualquer uma das expressões corresponder. Isso pode ser útil para um único caso com vários valores possíveis.

case 1
when 1, 2
  puts "One or two"
else
  puts "Other"
end

case com intervalos

O case também pode verificar se um valor está em um intervalo. Isso é feito usando um intervalo como expressão do when.

case var
when 1..3
  puts "One to three"
else
  puts "Other"
end

case sem expressão do case

Quando não há necessidade de uma expressão do case, é possível omiti-la. Ao fazer isso, cada expressão do case é avaliada quanto à veracidade. E faz com que se comportem como instruções if-else-if.

case
when 1 == 1
  puts "One is equal to one"
when 1 > 2
  puts "One is greater than two"
else
  puts "Other"
end

when em uma única linha

O Crystal permite instruções case de uma única linha. Isso pode ser usado quando você tem uma instrução simples de uma única linha. A instrução when de uma única linha é escrita como when <expression> then <statement>. E quando usada na cláusula else, ela é escrita como else <statement>.

case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end

case com tipos

O case permite fazer correspondência com tipos. A comparação usa o operador is_a? para verificar o tipo da variável. Por exemplo, isso permite um bloco para cada tipo em uma união de tipos.

case var
when Int32
  puts "Int32"
when String
  puts "String"
else
  puts "Other"
end

Objeto implícito

O case permite o uso de um objeto implícito. Isso permite, por exemplo, que uma expressão do when seja uma chamada de método na expressão do case. Dependendo de o método retornar um valor verdadeiro ou falso, o case corresponderá ou não.

case 1
when .odd?
  puts "Odd"
when .even?
  puts "Even"
end

Instruções

Neste exercício, vamos simular o primeiro turno de uma partida de Blackjack.

1. Calcule o valor de qualquer carta.

Você vai receber duas cartas e poderá ver a carta virada para cima do dealer. Todas as cartas são representadas por uma string como "ace", "king", "three", "two", etc. Os valores de cada carta são:

carta valor carta valor
ace 11 eight 8
two 2 nine 9
three 3 ten 10
four 4 jack 10
five 5 queen 10
six 6 king 10
seven 7 other 0
Note

Normalmente, os ases podem valer 1 ou 11, mas, para simplificar, vamos assumir que eles só podem valer 11.

Implemente o método Blackjack.parse_card, que recebe uma carta em forma de string como argumento. O método deve retornar o valor da carta como um número inteiro.

Blackjack.parse_card("ace")
# => 11

2. Nomeie faixas de valores.

A pontuação do jogador precisa ser categorizada em faixas de valores. A pontuação do jogador é calculada somando os valores das duas cartas do jogador. As faixas usadas são:

faixa valor
low [4, 11]
mid [12, 16]
high [17, 20]
blackjack [21]

Implemente o método Blackjack.card_range, que recebe duas cartas em forma de string como argumentos. O método deve retornar o nome da faixa de valores em que as duas cartas se encaixam.

Blackjack.card_range("ten", "king")
# => "high"

3. Implemente a lógica de decisão para o primeiro turno.

Dependendo das suas duas cartas e da carta do dealer, existe uma estratégia para o primeiro turno do jogo, na qual você tem as seguintes opções:

  • Parar (S)
  • Pedir carta (H)
  • Dividir (P)
  • Ganhar automaticamente (W)

Embora ainda não seja ideal, você vai seguir a estratégia que seu amigo Alex vem desenvolvendo, que é a seguinte:

  • Se você tiver um par de ases, sempre divida.
  • Se você tiver um Blackjack (duas cartas que somam um valor de 21), e o dealer não tiver um ás, uma figura ou um dez, você ganha automaticamente. Se o dealer tiver alguma dessas cartas, você terá que parar e esperar a revelação da outra carta.
  • Se as suas cartas somarem um valor dentro da faixa [17, 20], você deve sempre parar.
  • Se as suas cartas somarem um valor dentro da faixa [12, 16], você deve sempre parar, a menos que o dealer tenha um 7 ou mais, caso em que você deve sempre pedir carta.
  • Se as suas cartas somarem 11 ou menos, você deve sempre pedir carta.

Implemente o método Blackjack.first_turn, que recebe três cartas em forma de string como argumentos. O método deve retornar a decisão que você deve tomar como uma string.

Blackjack.first_turn("ace", "ace", "two")
# => "P"
Editar via GitHub O link abre em uma nova janela ou aba
Crystal Exercism

Tudo pronto para começar Blackjack?

Crie sua conta no Exercism para aprender e dominar Crystal com 26 conceitos142 exercícios e mentoria humana de verdade, tudo de graça.