Trilhas
/
Crystal
Crystal
/
Exercícios
/
Jogo de xadrez
Jogo de xadrez

Jogo de xadrez

Exercício de aprendizagem

Introdução

Intervalos representam um intervalo entre dois valores. Os tipos mais comuns que dão suporte a intervalos são Int, Char e String. Eles podem ser usados para muitas coisas, como criar uma coleção rapidamente, fatiar strings, verificar se um valor está em um intervalo e iterar. Eles são criados com o operador de intervalo .. ou ... (inclusivo e exclusivo, respectivamente).

1..5  # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4

O motivo de existirem dois operadores de intervalo é criar intervalos que incluem ou excluem o valor final, o que pode ser útil quando, por exemplo, você trabalha com índices que começam em zero.

Intervalos também podem ser criados com o inicializador Range.

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

Quando você cria um intervalo em Crystal com os operadores de intervalo .. ou ... e quer chamar um método nele, precisa envolver o intervalo entre parênteses. Isso acontece porque, caso contrário, o método seria chamado no segundo argumento do operador de intervalo.

(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32

Obtendo substrings

Quando você quer fatiar uma string, pode usar o operador de intervalo para obter uma substring. Ou seja, criando um intervalo com os índices inicial e final da substring.

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

Você também pode usar índices negativos para obter a substring a partir do fim da string.

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

Métodos de intervalo

Intervalos têm um conjunto de métodos que podem ser usados para trabalhar com eles. Por exemplo, esses métodos podem ser usados para obter a soma de todos os valores do intervalo ou verificar se o intervalo inclui um valor.

Método Descrição Exemplo
sum Retorna a soma de todos os valores do intervalo (1..5).sum # => 15
size Retorna o tamanho do intervalo (1..5).size # => 5
includes? Retorna true se o intervalo inclui o valor fornecido, caso contrário false (1..5).includes?(3) # => true

Intervalos sem fim e sem início

Um intervalo pode ser sem fim e sem início. O intervalo sem fim ou sem início tem seu valor inicial ou final como nil, mas nil pode ser omitido ao definir o intervalo.

Usar intervalos sem início e sem fim é útil quando você quer, por exemplo, fatiar uma string do começo ou até o fim.

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
Caution

Se não for usado em uma coleção, o intervalo sem fim pode causar uma sequência sem fim, caso não seja usado com cuidado.

Intervalos de Char

Chars podem ser usados em intervalos e permitem obter um intervalo de chars entre dois chars. Por exemplo, isso pode ser útil quando você quer obter o alfabeto.

'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']

Intervalos de String

Strings também podem ser usados em intervalos, permitindo obter um intervalo de strings entre duas strings. Mas o comportamento é um pouco diferente do de Char quando vários caracteres são usados em um intervalo de strings. O comportamento pode ficar confuso ao criar intervalos de strings mais complexos, então tome cuidado.

("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]

Instruções

Como entusiasta de xadrez, você quer escrever a sua versão do jogo. Sim, pode já haver várias implementações de xadrez disponíveis online, mas a sua vai ser única!

Você começa implementando um sistema básico de movimento para as peças.

O jogo de xadrez será disputado em um tabuleiro de oito casas de largura por oito casas de comprimento. As casas são identificadas por uma letra e um número.

1. Defina os intervalos de fileiras e colunas

O jogo vai precisar armazenar as fileiras do tabuleiro. As fileiras são as linhas do tabuleiro e são numeradas de 1 a 8.

O jogo também vai precisar armazenar as colunas do tabuleiro. As colunas são identificadas pelas letras de A a H.

Defina as constantes Chess::RANKS e Chess::FILES, que armazenam o intervalo de fileiras e de colunas, respectivamente.

Chess::RANKS
# => 1..8

Chess::FILES
# => 'A'..'H'

2. Verifique se uma casa é válida

O jogo vai precisar verificar se uma casa é válida. Uma casa é válida se a fileira e a coluna estiverem dentro dos intervalos das fileiras e das colunas.

Defina o método Chess.valid_square?, que recebe os argumentos rank, que contém um int da fileira, e file, que contém um char da coluna. O método deve retornar true se a fileira e a coluna estiverem dentro do intervalo das fileiras e das colunas, e retornar false caso contrário.

Chess.valid_square?(1, 'A')
# => true

3. Obtenha o apelido do jogador

O jogo vai precisar obter o apelido do jogador. O apelido é formado pelos dois primeiros caracteres do primeiro nome do jogador e pelos dois últimos caracteres do sobrenome. O apelido deve ser escrito em maiúsculas.

Defina o método Chess.nickname, que recebe os argumentos first_name, que contém uma string com o primeiro nome do jogador, e last_name, que contém uma string com o sobrenome do jogador. O método deve retornar o apelido do jogador como uma string em maiúsculas.

Chess.nickname("John", "Doe")
# => "JOOE"

4. Crie a mensagem de movimento

O jogo vai precisar criar uma mensagem para um movimento, dizendo qual jogador se moveu para qual casa. A mensagem deve usar o apelido do jogador e a casa para onde ele se moveu. O jogo também deve determinar se o movimento é válido, verificando se a coluna e a fileira da casa estão dentro dos intervalos das colunas e das fileiras.

Se o movimento for válido, a mensagem deve ser: "{nickname} moved to {square}" Se o movimento for inválido, a mensagem deve ser: "{nickname} attempted to move to {square}, but that is not a valid square"

Defina o método Chess.move_message, que recebe os argumentos first_name, que contém uma string com o primeiro nome do jogador, last_name, que contém uma string com o sobrenome do jogador, e square, que contém uma string com a casa para onde o jogador se moveu. O método deve retornar a mensagem do movimento como uma string.

Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
Editar via GitHub O link abre em uma nova janela ou aba
Crystal Exercism

Tudo pronto para começar Jogo de xadrez?

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