Trilhas
/
Go
Go
/
Exercícios
/
Tabuleiro de xadrez
Tabuleiro de xadrez

Tabuleiro de xadrez

Exercício de aprendizagem

Introdução

Em Go, você pode iterar sobre um slice usando for e um índice, ou pode usar range. O range também permite iterar sobre um map.

Cada iteração retorna dois valores: o índice/chave e uma cópia do elemento nesse índice/chave.

Iterar sobre um slice

Mamão com açúcar: iterar sobre um slice segue a ordem esperada.

xi := []int{10, 20, 30}
for i, x := range xi {
  fmt.Println(i, x)
}
// outputs:
// 0, 10
// 1, 20
// 2, 30

Iterar sobre um map

Iterar sobre um map traz um novo problema. A ordem agora é aleatória.

hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
  fmt.Println(k, v)
}
// outputs, for example:
// 99 20
// 999 30
// 9 10
Note

Pode parecer que a saída acima está incorreta, já que seria de esperar que o primeiro par chave/valor da declaração do map, 9 10, fosse o primeiro a ser impresso, e não o último. No entanto, maps são desordenados por natureza: não existe um primeiro nem um último par chave/valor. Por isso, ao iterar sobre as entradas de um map, a ordem em que as entradas serão visitadas é aleatória e não segue nenhum padrão específico. Isso significa que a saída acima é possível, mas pode ser diferente da que você obtém se tentar rodar isso por conta própria. Para saber mais sobre isso, veja Especificação da linguagem Go: cláusula range.

Iteração omitindo a chave ou o valor

Em Go, uma variável não utilizada gera um erro em tempo de compilação. Às vezes você só precisa do valor, como no primeiro exemplo:

xi := []int{10, 20, 30}
for i, x := range xi {
  fmt.Println(x)
}
// Go build failed: i declared but not used

Você pode substituir o i por _, o que diz ao compilador que não usamos aquele valor:

xi := []int{10, 20, 30}
for _, x := range xi {
  fmt.Println(x)
}
// outputs:
// 10
// 20
// 30

Se você quiser imprimir apenas o índice, pode substituir o x por _ ou simplesmente omitir a declaração:

xi := []int{10, 20, 30}
// for i, _ := range xi {
for i := range xi {
  fmt.Println(i)
}
// outputs:
// 0
// 1
// 2

Definindo tipos

Uma definição de tipo cria um novo tipo nomeado, distinto de qualquer outro tipo, mesmo daquele com o mesmo tipo subjacente.

type File []bool

Aqui, File se refere a uma única coluna vertical de um tabuleiro de xadrez, normalmente rotulada de A a H. Cada casa dessa coluna é representada por um valor Boolean que indica se ela está ocupada ou não. Agora que File está definido, podemos usá-lo dentro de outras definições:

type Chessboard map[string]File

board := Chessboard{
    "A": File{true, false, true},
    "B": File{false, true, false},
}

Chessboard mapeia identificadores de colunas para valores File. Cada File é um slice de Booleans que representa as casas de uma coluna do tabuleiro. Sem essas definições de tipo, board seria um map[string][]bool, o que tornaria mais difícil entender o que estamos representando.

Instruções

Como entusiasta de xadrez, você gostaria de escrever sua própria versão do jogo. Sim, já deve existir por aí um monte de implementações de xadrez disponíveis online, mas a sua vai ser única!

Cada casa do tabuleiro é identificada por um par letra-número:

  • As linhas horizontais de casas, chamadas fileiras, são numeradas de 1 a 8.
  • As colunas verticais de casas, chamadas colunas, são rotuladas de A a H.
   A B C D E F G H
 8 # _ _ _ # _ _ # 8
 7 _ _ _ _ _ _ _ _ 7
 6 _ _ _ _ # _ _ # 6
 5 _ # _ _ _ _ _ # 5
 4 _ _ _ _ _ _ # # 4
 3 # _ # _ _ _ _ # 3
 2 _ _ _ _ _ _ _ # 2
 1 # _ _ _ _ _ _ # 1
   A B C D E F G H

1. Dado um tabuleiro e uma coluna, conte quantas casas estão ocupadas

Implemente a função CountInFile(board Chessboard, file string) int. Ela deve contar o número total de casas ocupadas iterando sobre um map. Retorne um número inteiro. Retorne uma contagem de zero (0) se a coluna informada não for encontrada no map.

CountInFile(board, "A")
// => 3

2. Dado um tabuleiro e uma fileira, conte quantas casas estão ocupadas

Implemente a função CountInRank(board Chessboard, rank int) int. Ela deve contar o número total de casas ocupadas iterando sobre a fileira informada. Retorne um número inteiro. Retorne uma contagem de zero (0) se a fileira informada não for válida (não estiver entre 1 e 8, inclusive).

CountInRank(board, 2)
// => 1

3. Conte quantas casas estão presentes no tabuleiro informado

Implemente a função CountAll(board Chessboard) int. Ela deve contar quantas casas estão presentes no tabuleiro e retorna um número inteiro. Como você não precisa verificar o conteúdo das casas, considere usar range omitindo tanto o index quanto o value.

CountAll(board)
// => 64

4. Conte quantas casas estão ocupadas no tabuleiro informado

Implemente a função CountOccupied(board Chessboard) int. Ela deve contar quantas casas estão ocupadas no tabuleiro. Retorne um número inteiro.

CountOccupied(board)
// => 15
Editar via GitHub O link abre em uma nova janela ou aba
Go Exercism

Tudo pronto para começar Tabuleiro de xadrez?

Crie sua conta no Exercism para aprender e dominar Go com 34 conceitos166 exercícios e mentoria humana de verdade, tudo de graça.