Parcours
/
Go
Go
/
Exercices
/
Échiquier
Échiquier

Échiquier

Exercice d'apprentissage

Introduction

En Go, on peut parcourir un slice avec for et un indice, ou bien utiliser range. range permet aussi de parcourir une map.

Chaque itération renvoie deux valeurs : l'indice ou la clé, ainsi qu'une copie de l'élément situé à cet indice ou à cette clé.

Parcours un slice

Simple comme bonjour : une boucle sur un slice suit l'ordre attendu.

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

Parcours une map

Parcourir une map pose un nouveau problème. L'ordre est désormais aléatoire.

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

On pourrait croire que la sortie ci-dessus est incorrecte, car on s'attendrait à ce que la première paire clé/valeur déclarée dans la map, 9 10, soit la première affichée et non la dernière. Cependant, les maps n'ont pas d'ordre par nature : il n'existe ni première ni dernière paire clé/valeur. C'est pourquoi, lorsqu'on parcourt les entrées d'une map, l'ordre dans lequel elles sont visitées est aléatoire et ne suit aucun schéma particulier. La sortie ci-dessus est donc possible, mais elle peut différer de ce que tu obtiendras si tu essaies de lancer ce code toi-même. Pour en savoir plus, consulte Spécification du langage Go : la clause range.

Itération en omettant la clé ou la valeur

En Go, une variable inutilisée provoque une erreur à la compilation. Parfois, seule la valeur nous intéresse, comme dans le premier exemple :

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

Tu peux remplacer le i par _, ce qui indique au compilateur que cette valeur n'est pas utilisée :

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

Si tu veux seulement afficher l'indice, tu peux remplacer le x par _, ou simplement omettre la déclaration :

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

Définis des types

Une définition de type crée un nouveau type nommé, distinct de tous les autres types, y compris ceux qui ont le même type sous-jacent.

type File []bool

Ici, File désigne une colonne verticale d'un échiquier, généralement désignée par une lettre de A à H. Chaque case de cette colonne est représentée par une valeur booléenne qui indique si elle est occupée ou non. Maintenant que File est défini, on peut l'utiliser dans d'autres définitions :

type Chessboard map[string]File

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

Chessboard associe des identifiants de colonne à des valeurs File. Chaque File est un slice de booléens qui représente les cases d'une colonne de l'échiquier. Sans ces définitions de type, board serait une map[string][]bool, ce qui rendrait moins évident ce que l'on représente.

Instructions

En passionné d'échecs, tu aimerais écrire ta propre version du jeu. Certes, il existe déjà plein d'implémentations des échecs en ligne, mais la tienne sera unique !

Chaque case de l'échiquier est identifiée par un couple lettre-nombre :

  • Les lignes horizontales de cases, appelées rangées, sont numérotées de 1 à 8.
  • Les lignes verticales de cases, appelées colonnes, sont désignées par les lettres 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. Étant donné un échiquier et une colonne, compte combien de cases sont occupées

Implémente la fonction CountInFile(board Chessboard, file string) int. Elle doit compter le nombre total de cases occupées en parcourant une map. Elle renvoie un entier. Elle renvoie zéro (0) si la colonne donnée est introuvable dans la map.

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

2. Étant donné un échiquier et une rangée, compte combien de cases sont occupées

Implémente la fonction CountInRank(board Chessboard, rank int) int. Elle doit compter le nombre total de cases occupées en parcourant la rangée donnée. Elle renvoie un entier. Elle renvoie zéro (0) si la rangée donnée n'est pas valide (pas entre 1 et 8, bornes incluses).

CountInRank(board, 2)
// => 1

3. Compte combien de cases sont présentes dans l'échiquier donné

Implémente la fonction CountAll(board Chessboard) int. Elle doit compter combien de cases sont présentes dans l'échiquier et renvoie un entier. Comme tu n'as pas besoin de vérifier le contenu des cases, tu peux utiliser range en omettant à la fois index et value.

CountAll(board)
// => 64

4. Compte combien de cases sont occupées dans l'échiquier donné

Implémente la fonction CountOccupied(board Chessboard) int. Elle doit compter combien de cases sont occupées dans l'échiquier. Elle renvoie un entier.

CountOccupied(board)
// => 15
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Go Exercism

Prêt à commencer Échiquier ?

Inscris-toi sur Exercism pour apprendre et maîtriser Go avec 34 concepts166 exercices, et un vrai mentorat humain, le tout gratuitement.