Note
Bonjour et bienvenue dans la Communauté Facebook des passionnés de Raspberry Pi, Arduino et ESP32 de SunFounder ! Plongez plus profondément dans l’univers des Raspberry Pi, Arduino et ESP32 avec d’autres passionnés.
Pourquoi rejoindre ?
Support d’experts : Résolvez les problèmes après-vente et les défis techniques avec l’aide de notre communauté et de notre équipe.
Apprendre et partager : Échangez des astuces et des tutoriels pour améliorer vos compétences.
Aperçus exclusifs : Accédez en avant-première aux annonces de nouveaux produits et aux aperçus.
Réductions spéciales : Profitez de réductions exclusives sur nos produits les plus récents.
Promotions festives et cadeaux : Participez à des cadeaux et des promotions de vacances.
👉 Prêt à explorer et à créer avec nous ? Cliquez [Ici] et rejoignez-nous aujourd’hui !
4.1.14 JEU - Devinez le Nombre
Introduction
« Devinez le Nombre » est un jeu de fête amusant où vous et vos amis vous relayez pour saisir un nombre (0 à 99). La plage de nombres se réduit à chaque saisie jusqu’à ce qu’un joueur résolve l’énigme correctement. Alors, ce joueur est déclaré perdant et subit une pénalité. Par exemple, si le nombre chanceux est 51, que les joueurs ne peuvent pas voir, et que le joueur ① saisit 50, l’indication de la plage de nombres change pour 50~99 ; si le joueur ② saisit 70, la plage de nombres devient 50~70 ; si le joueur ③ saisit 51, ce joueur est le malchanceux. Ici, nous utilisons un clavier pour entrer les nombres et un LCD pour afficher les résultats.
Composants nécessaires
Pour ce projet, nous avons besoin des composants suivants.
Il est certainement pratique d’acheter un kit complet, voici le lien :
Nom |
ARTICLES DANS CE KIT |
LIEN |
|---|---|---|
Kit Raphael |
337 |
Vous pouvez également les acheter séparément via les liens ci-dessous.
INTRODUCTION DU COMPOSANT |
LIEN D’ACHAT |
|---|---|
- |
|
Schéma
Nom T-Board |
physique |
wiringPi |
BCM |
GPIO18 |
Pin 12 |
1 |
18 |
GPIO23 |
Pin 16 |
4 |
23 |
GPIO24 |
Pin 18 |
5 |
24 |
GPIO25 |
Pin 22 |
6 |
25 |
SPIMOSI |
Pin 19 |
12 |
10 |
GPIO22 |
Pin 15 |
3 |
22 |
GPIO27 |
Pin 13 |
2 |
27 |
GPIO17 |
Pin 11 |
0 |
17 |
SDA1 |
Pin 3 |
SDA1(8) |
SDA1(2) |
SCL1 |
Pin 5 |
SCL1(9) |
SDA1(3) |
Procédures expérimentales
Étape 1 : Construire le circuit.
Étape 2 : Configurer I2C (voir Configuration I²C.)
Étape 3 : Changer de répertoire.
cd ~/raphael-kit/python-pi5
Étape 4 : Exécuter.
sudo python3 4.1.17_GAME_GuessNumber_zero.py
Après l’exécution du programme, la page initiale s’affiche sur le LCD :
Bienvenue !
Appuyez sur A pour commencer !
Appuyez sur ‘A’, et le jeu commencera et la page du jeu apparaîtra sur le LCD.
Entrez le nombre :
0 < point < 99
Un nombre aléatoire ‘point’ est produit mais non affiché sur le LCD au début du jeu, et ce que vous devez faire est de le deviner. Le nombre que vous avez tapé apparaît à la fin de la première ligne jusqu’à ce que le calcul final soit terminé. (Appuyez sur ‘D’ pour démarrer la comparaison, et si le nombre entré est supérieur à 10, la comparaison automatique commencera.)
La plage de nombres de ‘point’ est affichée sur la deuxième ligne. Et vous devez taper le nombre dans cette plage. Lorsque vous tapez un nombre, la plage se rétrécit ; si vous obtenez le nombre chanceux par chance ou malchance, il apparaîtra « Vous l’avez trouvé ! »
Note
Si vous rencontrez l’erreur
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1', vous devez consulter Configuration I²C pour activer l’I2C.Si l’erreur
ModuleNotFoundError: No module named 'smbus2'apparaît, veuillez exécutersudo apt install python3-smbus2.Si l’erreur
OSError: [Errno 121] Remote I/O errorsurvient, cela signifie que le module est mal câblé ou que le module est défectueux.Si le câblage et le code sont corrects, mais que l’écran LCD n’affiche toujours pas de contenu, vous pouvez tourner le potentiomètre à l’arrière pour augmenter le contraste.
Avertissement
Si vous recevez le message d’erreur RuntimeError: Cannot determine SOC peripheral base address, veuillez consulter Si « gpiozero » ne fonctionne pas.
Code
Note
Vous pouvez modifier/réinitialiser/copier/exécuter/arrêter le code ci-dessous. Mais avant cela, vous devez vous rendre au chemin du code source comme raphael-kit/python-pi5. Après modification du code, vous pouvez l’exécuter directement pour voir l’effet.
#!/usr/bin/env python3
from gpiozero import DigitalOutputDevice, Button
from time import sleep
import LCD1602
import random
class Keypad:
def __init__(self, rows_pins, cols_pins, keys):
"""
Initialize the keypad with specified row and column pins and key layout.
:param rows_pins: List of GPIO pins for the rows.
:param cols_pins: List of GPIO pins for the columns.
:param keys: Layout of keys on the keypad.
"""
self.rows = [DigitalOutputDevice(pin) for pin in rows_pins] # Setup row pins
self.cols = [Button(pin, pull_up=False) for pin in cols_pins] # Setup column pins
self.keys = keys # Define keypad layout
def read(self):
"""
Read and return the currently pressed keys.
:return: List of pressed keys.
"""
pressed_keys = []
for i, row in enumerate(self.rows):
row.on() # Activate current row
for j, col in enumerate(self.cols):
if col.is_pressed:
index = i * len(self.cols) + j
pressed_keys.append(self.keys[index]) # Append pressed key
row.off() # Deactivate row
return pressed_keys
# Game-related variables
count = 0
pointValue = 0
upper = 99
lower = 0
def setup():
"""
Setup function for initializing the keypad and LCD display.
"""
global keypad, last_key_pressed, keys
rowsPins = [18, 23, 24, 25]
colsPins = [10, 22, 27, 17]
keys = ["1", "2", "3", "A",
"4", "5", "6", "B",
"7", "8", "9", "C",
"*", "0", "#", "D"]
keypad = Keypad(rowsPins, colsPins, keys)
last_key_pressed = []
LCD1602.init(0x27, 1) # Initialize LCD
LCD1602.clear()
LCD1602.write(0, 0, 'Welcome!')
LCD1602.write(0, 1, 'Press A to Start!')
def init_new_value():
"""
Initialize a new target value and reset game parameters.
"""
global pointValue, upper, lower, count
pointValue = random.randint(0, 99)
upper = 99
lower = 0
count = 0
print('point is %d' % pointValue)
def detect_point():
"""
Check if the guessed number is the target, too high, or too low.
:return: 1 if correct guess, 0 otherwise.
"""
global count, upper, lower
if count > pointValue and count < upper:
upper = count
elif count < pointValue and count > lower:
lower = count
elif count == pointValue:
count = 0
return 1
count = 0
return 0
def lcd_show_input(result):
"""
Display the current game state and results on the LCD.
:param result: Result of the last guess (0 or 1).
"""
LCD1602.clear()
if result == 1:
LCD1602.write(0, 1, 'You have got it!')
sleep(5)
init_new_value()
lcd_show_input(0)
else:
LCD1602.write(0, 0, 'Enter number:')
LCD1602.write(13, 0, str(count))
LCD1602.write(0, 1, str(lower))
LCD1602.write(3, 1, ' < Point < ')
LCD1602.write(13, 1, str(upper))
def loop():
"""
Main game loop for handling keypad input and updating game state.
"""
global keypad, last_key_pressed, count
while True:
result = 0
pressed_keys = keypad.read()
if pressed_keys and pressed_keys != last_key_pressed:
if pressed_keys == ["A"]:
init_new_value()
lcd_show_input(0)
elif pressed_keys == ["D"]:
result = detect_point()
lcd_show_input(result)
elif pressed_keys[0] in keys:
if pressed_keys[0] in ["A", "B", "C", "D", "#", "*"]:
continue
count = count * 10 + int(pressed_keys[0])
if count >= 10:
result = detect_point()
lcd_show_input(result)
print(pressed_keys)
last_key_pressed = pressed_keys
sleep(0.1)
try:
setup()
loop()
except KeyboardInterrupt:
LCD1602.clear() # Clear LCD on interrupt
Explication du code
Cette section importe les classes essentielles de la bibliothèque GPIO Zero pour gérer les dispositifs de sortie numérique et les boutons. Elle inclut également la fonction sleep du module time pour introduire des délais dans le script. La bibliothèque LCD1602 est importée pour l’opération de l’affichage LCD, utile pour afficher des textes ou des sorties de données. De plus, la bibliothèque random est incorporée, offrant des fonctions pour générer des nombres aléatoires, ce qui peut être avantageux pour divers aspects du projet.
#!/usr/bin/env python3 from gpiozero import DigitalOutputDevice, Button from time import sleep import LCD1602 import random
Définit une classe pour le clavier, l’initialisant avec des broches de rangées et de colonnes et définissant une méthode pour lire les touches pressées.
class Keypad: def __init__(self, rows_pins, cols_pins, keys): """ Initialize the keypad with specified row and column pins and key layout. :param rows_pins: List of GPIO pins for the rows. :param cols_pins: List of GPIO pins for the columns. :param keys: Layout of keys on the keypad. """ self.rows = [DigitalOutputDevice(pin) for pin in rows_pins] # Setup row pins self.cols = [Button(pin, pull_up=False) for pin in cols_pins] # Setup column pins self.keys = keys # Define keypad layout def read(self): """ Read and return the currently pressed keys. :return: List of pressed keys. """ pressed_keys = [] for i, row in enumerate(self.rows): row.on() # Activate current row for j, col in enumerate(self.cols): if col.is_pressed: index = i * len(self.cols) + j pressed_keys.append(self.keys[index]) # Append pressed key row.off() # Deactivate row return pressed_keys
Initialise une variable
countà zéro, potentiellement utilisée pour suivre les tentatives ou des valeurs spécifiques dans le jeu. Configure le clavier et l’affichage LCD avec un message de bienvenue et des instructions. Initialise la variablepointValueà zéro, représentant potentiellement un score ou une valeur cible dans le jeu. Définit une limiteupperpour le jeu, initialement fixée à 99, ce qui pourrait être le maximum dans un jeu de devinettes numériques. Définit la limitelowerà partir de zéro, probablement utilisée comme borne minimale dans le jeu.# Game-related variables count = 0 pointValue = 0 upper = 99 lower = 0
Configure le clavier et l’affichage LCD, affichant un message de bienvenue et des instructions.
def setup(): """ Setup function for initializing the keypad and LCD display. """ global keypad, last_key_pressed, keys rowsPins = [18, 23, 24, 25] colsPins = [10, 22, 27, 17] keys = ["1", "2", "3", "A", "4", "5", "6", "B", "7", "8", "9", "C", "*", "0", "#", "D"] keypad = Keypad(rowsPins, colsPins, keys) last_key_pressed = [] LCD1602.init(0x27, 1) # Initialize LCD LCD1602.clear() LCD1602.write(0, 0, 'Welcome!') LCD1602.write(0, 1, 'Press A to Start!')
Initialise une nouvelle valeur cible pour le jeu et réinitialise les paramètres du jeu.
def init_new_value(): """ Initialize a new target value and reset game parameters. """ global pointValue, upper, lower, count pointValue = random.randint(0, 99) upper = 99 lower = 0 count = 0 print('point is %d' % pointValue)
Vérifie si le numéro deviné correspond à la cible et met à jour la plage de devinettes en conséquence.
def detect_point(): """ Check if the guessed number is the target, too high, or too low. :return: 1 if correct guess, 0 otherwise. """ global count, upper, lower if count > pointValue and count < upper: upper = count elif count < pointValue and count > lower: lower = count elif count == pointValue: count = 0 return 1 count = 0 return 0
Affiche l’état du jeu sur l’écran LCD, montrant la devinette actuelle, la plage et le résultat.
def lcd_show_input(result): """ Display the current game state and results on the LCD. :param result: Result of the last guess (0 or 1). """ LCD1602.clear() if result == 1: LCD1602.write(0, 1, 'You have got it!') sleep(5) init_new_value() lcd_show_input(0) else: LCD1602.write(0, 0, 'Enter number:') LCD1602.write(13, 0, str(count)) LCD1602.write(0, 1, str(lower)) LCD1602.write(3, 1, ' < Point < ') LCD1602.write(13, 1, str(upper))
La boucle principale pour gérer l’entrée du clavier, mettre à jour l’état du jeu et afficher les résultats sur l’écran LCD.
def loop(): """ Main game loop for handling keypad input and updating game state. """ global keypad, last_key_pressed, count while True: result = 0 pressed_keys = keypad.read() if pressed_keys and pressed_keys != last_key_pressed: if pressed_keys == ["A"]: init_new_value() lcd_show_input(0) elif pressed_keys == ["D"]: result = detect_point() lcd_show_input(result) elif pressed_keys[0] in keys: if pressed_keys[0] in ["A", "B", "C", "D", "#", "*"]: continue count = count * 10 + int(pressed_keys[0]) if count >= 10: result = detect_point() lcd_show_input(result) print(pressed_keys) last_key_pressed = pressed_keys sleep(0.1)
Lance la configuration et entre dans la boucle principale du jeu, permettant une sortie propre à l’aide d’une interruption du clavier.
try: setup() loop() except KeyboardInterrupt: LCD1602.clear() # Clear LCD on interrupt