Bemerkung

Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Gemeinschaft auf Facebook! Tauchen Sie tiefer ein in die Welt von Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten.

Warum beitreten?

  • Expertenunterstützung: Lösen Sie Nachverkaufsprobleme und technische Herausforderungen mit Hilfe unserer Gemeinschaft und unseres Teams.

  • Lernen & Teilen: Tauschen Sie Tipps und Anleitungen aus, um Ihre Fähigkeiten zu verbessern.

  • Exklusive Vorschauen: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und exklusiven Einblicken.

  • Spezialrabatte: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.

  • Festliche Aktionen und Gewinnspiele: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.

👉 Sind Sie bereit, mit uns zu erkunden und zu erschaffen? Klicken Sie auf [hier] und treten Sie heute bei!

4.1.14 SPIEL – Zahlenraten

Einführung

Zahlenraten ist ein unterhaltsames Partyspiel, bei dem du und deine Freunde abwechselnd eine Zahl (0~99) eingeben. Mit jeder Eingabe verkleinert sich der Bereich, bis ein Spieler die richtige Zahl errät. Dann wird dieser Spieler „geschlagen“ und „bestraft“. Zum Beispiel, wenn die Glückszahl 51 ist, die die Spieler nicht sehen können, und Spieler ① gibt 50 ein, ändert sich der Bereichszahlenprompt zu 50~99; wenn Spieler ② 70 eingibt, kann der Zahlenbereich 50~70 sein; wenn Spieler ③ 51 eingibt, ist dieser Spieler der Pechvogel. Hier nutzen wir ein Tastenfeld für die Eingabe der Zahlen und ein LCD, um die Ergebnisse anzuzeigen.

Benötigte Komponenten

Für dieses Projekt benötigen wir die folgenden Komponenten.

../_images/4.1.17_game_guess_number_list.png

Es ist definitiv praktisch, ein ganzes Kit zu kaufen, hier ist der Link:

Name

ARTIKEL IN DIESEM KIT

LINK

Raphael Kit

337

Raphael Kit

Sie können sie auch separat über die untenstehenden Links kaufen.

KOMPONENTENVORSTELLUNG

KAUF-LINK

GPIO-Erweiterungsplatine

BUY

Steckbrett

BUY

Jumper-Kabel

BUY

Widerstand

BUY

Tastenfeld

-

I2C LCD1602

BUY

Schaltplan

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)

../_images/4.1.17_game_guess_number_schematic.png

Experimentelle Verfahren

Schritt 1: Bauen Sie den Schaltkreis.

../_images/4.1.17_game_guess_number_circuit.png

Schritt 2: I2C einrichten (siehe I2C Konfiguration.)

Schritt 3: Verzeichnis wechseln.

cd ~/raphael-kit/python-pi5

Schritt 4: Ausführen.

sudo python3 4.1.17_GAME_GuessNumber_zero.py

Nachdem das Programm gestartet wurde, zeigt das LCD die Startseite:

Willkommen!
Drücke A zum Start!

Drücke ‚A‘, und das Spiel beginnt, und die Spieloberfläche erscheint auf dem LCD.

Zahl eingeben:
0 ‹Punkt‹ 99

Eine zufällige Zahl ‹Punkt› wird produziert, aber nicht auf dem LCD angezeigt, wenn das Spiel startet, und deine Aufgabe ist es, sie zu erraten. Die von dir getippte Zahl erscheint am Ende der ersten Zeile, bis die endgültige Berechnung abgeschlossen ist. (Drücke ‚D‘ zum Starten des Vergleichs, und wenn die eingegebene Zahl größer als 10 ist, startet der automatische Vergleich.)

Der Zahlenbereich von ‚Punkt‘ wird in der zweiten Zeile angezeigt. Und du musst eine Zahl innerhalb des Bereichs tippen. Wenn du eine Zahl tippst, verengt sich der Bereich; wenn du die Glückszahl glücklich oder unglücklich triffst, erscheint „Du hast es geschafft!“

Bemerkung

  • Wenn der Fehler FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1' auftritt, beziehe dich auf I2C Konfiguration, um das I2C zu aktivieren.

  • Wenn der Fehler ModuleNotFoundError: No module named 'smbus2' auftritt, führe bitte sudo pip3 install smbus2 aus.

  • Wenn der Fehler OSError: [Errno 121] Remote I/O error erscheint, bedeutet dies, dass das Modul falsch verdrahtet ist oder das Modul defekt ist.

  • Wenn der Code und die Verdrahtung in Ordnung sind, aber das LCD immer noch keinen Inhalt anzeigt, kannst du das Potentiometer auf der Rückseite drehen, um den Kontrast zu erhöhen.

Code

Bemerkung

Du kannst den untenstehenden Code Modifizieren/Zurücksetzen/Kopieren/Ausführen/Stoppen. Aber davor musst du zum Quellcodepfad wie raphael-kit/python-pi5. Nachdem du den Code modifiziert hast, kannst du ihn direkt ausführen, um den Effekt zu sehen.

#!/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

Code-Erklärung

  1. Dieser Abschnitt importiert die notwendigen Klassen aus der GPIO Zero-Bibliothek, um digitale Ausgabegeräte und Tasten zu handhaben. Außerdem wird die sleep-Funktion aus dem time-Modul zum Einführen von Verzögerungen im Skriptablauf importiert. Die LCD1602-Bibliothek wird für die Bedienung des LCD-Displays importiert, was nützlich ist, um Text oder Datenausgaben anzuzeigen. Zusätzlich wird die random-Bibliothek eingefügt, die Funktionen zur Erzeugung zufälliger Zahlen bietet, was für verschiedene Aspekte des Projekts vorteilhaft sein kann.

    #!/usr/bin/env python3
    
    from gpiozero import DigitalOutputDevice, Button
    from time import sleep
    import LCD1602
    import random
    
  2. Definiert eine Klasse für das Keypad, initialisiert es mit Zeilen- und Spaltenpins und definiert eine Methode zum Lesen gedrückter Tasten.

    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
    
  3. Initialisiert eine Variable „count“ als Null, möglicherweise verwendet, um Versuche oder spezifische Werte im Spiel zu verfolgen. Konfiguriert das Keypad und LCD-Display mit einer Begrüßungsnachricht und Anweisungen. Initialisiert die Variable „pointValue“ auf Null, möglicherweise repräsentiert sie einen Zielwert oder Punktestand im Spiel. Definiert eine „obere“ Grenze für das Spiel, zunächst auf 99 gesetzt, was das Maximum in einem Zahlenratespiel sein könnte. Setzt die „untere“ Grenze beginnend von Null, wahrscheinlich verwendet als minimale Grenze im Spiel.

    # Game-related variables
    count = 0
    pointValue = 0
    upper = 99
    lower = 0
    
  4. Richtet das Keypad und LCD-Display ein, zeigt eine Begrüßungsnachricht und Anweisungen an.

    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!')
    
  5. Initialisiert einen neuen Zielwert für das Spiel und setzt die Spielparameter zurück.

    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)
    
  6. Überprüft, ob die geratene Zahl dem Ziel entspricht und aktualisiert entsprechend den Ratebereich.

    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
    
  7. Zeigt den Spielstand auf dem LCD an, zeigt die aktuelle Vermutung, den Bereich und das Ergebnis.

    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))
    
  8. Die Hauptschleife zur Handhabung der Keypad-Eingabe, Aktualisierung des Spielstands und Anzeige der Ergebnisse auf dem 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)
    
  9. Führt das Setup aus und tritt in die Hauptschleife ein, ermöglicht einen sauberen Ausstieg mit einem Tastaturinterrupt.

    try:
       setup()
       loop()
    except KeyboardInterrupt:
       LCD1602.clear()  # Clear LCD on interrupt