.. note:: ¡Hola! Bienvenido a la comunidad de entusiastas de SunFounder para Raspberry Pi, Arduino y ESP32 en Facebook. Únete para profundizar en Raspberry Pi, Arduino y ESP32 junto a otros apasionados. **¿Por qué unirte?** - **Soporte de Expertos**: Resuelve problemas post-venta y desafíos técnicos con la ayuda de nuestra comunidad y equipo. - **Aprende y Comparte**: Intercambia consejos y tutoriales para mejorar tus habilidades. - **Avances Exclusivos**: Obtén acceso anticipado a anuncios de nuevos productos y vistas previas. - **Descuentos Especiales**: Disfruta de descuentos exclusivos en nuestros productos más recientes. - **Promociones Festivas y Sorteos**: Participa en sorteos y promociones de temporada. 👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy. 3.1.12 JUEGO– Adivina el Número ================================= Introducción ------------------ Adivina el Número es un juego de fiesta en el que tú y tus amigos toman turnos para ingresar un número (0~99). El rango se reduce con cada intento hasta que un jugador adivina correctamente, momento en el cual el jugador pierde y recibe un castigo. Por ejemplo, si el número secreto es 51 (invisible para los jugadores) y el jugador ① ingresa 50, el rango se ajusta a 50~99; si el jugador ② ingresa 70, el rango será de 50~70; si el jugador ③ ingresa 51, este jugador será el desafortunado. Aquí, usamos un teclado para ingresar números y una LCD para mostrar los resultados. Componentes ----------------- .. image:: img/list_GAME_Guess_Number.png :align: center 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) ============ ======== ======== ======= .. image:: img/Schematic_three_one12.png :align: center Procedimientos Experimentales --------------------------------- **Paso 1:** Construye el circuito. .. image:: img/image273.png :alt: Guess Number_bb :width: 800 **Paso 2**: Configura I2C (consulta el Apéndice. Si ya lo has configurado, omite este paso.) **Para Usuarios de Lenguaje C** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Paso 3**: Cambia de directorio. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/c/3.1.12/ **Paso 4**: Compila. .. raw:: html .. code-block:: gcc 3.1.12_GAME_GuessNumber.c -lwiringPi **Paso 5**: Ejecuta. .. raw:: html .. code-block:: sudo ./a.out Después de ejecutar el programa, la pantalla LCD muestra la página inicial: .. code-block:: Welcome! Press A to go! Presiona \'A\', y el juego comenzará mostrando la página de juego en la LCD. .. code-block:: Enter number: 0 ‹point‹ 99 .. note:: Si no funciona después de ejecutarlo, o aparece un mensaje de error: \"wiringPi.h: No such file or directory", consulta :ref:`faq_c_nowork`. Un número aleatorio \'**punto**\' es generado pero no se muestra en la pantalla LCD cuando el juego comienza, y lo que necesitas hacer es adivinarlo. El número ingresado aparecerá al final de la primera línea hasta que se complete el cálculo final. (Presiona \'D\' para iniciar la comparación, y si el número ingresado es mayor que **10**, la comparación automática comenzará.) El rango del número \'punto\' se muestra en la segunda línea, y debes ingresar un número dentro de ese rango. A medida que ingresas un número, el rango se reduce; si adivinas el número afortunado o desafortunado, aparecerá el mensaje \"¡Lo conseguiste!\" **Explicación del Código** Al comienzo del código se encuentran las funciones para manejar el **teclado** y la **LCD I2C 1602**. Puedes obtener más detalles sobre estas funciones en :ref:`1.1.7_i2c_lcd` y :ref:`2.1.5_keypad` Aquí, lo que necesitamos saber es lo siguiente: .. code-block:: c /****************************************/ //Comienza desde aquí /****************************************/ void init(void){     fd = wiringPiI2CSetup(LCDAddr); lcd_init(); lcd_clear();     for(int i=0 ; i<4 ; i++) {         pinMode(rowPins[i], OUTPUT);         pinMode(colPins[i], INPUT); } lcd_clear();     write(0, 0, "Welcome!");     write(0, 1, "Press A to go!"); } Esta función se utiliza para definir inicialmente **I2C LCD1602** y **Teclado** y para mostrar \"¡Bienvenido!\" y \"Presiona A para empezar\". .. code-block:: c void init_new_value(void){ srand(time(0));     pointValue = rand()%100;     upper = 99;     lower = 0;     count = 0;     printf("point is %d\n",pointValue); } La función genera el número aleatorio \'**punto**\' y restablece el rango del punto. .. code-block:: c bool detect_point(void){     if(count > pointValue){         if(count < upper){             upper = count; } }     else if(count < pointValue){         if(count > lower){             lower = count; } }     else if(count = pointValue){         count = 0;         return 1; }     count = 0;     return 0; } detect_point() compara el número ingresado con el \"punto\" generado. Si el resultado de la comparación es que no coinciden, **count** asignará valores a **upper** y **lower** y devolverá \'**0**\'; de lo contrario, si el resultado indica coincidencia, devuelve \'**1**\'. .. code-block:: c void lcd_show_input(bool result){     char *str=NULL;     str =(char*)malloc(sizeof(char)*3); lcd_clear();     if (result == 1){         write(0,1,"You've got it!"); delay(5000); init_new_value(); lcd_show_input(0); return; }     write(0,0,"Enter number:");     Int2Str(str,count);     write(13,0,str);     Int2Str(str,lower);     write(0,1,str);     write(3,1,"='0' && pressed_keys[0] <= '9'){                     count = count * 10;                     count = count + (pressed_keys[0] - 48);                     if (count>=10){                         result = detect_point(); } lcd_show_input(result); } }             keyCopy(last_key_pressed, pressed_keys); } delay(100); }     return 0;    } Main() contiene todo el proceso del programa, como se muestra a continuación: 1) Inicializa **I2C LCD1602** y **Teclado**. 2) Usa **init_new_value()** para crear un número aleatorio entre **0-99**. 3) Determina si se ha presionado un botón y obtiene la lectura del botón. 4) Si se presiona el botón \'**A**\', aparecerá un número aleatorio **0-99** y el juego comienza. 5) Si se detecta que se ha presionado el botón \'**D**\', el programa entra en el juicio de resultado y muestra el resultado en la LCD. Este paso permite que puedas juzgar el resultado presionando solo un número y luego el botón \'**D**\'. 6) Si se presiona un botón **0-9**, el valor de **count** cambiará; si **count** es mayor que **10**, entonces comienza el juicio. 7) Los cambios en el juego y sus valores se muestran en la **LCD1602**. **Para Usuarios de Lenguaje Python** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Paso 3**: Cambia de directorio. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/python/ **Paso 4**: Ejecuta. .. raw:: html .. code-block:: sudo python3 3.1.12_GAME_GuessNumber.py Después de ejecutar el programa, la pantalla LCD muestra la página inicial: .. code-block:: Welcome! Press A to go! Presiona \'A\', y el juego comenzará mostrando la página de juego en la LCD. .. code-block:: Enter number: 0 ‹point‹ 99 Un número aleatorio \'**punto**\' es generado pero no se muestra en la pantalla LCD cuando el juego comienza, y lo que necesitas hacer es adivinarlo. El número ingresado aparecerá al final de la primera línea hasta que se complete el cálculo final. (Presiona \'D\' para iniciar la comparación, y si el número ingresado es mayor que **10**, la comparación automática comenzará.) El rango del número \'punto\' se muestra en la segunda línea, y debes ingresar un número dentro de ese rango. A medida que ingresas un número, el rango se reduce; si adivinas el número afortunado o desafortunado, aparecerá el mensaje \"¡Lo conseguiste!\" **Código** .. note:: Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código a continuación. Pero antes, necesitas dirigirte a la ruta del código fuente, como ``davinci-kit-for-raspberry-pi/python``. .. raw:: html .. code-block:: python import RPi.GPIO as GPIO import time import LCD1602 import random ##################### AQUÍ ESTÁ LA LIBRERÍA DEL TECLADO TRANSFERIDA DESDE Arduino ############ #class Key: Define algunas de las propiedades de Key class Keypad(): def __init__(self, rowsPins, colsPins, keys): self.rowsPins = rowsPins self.colsPins = colsPins self.keys = keys GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(self.rowsPins, GPIO.OUT, initial=GPIO.LOW) GPIO.setup(self.colsPins, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) def read(self): pressed_keys = [] for i, row in enumerate(self.rowsPins): GPIO.output(row, GPIO.HIGH) for j, col in enumerate(self.colsPins): index = i * len(self.colsPins) + j if (GPIO.input(col) == 1): pressed_keys.append(self.keys[index]) GPIO.output(row, GPIO.LOW) return pressed_keys ################ EL CÓDIGO DE EJEMPLO INICIA AQUÍ ################ count = 0 pointValue = 0 upper=99 lower=0 def setup(): 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 (dirección esclava, luz de fondo) LCD1602.clear() LCD1602.write(0, 0, 'Welcome!') LCD1602.write(0, 1, 'Press A to Start!') def init_new_value(): global pointValue,upper,count,lower pointValue = random.randint(0,99) upper = 99 lower = 0 count = 0 print('point is %d' %(pointValue)) def detect_point(): global count,upper,lower if count > pointValue: if count < upper: upper = count elif count < pointValue: if count > lower: lower = count elif count == pointValue: count = 0 return 1 count = 0 return 0 def lcd_show_input(result): LCD1602.clear() if result == 1: LCD1602.write(0,1,'You have got it!') time.sleep(5) init_new_value() lcd_show_input(0) return 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(): global keypad, last_key_pressed,count while(True): result = 0 pressed_keys = keypad.read() if len(pressed_keys) != 0 and last_key_pressed != pressed_keys: 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 list(["A","B","C","D","#","*"]): continue count = count * 10 count += int(pressed_keys[0]) if count >= 10: result = detect_point() lcd_show_input(result) print(pressed_keys) last_key_pressed = pressed_keys time.sleep(0.1) # Define una función destroy para limpiar todo después de que el script haya terminado def destroy(): # Liberar recursos GPIO.cleanup() LCD1602.clear() if __name__ == '__main__': # El programa comienza desde aquí try: setup() while True: loop() except KeyboardInterrupt: # Cuando se presiona 'Ctrl+C', se ejecuta destroy(). destroy() **Explicación del Código** Al comienzo del código se encuentran las funciones funcionales de **teclado** y **I2C LCD1602**. Puedes obtener más detalles sobre ellas en :ref:`1.1.7_i2c_lcd` y :ref:`2.1.5_keypad`. Aquí, lo que necesitamos saber es lo siguiente: .. code-block:: python def init_new_value():     global pointValue,upper,count,lower     pointValue = random.randint(0,99)     upper = 99     lower = 0     count = 0     print('point is %d' %(pointValue)) La función genera el número aleatorio \'**punto**\' y restablece el rango del punto. .. code-block:: python def detect_point():     global count,upper,lower     if count > pointValue:         if count < upper:             upper = count      elif count < pointValue:         if count > lower:             lower = count     elif count == pointValue:         count = 0         return 1     count = 0     return 0 detect_point() compara el número ingresado (**count**) con el \"**punto**\" generado. Si el resultado de la comparación es que no coinciden, **count** asignará valores a **upper** y **lower** y devolverá \'**0**\'; de lo contrario, si el resultado indica coincidencia, devuelve \'**1**\'. .. code-block:: python def lcd_show_input(result): LCD1602.clear() if result == 1: LCD1602.write(0,1,'You have got it!') time.sleep(5) init_new_value() lcd_show_input(0) return 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)) Esta función se utiliza para mostrar la página del juego. str(count): Debido a que **write()** solo admite el tipo de dato — **cadena de caracteres**, es necesario **str()** para convertir el **número** en una **cadena**. .. code-block:: python def loop():     global keypad, last_key_pressed,count while(True):         result = 0         pressed_keys = keypad.read()         if len(pressed_keys) != 0 and last_key_pressed != pressed_keys:             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 list(["A","B","C","D","#","*"]): continue                 count = count * 10                 count += int(pressed_keys[0])                 if count >= 10:                     result = detect_point() lcd_show_input(result) print(pressed_keys)         last_key_pressed = pressed_keys time.sleep(0.1) Main() contiene todo el proceso del programa, como se muestra a continuación: 1) Inicializa **I2C LCD1602** y **Teclado**. 2) Verifica si se ha presionado un botón y obtiene la lectura del botón. 3) Si se presiona el botón \'**A**\', aparecerá un número aleatorio **0-99** y el juego comenzará. 4) Si se detecta que se ha presionado el botón \'**D**\', el programa entrará en el juicio de resultado. 5) Si se presiona un botón **0-9**, el valor de **count** cambiará; si **count** es mayor que **10**, entonces comenzará el juicio. 6) Los cambios en el juego y sus valores se muestran en **LCD1602**. Imagen del Fenómeno ------------------------ .. image:: img/image274.jpeg :align: center