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

Tabuleiro de xadrez

Exercício de aprendizagem

Introdução

Em Go, podes iterar sobre um slice com for e um índice, ou podes usar range. O range também te permite iterar sobre um map.

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

Iterar sobre um slice

Muito simples: iterar sobre um slice com um ciclo, pela 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 levanta 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 o resultado acima está incorreto, porque seria de esperar que o primeiro par chave/valor na declaração do map, 9 10, fosse o primeiro a ser impresso e não o último. No entanto, os maps não têm ordem 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 pela qual as entradas são visitadas é aleatória e não segue nenhum padrão específico. Isto significa que o resultado acima é possível, mas pode ser diferente daquele que obténs se tentares executar isto tu mesmo. Para saberes mais sobre isto, consulta Especificação da Linguagem Go: cláusula range.

Iteração com omissão da chave ou do valor

Em Go, uma variável não usada dá erro em tempo de compilação. Por vezes só precisas 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

Podes substituir o i por _, o que diz ao compilador que não usamos esse valor:

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

Se quiseres imprimir apenas o índice, podes 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

Definir tipos

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

type File []bool

File refere-se aqui a uma única coluna vertical de um tabuleiro de xadrez, normalmente identificada de A a H. Cada casa desta coluna é representada por um valor Boolean que indica se 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 associa identificadores de coluna a valores File. Cada File é um slice de Boolean que representa as casas de uma coluna do tabuleiro. Sem estas definições de tipo, board seria um map[string][]bool, o que tornaria mais difícil perceber o que estamos a representar.

Instruções

Como entusiasta de xadrez, gostarias de escrever a tua própria versão do jogo. Sim, já devem existir muitas implementações de xadrez disponíveis online, mas a tua vai ser única!

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

  • As linhas horizontais de casas, chamadas fileiras, estão numeradas de 1 a 8.
  • As linhas verticais de casas, chamadas colunas, são identificadas 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 de xadrez e uma coluna, conta quantas casas estão ocupadas

Implementa a função CountInFile(board Chessboard, file string) int. Deve contar o número total de casas ocupadas percorrendo um mapa. Devolve um número inteiro. Devolve uma contagem de zero (0) se a coluna indicada não existir no mapa.

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

2. Dado um tabuleiro de xadrez e uma fileira, conta quantas casas estão ocupadas

Implementa a função CountInRank(board Chessboard, rank int) int. Deve contar o número total de casas ocupadas percorrendo a fileira indicada. Devolve um número inteiro. Devolve uma contagem de zero (0) se a fileira indicada não for válida (não estiver entre 1 e 8, inclusive).

CountInRank(board, 2)
// => 1

3. Conta quantas casas existem no tabuleiro de xadrez indicado

Implementa a função CountAll(board Chessboard) int. Deve contar quantas casas existem no tabuleiro de xadrez e devolve um número inteiro. Como não precisas de verificar o conteúdo das casas, considera usar range omitindo tanto o index como o value.

CountAll(board)
// => 64

4. Conta quantas casas estão ocupadas no tabuleiro de xadrez indicado

Implementa a função CountOccupied(board Chessboard) int. Deve contar quantas casas estão ocupadas no tabuleiro de xadrez. Devolve um número inteiro.

CountOccupied(board)
// => 15
Editar via GitHub A ligação abre numa nova janela ou separador
Go Exercism

Estás pronto para começar Tabuleiro de xadrez?

Inscreve-te no Exercism para aprenderes e dominares Go com 34 conceitos166 exercícios, e mentoria humana real, tudo grátis.