注釈

こんにちは、FacebookのSunFounder Raspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Raspberry Pi、Arduino、ESP32についてもっと深く探求しましょう。

参加する理由?

  • 専門家のサポート: コミュニティとチームからのサポートで販売後の問題や技術的な課題を解決。

  • 学びと共有: スキル向上のためのヒントやチュートリアルを交換。

  • 独占プレビュー: 新製品の発表や先行予告をいち早く入手。

  • 特別割引: 最新製品の独占割引を楽しむ。

  • 祝祭プロモーションとギブアウェイ: ギブアウェイや休日プロモーションに参加。

👉 一緒に探求し、創造してみませんか?クリック [こちら] して今すぐ参加!

7.7 「数字当てゲーム」の作成

このプロジェクトでは、Raspberry Pi Pico 2、4x4マトリックスキーパッド、そしてI2C LCD1602ディスプレイを使用して、インタラクティブな 数字当てゲーム を構築します。ゲームは0から99までのランダムな数字を生成し、プレイヤーは交代でその数字を推測します。各プレイヤーの推測後、ゲームはその推測が高すぎたか低すぎたかに基づいて範囲を絞り込み、誰かが正しい数字を当てるまで続けます。

必要なもの

このプロジェクトには以下のコンポーネントが必要です。

キット全体を購入することは非常に便利です。こちらがリンクです:

名称

このキットに含まれるアイテム

リンク

Newton Lab Kit

450以上

Newton Lab Kit

以下のリンクから個別に購入することもできます。

SN

コンポーネント

数量

リンク

1

Raspberry Pi Pico 2

1

購入

2

Micro USBケーブル

1

3

ブレッドボード

1

購入

4

ジャンパーワイヤー

数本

購入

5

抵抗器

4(10KΩ)

購入

6

4x4キーパッド

1

購入

7

I2C LCD1602

1

購入

コンポーネントの理解

  • 4x4マトリックスキーパッド: 4行4列のマトリックスで配置された16個のボタンを持つキーパッドです。数字やコマンドの入力に使用します。

  • I2C LCD1602ディスプレイ: 16x2文字のLCDディスプレイで、I2Cインターフェースを備えており、SDAとSCLの2本のデータラインのみを使用することで配線を簡略化します。

回路図

sch_guess_number

この回路は 4.2 4x4 キーパッドの使用 に基づいており、押されたキーを表示するためのI2C LCD1602が追加されています。

配線図

wiring_game_guess_number

配線を容易にするために、上の図では、マトリックスキーボードの列行と10K抵抗が同時にG10〜G13の穴に挿入されます。

コードの書き方

MicroPythonプログラムを書いて、以下の操作を行います:

  • 0から99の間のランダムな数字を生成します。

  • キーパッドからの入力を読み取ります。

  • LCDディスプレイを更新して、ヒントとプレイヤーの入力を表示します。

  • 各予想の後で範囲を絞り込みます。

注釈

  • 7.7_game_guess_number.pynewton-lab-kit/micropython から開くか、Thonnyにコードをコピーして「実行」ボタンをクリックするか、F5キーを押します。

  • 正しいインタープリタが選択されていることを確認してください:MicroPython (Raspberry Pi Pico).COMxx。

  • lcd1602.py というライブラリを使用する必要がありますので、Picoにアップロードされているか確認してください。詳細なチュートリアルは Picoにライブラリをアップロード を参照してください。

from lcd1602 import LCD
from machine import I2C, Pin
import utime
import urandom

# LCD1602ディスプレイのためのI2C通信を初期化します
i2c = I2C(1, sda=Pin(6), scl=Pin(7), freq=400000)
lcd = LCD(i2c)

# 4x4マトリックスキーパッドのキャラクターマッピング
keypad_map = [
    ["1", "2", "3", "A"],
    ["4", "5", "6", "B"],
    ["7", "8", "9", "C"],
    ["*", "0", "#", "D"]
]

# 行と列のピンを定義します
row_pins = [Pin(pin_num, Pin.OUT) for pin_num in [21, 20, 19, 18]]  # R1-R4
col_pins = [Pin(pin_num, Pin.IN, Pin.PULL_DOWN) for pin_num in [13, 12, 11, 10]]  # C1-C4

# キーパッドをスキャンする関数
def read_keypad():
    for row_num, row_pin in enumerate(row_pins):
        row_pin.high()
        for col_num, col_pin in enumerate(col_pins):
            if col_pin.value() == 1:
                row_pin.low()
                return keypad_map[row_num][col_num]
        row_pin.low()
    return None

# ゲーム変数を初期化する関数
def init_game():
    global target_number, lower_bound, upper_bound, guess
    target_number = urandom.randint(0, 99)
    lower_bound = 0
    upper_bound = 99
    guess = ""
    lcd.clear()
    lcd.message("Press A to Start")

# ディスプレイを更新する関数
def update_display(message):
    lcd.clear()
    lcd.message(message)

# メインプログラム
init_game()
game_started = False

while True:
    key = read_keypad()
    if key:
        utime.sleep(0.2)  # デバウンスの遅延

        if not game_started:
            if key == "A":
                game_started = True
                update_display("Enter your guess:")
        else:
            if key in "0123456789":
                if len(guess) < 2:
                    guess += key
                    update_display("Guess: {}\n{} < ? < {}".format(guess, lower_bound, upper_bound))
            elif key == "D":
                if guess != "":
                    guess_number = int(guess)
                    if guess_number < lower_bound or guess_number > upper_bound:
                        update_display("Out of range!\n{} < ? < {}".format(lower_bound, upper_bound))
                    elif guess_number > target_number:
                        upper_bound = guess_number - 1
                        guess = ""
                        update_display("Too High!\n{} < ? < {}".format(lower_bound, upper_bound))
                    elif guess_number < target_number:
                        lower_bound = guess_number + 1
                        guess = ""
                        update_display("Too Low!\n{} < ? < {}".format(lower_bound, upper_bound))
                    else:
                        update_display("Correct!\nNumber is {}".format(target_number))
                        game_started = False
                        utime.sleep(2)
                        init_game()
                else:
                    update_display("Enter a number")
            elif key == "A":
                # ゲームを再開します
                init_game()
                game_started = True
                update_display("Enter your guess:")
            elif key == "B":
                # 現在の推測をクリアします
                guess = ""
                update_display("Guess cleared")
            elif key == "C":
                # ヒントを表示するか、その他の機能
                update_display("Hint not available")
    utime.sleep(0.1)

コードが実行された後、ゲームをプレイするための手順に従ってください:

  • ゲームを開始:

    キーパッドの「A」キーを押します。

  • 推測を入力:

    • 数字キーを使用してあなたの推測を入力します(0-99)。

    • 推測を送信するには「D」を押します。

  • フィードバックを受け取る:

    • LCDはあなたの推測が高すぎる、低すぎる、または正しいかを示します。

    • 範囲はそれに応じて調整されます。

  • ゲームに勝つ:

    • 正しい数字を推測すると、LCDに「Correct! Number is XX」と表示されます。

    • ゲームは短い遅延の後に自動的にリセットされます。

コードの理解

  1. インポートと初期化:

    • lcd1602.LCD: LCDディスプレイを制御するために。

    • machine.Pin: GPIOピンとのやり取りのために。

    • urandom: ランダムな数字を生成するために。

    • LCD1602ディスプレイのためのI2C通信を初期化します。

  2. キーパッドスキャン機能( read_keypad ):

    • 一度に一つの行を高く設定します。

    • 任意の列が高く読み取られた場合、ボタンが押されたことを示します。

    • 押されたキーに対応する文字を返します。

    def read_keypad():
        for row_num, row_pin in enumerate(row_pins):
            row_pin.high()
            for col_num, col_pin in enumerate(col_pins):
                if col_pin.value() == 1:
                    row_pin.low()
                    return keypad_map[row_num][col_num]
            row_pin.low()
        return None
    
  3. ゲーム変数と初期化( init_game ):

    • target_number: 0から99の間のランダムな数字。

    • lower_bound and upper_bound: それぞれ0と99から始まります。

    • guess: 現在の推測入力を格納する文字列。

    def init_game():
        global target_number, lower_bound, upper_bound, guess
        target_number = urandom.randint(0, 99)
        lower_bound = 0
        upper_bound = 99
        guess = ""
        lcd.clear()
        lcd.message("Press A to Start")
    
  4. ディスプレイ更新機能( update_display ):

    LCDをクリアして、提供されたメッセージを表示します。

    # Display function
    def update_display(message):
        lcd.clear()
        lcd.message(message)
    
  5. メインプログラムループ:

    • キー入力を待ち、ゲームロジックを処理します。

    • キー A : ゲームを開始または再開します。

    • 数字 0 - 9 : 現在の推測番号を構築します。

    • キー D : 推測を送信し、範囲を更新します。

    • 推測が現在の範囲内にあるかどうかをチェックします。

    • 推測に基づいて lower_bound または upper_bound を更新します。

    • 次の入力のために推測をリセットします。

    • 推測が正しい場合は、成功メッセージを表示し、ゲームをリセットします。

    • キー B: 現在の推測をクリアします。

    • キー C: 追加の機能用(例:ヒント)。

    while True:
        key = read_keypad()
        if key:
            utime.sleep(0.2)  # デバウンスの遅延
    
            if not game_started:
                if key == "A":
                    game_started = True
                    update_display("Enter your guess:")
    ...
    ...
        utime.sleep(0.1)
    
  6. デバウンシングと遅延:

    • utime.sleep(0.2): キー押下後の短い遅延でデバウンス。

    • utime.sleep(0.1): メインループの小さな遅延でCPU使用を減らします。

トラブルシューティング

  • LCDがテキストを表示しない:

    • SDAとSCLの接続(GP6とGP7)を確認します。

    • LCDが正しく電源供給されているかをチェックします。

    • LCDモジュールの裏にあるコントラストポテンショメータを調整します。

  • キーパッドが反応しない:

    • すべての行と列の接続をチェックします。

    • 内部プルダウンを使用していない場合は、プルダウン抵抗が接続されていることを確認します。

    • キーパッドが正常に機能しているかを確認します。

  • ランダム数が変更されない:

    • urandom が適切にインポートされ、使用されていることを確認します。

    • ランダムシードが初期化される必要があるかもしれません。

  • ゲームロジックの問題:

    • 推測を処理するときの条件と範囲を再確認します。

    • 上限と下限が正しく更新されていることを確認します。

拡張と改良

  • マルチプレイヤーサポートの追加:

    • 各プレイヤーが行う推測の数を追跡します。

    • プレイヤー間で順番を交代します。

  • スコアリングシステムの実装:

    • 数字をどれだけ早く推測したかに基づいてポイントを授与します。

    • LCDにスコアを表示します。

  • ヒントの提供:

    'C'キーを使用して、「数字は偶数です」または「数字は5の倍数です」といったヒントを提供します。

  • 範囲の拡大:

    • ゲームを0から999の数字を推測するように変更します。

    • 表示と入力方法をそれに応じて調整します。

  • 視覚的および音声フィードバック:

    追加のフィードバックを提供するために、LEDやブザーを追加します。

結論

Raspberry Pi Pico 2を使用してインタラクティブな「数字当てゲーム」を成功裏に構築しました!このプロジェクトは、ユーザー入力、ランダム数生成、およびディスプレイ出力を組み合わせて、楽しく魅力的なゲームを作り出しています。キーパッド、LCDディスプレイ、ゲームロジックのMicroPythonでの作業に慣れる絶好の方法です。

このゲームをさらに強化して新しい機能を追加したり、インタフェースを改善することが自由です。このプロジェクトは、より複雑なインタラクティブアプリケーションの基盤として機能することができます。