Nota
¡Hola! Bienvenido a la Comunidad de Entusiastas de SunFounder para Raspberry Pi, Arduino y ESP32 en Facebook. Sumérgete más en Raspberry Pi, Arduino y ESP32 con otros entusiastas.
¿Por qué unirse?
Soporte Experto: Resuelve problemas post-venta y desafíos técnicos con la ayuda de nuestra comunidad y equipo.
Aprender y Compartir: Intercambia consejos y tutoriales para mejorar tus habilidades.
Avances Exclusivos: Obtén acceso temprano a nuevos anuncios de productos y avances.
Descuentos Especiales: Disfruta de descuentos exclusivos en nuestros productos más nuevos.
Promociones y Sorteos Festivos: Participa en sorteos y promociones de temporada.
👉 ¿Listo para explorar y crear con nosotros? Haz clic en [Aquí] y únete hoy mismo.
4.1.14 JUEGO - Adivina el Número
Introducción
Adivinar Números es un juego divertido de fiesta donde tú y tus amigos se turnan para ingresar un número (0~99). El rango se hará más pequeño con cada número ingresado hasta que un jugador adivine correctamente el número secreto. Luego, el jugador pierde y se le aplica un castigo. Por ejemplo, si el número secreto es 51, que los jugadores no pueden ver, y el jugador ① ingresa 50, el rango de números cambia a 50~99; si el jugador ② ingresa 70, el rango de números puede ser 50~70; si el jugador ③ ingresa 51, este jugador es el desafortunado. Aquí, usamos un teclado para ingresar números y una pantalla LCD para mostrar los resultados.
Componentes Necesarios
En este proyecto, necesitamos los siguientes componentes.
Es definitivamente conveniente comprar un kit completo, aquí está el enlace:
Nombre |
ARTÍCULOS EN ESTE KIT |
ENLACE |
|---|---|---|
Kit Raphael |
337 |
También puedes comprarlos por separado en los siguientes enlaces.
INTRODUCCIÓN DE COMPONENTES |
ENLACE DE COMPRA |
|---|---|
- |
|
Diagrama Esquemático
T-Board Name |
physical |
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) |
Procedimientos Experimentales
Paso 1: Construir el circuito.
Paso 2: Configurar I2C (ver Configuración de I²C.)
Paso 3: Cambiar directorio.
cd ~/raphael-kit/python-pi5
Paso 4: Ejecutar.
sudo python3 4.1.17_GAME_GuessNumber_zero.py
Después de que el programa se ejecute, se muestra la página inicial en la pantalla LCD:
Welcome!
Press A to go!
Presiona ‘A’, y el juego comenzará y la página del juego aparecerá en la LCD.
Enter number:
0 < point < 99
Un número aleatorio ‘point’ se produce pero no se muestra en la LCD cuando comienza el juego, y lo que necesitas hacer es adivinarlo. El número que has escrito aparece al final de la primera línea hasta que se termine el cálculo final. (Presiona ‘D’ para comenzar la comparación, y si el número ingresado es mayor que 10, la comparación automática comenzará).
El rango de números de ‘point’ se muestra en la segunda línea. Y debes escribir el número dentro del rango. Cuando escribes un número, el rango se estrecha; si tienes suerte y adivinas el número, aparecerá “¡Lo has adivinado!”
Nota
Si obtienes el error
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1', necesitas consultar Configuración de I²C para habilitar el I2C.Si obtienes el error
ModuleNotFoundError: No module named 'smbus2', por favor ejecutasudo apt install python3-smbus2.Si aparece el error
OSError: [Errno 121] Remote I/O error, significa que el módulo está mal conectado o el módulo está dañado.Si el código y el cableado están bien, pero la LCD aún no muestra contenido, puedes girar el potenciómetro en la parte posterior para aumentar el contraste.
Advertencia
Si recibe el mensaje de error RuntimeError: Cannot determine SOC peripheral base address, consulte Si «gpiozero» no funciona.
Código
Nota
Puedes Modificar/Restablecer/Copiar/Ejecutar/Detener el código a continuación. Pero antes de eso, necesitas ir a la ruta del código fuente como raphael-kit/python-pi5. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.
#!/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] # Configurar pines de fila
self.cols = [Button(pin, pull_up=False) for pin in cols_pins] # Configurar pines de columna
self.keys = keys # Definir el diseño del teclado
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() # Activar fila actual
for j, col in enumerate(self.cols):
if col.is_pressed:
index = i * len(self.cols) + j
pressed_keys.append(self.keys[index]) # Agregar tecla presionada
row.off() # Desactivar fila
return pressed_keys
# Variables relacionadas con el juego
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) # Inicializar 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() # Limpiar LCD al interrumpir
Explicación del Código
Esta sección importa clases esenciales de la biblioteca GPIO Zero para manejar dispositivos de salida digital y botones. También incluye la función sleep del módulo time para introducir retrasos en el script. La biblioteca LCD1602 se importa para operar la pantalla LCD, útil para mostrar texto o datos. Además, se incorpora la biblioteca random, que ofrece funciones para generar números aleatorios, lo cual puede ser ventajoso para varios aspectos del proyecto.
#!/usr/bin/env python3 from gpiozero import DigitalOutputDevice, Button from time import sleep import LCD1602 import random
Define una clase para el teclado, inicializándolo con pines de fila y columna, y definiendo un método para leer las teclas presionadas.
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] # Configurar pines de fila self.cols = [Button(pin, pull_up=False) for pin in cols_pins] # Configurar pines de columna self.keys = keys # Definir el diseño del teclado 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() # Activar fila actual for j, col in enumerate(self.cols): if col.is_pressed: index = i * len(self.cols) + j pressed_keys.append(self.keys[index]) # Agregar tecla presionada row.off() # Desactivar fila return pressed_keys
Inicializa una variable
countcomo cero, potencialmente utilizada para rastrear intentos o valores específicos en el juego. Configura el teclado y la pantalla LCD con un mensaje de bienvenida e instrucciones. Inicializa la variablepointValuea cero, posiblemente representando un objetivo o valor en el juego. Define un límiteupperpara el juego, inicialmente configurado en 99, que podría ser el máximo en un juego de adivinanza de números. Establece el límitelowercomenzando desde cero, probablemente utilizado como el límite mínimo en el juego.# Variables relacionadas con el juego count = 0 pointValue = 0 upper = 99 lower = 0
Configura el teclado y la pantalla LCD, mostrando un mensaje de bienvenida e instrucciones.
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) # Inicializar LCD LCD1602.clear() LCD1602.write(0, 0, 'Welcome!') LCD1602.write(0, 1, 'Press A to Start!')
Inicializa un nuevo valor objetivo para el juego y restablece los parámetros del juego.
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('el número es %d' % pointValue)
Verifica si el número adivinado coincide con el objetivo y actualiza el rango de adivinanza en consecuencia.
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
Muestra el estado del juego en la pantalla LCD, mostrando la adivinanza actual, el rango y el resultado.
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))
El bucle principal para manejar la entrada del teclado, actualizar el estado del juego y mostrar los resultados en la pantalla 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)
Ejecuta la configuración y entra en el bucle principal del juego, permitiendo una salida limpia utilizando una interrupción de teclado.
try: setup() loop() except KeyboardInterrupt: LCD1602.clear() # Limpiar LCD al interrumpir