注釈
こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。
参加する理由は?
エキスパートサポート:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
学び&共有:ヒントやチュートリアルを交換してスキルを向上させましょう。
独占的なプレビュー:新製品の発表や先行プレビューに早期アクセスしましょう。
特別割引:最新製品の独占割引をお楽しみください。
祭りのプロモーションとギフト:ギフトや祝日のプロモーションに参加しましょう。
👉 私たちと一緒に探索し、創造する準備はできていますか?[ここ]をクリックして今すぐ参加しましょう!
4.1.12 ゲーム – 数当て¶
はじめに¶
数当ては、あなたと友達が交互に数字(0〜99)を入力する楽しいパーティーゲームです。数字の入力に従って、範囲は狭まっていき、プレイヤーが謎を正しく解答するまで続きます。その後、プレイヤーは負けて罰せられます。たとえば、幸運の数字が51で、プレイヤー1が50を入力した場合、数字の範囲は50〜99に変わります。プレイヤー2が70を入力すると、数字の範囲は50〜70になります。プレイヤー3が51を入力した場合、そのプレイヤーは不運です。ここでは、キーパッドを使用して数字を入力し、LCDを使用して結果を表示します。
必要な部品¶
このプロジェクトには、次のコンポーネントが必要です。
一式を購入するのが便利です、こちらがリンクです:
名前 |
このキットのアイテム |
リンク |
---|---|---|
Raphael Kit |
337 |
以下のリンクから別々に購入することもできます。
コンポーネントの紹介 |
購入リンク |
---|---|
- |
|
回路図¶
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) |
実験手順¶
ステップ 1: 回路を組み立てます。
ステップ 2: I2Cをセットアップします(詳細は I2C設定 を参照)。
ステップ 3: ディレクトリを変更します。
cd ~/raphael-kit/python-pi5
ステップ 4: 実行します。
sudo python3 3.1.12_GAME_GuessNumber_zero.py
プログラムが実行されると、LCDに初期ページが表示されます:
Welcome!
Press A to go!
'A'ボタンを押すと、ゲームが開始し、LCDにゲームページが表示されます。
Enter number:
0 < point < 99
ランダムな数字 '‹point‹' がゲーム開始時に生成されますが、LCDには表示されません。必要なことは、それを推測することです。入力した数値は、最終的な計算が終了するまで、最初の行の末尾に表示されます(比較を開始するには 'D' を押し、入力された数値が 10 より大きい場合、自動的な比較が開始されます)。
'‹point‹' の数値範囲が2行目に表示されます。指定された範囲内で数値を入力する必要があります。数値を入力すると、範囲が狭まり、幸運か不運かにかかわらず、 当たりました!
と表示されます。
注釈
エラー
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'
が表示される場合、I2Cを有効にするには I2C設定 を参照してください。エラー
ModuleNotFoundError: No module named 'smbus2'
が表示される場合、sudo pip3 install smbus2
を実行してください。エラー
OSError: [Errno 121] Remote I/O error
が表示される場合、モジュールの接続が誤っているか、モジュールが壊れている可能性があります。コードと配線が正常であるにもかかわらず、LCDにコンテンツが表示されない場合は、背面のポテンショメーターを回してコントラストを上げることができます。
コード
注釈
以下のコードを 修正/リセット/コピー/実行/停止 することができます。ただし、その前に raphael-kit/python-pi5
のソースコードパスに移動する必要があります。
#!/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
コード説明
GPIO Zeroライブラリからデジタル出力デバイスとボタンのための重要なクラスをインポートするセクションです。スクリプト内で遅延を導入するために、timeモジュールのsleep関数も含まれています。LCD1602ライブラリは、テキストやデータ出力を表示するために役立つLCDディスプレイの操作に利用されます。さらに、ランダムな数字を生成するための関数を提供するrandomライブラリも組み込まれています。これはプロジェクトのさまざまな面で有利になる可能性があります。
#!/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
ゲームに関連する変数
count
をゼロとして初期化し、キーパッドとLCDディスプレイを設定し、ウェルカムメッセージと指示を表示します。ゲームでの特定のスコアや値を表す可能性があるpointValue
変数をゼロに初期化します。当初は99に設定されたupper
は、数字当てゲームの最大値として使用される可能性があります。ゲームの最小境界として使用される可能性のあるゼロからのlower
限界を設定します。# Game-related variables count = 0 pointValue = 0 upper = 99 lower = 0
キーパッドとLCDディスプレイを設定し、ウェルカムメッセージと指示を表示します。
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
LCDにゲームの状態を表示し、現在の推測、範囲、結果を示します。
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))
キーパッド入力の処理、ゲームの状態の更新、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)
セットアップを実行し、メインゲームループに入ります。キーボード割り込みを使用してクリーンな終了が可能です。
try: setup() loop() except KeyboardInterrupt: LCD1602.clear() # Clear LCD on interrupt