21H — e-Chess
Par admin le mardi, février 2 2021, 12:00 - 2020–2021 - Lien permanent
Ce projet a été réalisé par HÜRLIMANN, Max Eliot Luc.
1. Introduction
Le jeu d’échecs existe depuis des lustres, mais sa démocratisation ne s'est faite que récemment, notamment grâce internet, qui permet la diffusion de compétitions sur des platformes de streaming
comme Twitch et il y a quelques mois grâce à la série Netflix : "The Queen's Gambit". Il y a plusieurs manières intéressantes de lier le jeu d'échecs à l'informatique, par exemple dans le domaine de l'intelligence artificielle comme Deep Blue et ses descendants (Leela chess zero, stockfish, alpha zero..) ou bien la création d'un site web pour jouer aux échecs, ou bien un échiquier connecté, ou bien ...
(voir https://www.chessprogramming.org/Main_Page pour d'autres idées).
C'est sur cette dernière option que j'ai décidé de m'orienter, car il nous était demandé de réaliser un projet dans lequel il fallait utiliser de l'électronique. Le but de mon projet est de construire un échiquier qui détecte sur quelles cases il y a une pièce, et de l'afficher sur un écran. Il existe déjà plusieurs modèles que l'on peut acheter sur internet (par exemple le DGT CHESSBOARD). Ce qui rend mon projet intéressant et original, c'est que le matériel que j'ai à disposition est beaucoup plus modeste que celui des différentes entreprises. Il va donc falloir être inventif pour trouver un système qui marche (certes moins élegant) avec un matériel moins poussé.
2. Matériel et méthodes
2.1 Matériel
- Raspberry Pi 3B
- Grand breadboard
- 8 résistors 330Ω
- 128 fils conducteur
- Papier aluminium + élastiques
- Échiquier
- Tournevis
2.2 Méthode
2.2.1 Hardware
Ma première idée était d'acheter 64 boutons électroniques, 1 pour chaque case de l'échiquier, mais quand j'ai vu le prix d'un bouton en suisse, je me suis forcé à trouver une solution moins couteuse.
La solution plus économe s'avérait même être plus simple/élegante que l'idée initiale. Je me suis rendu compte qu'on peut simuler ce que fait un bouton avec deux fils conducteurs et un bout de métal conducteur (ici de l'aluminium car facile à trouver chez soi). Il suffit de brancher un fil à un pin output est l'autre à un pin input et de les poser à côté sur une case, sans contact. Lorsque on pose une pièce sur la case, l'aluminium qui a été attaché sur le dessous de la pièce conduit l'électricité d'un pin à l'autre et nous pouvons ainsi coder le pin input en fonction de si la tension est haute ou non (si il y a une pièce sur la case ou pas).
Bien sûr, cette solution économe d'un bouton ne marche que pour les cas ou l'objet appuyant sur le bouton reste sur le bouton,
et c'est notre cas. Maintenant il faut répeter cette étape pour les 64 cases de l'échiquier. Pour éviter d'avoir des fils qui traînent de partout, j'ai fait des trous dans l'échiquier à l'aide d'un tournevis à chaque intersection de 4 cases, et j'ai disposé les fils en pattern comme vous le voyez sur la figure en dessous.
2.2.2 Software
Il faut découper le code en plusieurs morceaux afin de ne pas se perdre dans un code illisible. Le premier bout de code est celui qui permet de reconnaître sur quelles cases il y a quelquechose/une pièce/de l'aluminium. Lorsque cela est fait on peut écrire le code qui affiche l'échiquier. On peut encore subdiviser la première étape, en commençant tout d'abord par définir quels sont nos pins input et output : import RPi.GPIO as GPIO
# use microcontroller numbering GPIO.setmode(GPIO.BCM)
try: #Setting RPi GPIO pins as arrays to be able to loop through them columnArray= 27, 26, 25, 24, 23, 22, 21, 20 #Where the pin for column H = 27, column G = 26, etc. rowArray = 19, 18, 17, 16, 13, 12, 6, 5 #Same here for rows : row 1= pin 19 , row 2 = pin 18 etc. for x in columnArray: GPIO.setup(x, GPIO.OUT) for y in rowArray: GPIO.setup(y, GPIO.IN, GPIO.PUD_DOWN) #Internal pull down resistor for input pins
On pourrait setup les pins manuellement, pin par pin mais premièrement il est plus simple d'utiliser des arrays et en plus on en aura besoin plus tard pour scanner toutes les cases à l'aide de boucles while. Définissons maintenant la fonction qui permet de checker pour la case i, j. On pourrait l'écrire dans les boucles while directement mais le code sera plus lisible de cette manière.
#define the function to check if there is a piece on i,j (where 0,0 would be A1 and 7,7 would be H8) def check_square(i, j): #send current through column i GPIO.output(columnArrayi, GPIO.HIGH) #check if something comes back from row j if (GPIO.input(rowArrayj)): return True #if nothing happens, then there is no piece hense the value False. else: return False #important to not forget to reset the output pin to low, otherwise there will be interference with other squares GPIO.output(columnArrayi, GPIO.LOW)
Ce code fait exactement ce qu'on pense, il envoie du courant dans la colonne i et il regarde si il y a du courant qui revient de la ligne j. Si c'est le cas il y a une pièce d'où le retour de la valeur true, et sinon c'est false. Il faut just faire attention à ne pas oublier la dernière commande, qui dit qu'on arrête d'envoyer du courant dans la colonne i (sinon on aura des problèmes par la suite avec un code qui pense qu'une case est activée alors qu'elle ne l'est pas).
#These while loops just print on which square there is a piece at the beginning of the programm a2h='A', 'B', 'C', 'D', 'E', 'F', 'G', ... i=0 j=0 while i<2: while j<2: if (check_square(i, j)): printelse: print
j+=1 j=0 i+=1
Ce code écrit 64 lignes pour les 64 cases, en disant sur quelle case il y quelque chose ou pas. Je n'ai pas eu le temps de coder la partie visuelle, qui affiche l'échiquier (j'en reparle après), mais j'ai pu tester ce code,
#This line of code prints out an Ascii chessboard (starting position) #small case letters are black pieces, capital are white, #r=rook, n= knight, b=bishop, q=queen, k=king (same for white pieces) print('rnbqkbnr','p'*8,*'.'*8*4,'P'*8,'RNBQKBNR',sep='\n')
qui imprime un mini échiquier en Ascii.
3. Résultats
Malheureusement, en essayant de télécharger un libraire python pour les échecs samedi, j'ai fait quelquechose (à l'heure de l'écriture de ce blog je ne sais pas encore quoi) qui fait que je ne peux plus accéder à mon Raspberry Pi. Je n'ai donc malheureusement pas de résultats à vous montrer. Je peux cependant témoigner que le prototype à une case marchait.
if (GPIO.input(rowArrayj)): print ("Something on A1") else: print ("Nothing on A1")
En lançant le code il dit effectivement Something on A1 quand il y avait une pièce et Nothing on A1 quand il n'y en avait pas.
Le prototype à 4 cases ne marchait pas quand je n'avais pas utilisé un pull down resistor et je n'ai malheureusement pas eu l'occasion de tester le code avec le pull down resistor. Si je devais faire une prédiction, je pense que cela aurait marché car en demandant à plusieurs personnes qui s'y connaissaient (sur des forums) ils ne voyaient aucun autre problème avec mon code ou mon circuit.
4. Discussion
J'ai rencontré plusieurs problèmes dans la réalisation du projet. Le problème principal étant la gestion du temps, les autres problèmes en découlent. Le premier problème est que je n'avais pas utilisé les pull down resistor sur les pins input, et donc quand il n'était pas activé par un pin output, ils étaient en mode 'float' et la valeur variait entre 0 et 1, ce qui explique pourquoi lors des tests le code ne marchait pas 100% du temps. Le deuxième problème est que les pièces d'échecs utilisées ne sont pas assez lourdes, et souvent il y avait des mauvais contacts entre les fils et la pièce. Finalement, j'ai sous estimé la difficulté de la programmation d'un afficheur de l'échiquier, je me suis rendu compte trop tard que je n'aurais pas le temps de le programmer. Ce sera peut-être une occasion pour le projet P, avec un validateur de coups (est-ce que le coup suit les règles du jeu d'échec ?
5. Conclusion
Même si, comme mentionné dans la section discussion, j'ai rencontré quelques problèmes lors de la réalisation du projet, je suis très content de ce que j'ai accompli et surtout de ce que j'ai appris. L'objectif n'a pas été complètement atteint, car je n'ai pas réussi à coder la partie qui affichait l'échiquier en temps réel, seulement la position initiale en ascii, et surtout je n'ai pas pu vérifier si le code fonctionnait correctement après l'ajout du pull down resistor dans le code. Néanmoins, l'objectif principal de ce projet est à mon avis, d'apprendre, de s'amuser et surtout donner envie de réaliser d'autres projet (pas forcément dans un cadre scolaire). Cet objectif a clairement été atteint. Je pense continuer ce projet de mon côté, car il m'a vraiment intéressé et comme je viens de le dire, il m'a beaucoup appris. Ce qu'il faut en retenir aussi, c'est l'importance de l'organisation et de commencer le projet en avance. J'espère ne pas oublier ce conseil lors du projet P !
Références
1) Fonctions, boucles, if statement, syntaxe : https://www.w3schools.com/python
2) Pull down resistor : https://www.electronics-tutorials.ws/logic/pull-up-resistor.html, https://www.raspberrypi.org/forums/viewtopic.php?t=202568