From 6515dd764096763cb1daa15fc3d55ac0224d830a Mon Sep 17 00:00:00 2001 From: tanosou Date: Tue, 10 Feb 2026 10:38:22 +0900 Subject: [PATCH 1/4] add quiz-system --- CHANGELOG.md | 10 +++ assets/dialogues/dialogues.json | 32 ++++++++++ src/core/talk.py | 108 +++++++++++++++++++++++++++++--- src/utils.py | 11 ++++ 4 files changed, 154 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94359ef..4896bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # CHANGELOG of PBL-Game +## v0.43.0 (2026-02-10) +- クイズシステムの追加 + - テキスト入力形式(今回は半角数字のみに限定)のクイズを追加 + - `talk.py`のクイズ処理を三択問題とテキスト入力形式で分岐するように + - `quiz_type`を`text`(テキスト入力問題),`choice`(選択問題)で区別 + - 入力は10文字まで、backspaceで削除、zで決定 + +## v0.42.3 (2026-02-10) +- ゲームタイトルから「Demo ver」を消去し、タイトルを修正 + ## v0.42.2 (2026-01-27) - 新規NPC画像の追加 - `npc2.png` の画像ファイルを老人(青)から中年男性(青)に差し替え diff --git a/assets/dialogues/dialogues.json b/assets/dialogues/dialogues.json index 4343709..d4146ca 100644 --- a/assets/dialogues/dialogues.json +++ b/assets/dialogues/dialogues.json @@ -376,5 +376,37 @@ "speed": 0.0, "max_offset": 0 } + }, + "npc_text_quiz": { + "position": [ + 220, + 105 + ], + "map_id": "world", + "image": "character/npc1.png", + "lines": [ + "テキスト入力問題のテストだ。", + "簡単な計算問題を出すぞ。" + ], + "movement_x": { + "enabled": false, + "speed": 0.0, + "max_offset": 0 + }, + "quiz": [ + { + "type": "text", + "question": "1+1は?半角数字で入力してね。zキーで決定だ。", + "answer": "2" + }, + { + "type": "text", + "question": "3×5は?半角数字で入力してね。zキーで決定だ。", + "answer": "15" + } + ], + "reward": [ + "test_item" + ] } } \ No newline at end of file diff --git a/src/core/talk.py b/src/core/talk.py index 47a58f7..e62bf0c 100644 --- a/src/core/talk.py +++ b/src/core/talk.py @@ -29,8 +29,9 @@ def __init__(self, app): self.quiz_mode = False # クイズ中か self.quiz_result_mode = False # クイズ結果の表示中か self.current_quiz = None - self.quiz_choice = 0 + self.quiz_choice = 0 # 3択時の選択番号 self.quiz_index = 0 # 複数クイズのインデックス + self.quiz_text_input = "" # テキスト入力モード時の入力内容 self.wait_frames = 0 def is_active(self): @@ -152,6 +153,15 @@ def _handle_quiz(self, keys): if not self.current_quiz: return + quiz_type = self.current_quiz.get("type", "choice") + + if quiz_type == "text": + self._handle_text_quiz(keys) + else: # デフォルトは choice + self._handle_choice_quiz(keys) + + def _handle_choice_quiz(self, keys): + """3択問題の処理""" choices = self.current_quiz.get("choices", []) # 選択肢の移動 @@ -164,6 +174,23 @@ def _handle_quiz(self, keys): elif keys.get("z"): self._evaluate_quiz_answer() + def _handle_text_quiz(self, keys): + """テキスト入力問題の処理""" + # 数字キーの入力 + for digit in "0123456789": + if keys.get(digit): + # 10文字まで入力可能 + if len(self.quiz_text_input) < 10: + self.quiz_text_input += digit + + # BackSpaceキーで入力削除 + if keys.get("backspace"): + self.quiz_text_input = self.quiz_text_input[:-1] + + # 決定(Zキー) + elif keys.get("z"): + self._evaluate_text_quiz_answer() + def _evaluate_quiz_answer(self): """クイズの正誤判定""" q = self.current_quiz @@ -214,6 +241,60 @@ def _evaluate_quiz_answer(self): self.quiz_result_mode = True self.wait_frames = 15 + def _evaluate_text_quiz_answer(self): + """テキスト入力クイズの正誤判定""" + q = self.current_quiz + npc_data = self.dialogues.get(self.active, {}) + quiz = npc_data.get("quiz") + + # ユーザーの入力値と正解を比較 + user_answer = self.quiz_text_input.strip() + correct_answer = str(q.get("answer", "")) + + result_lines = [] + if user_answer == correct_answer: + if isinstance(quiz, list): + self.quiz_index += 1 + if self.quiz_index >= len(quiz): + # すべて正解 + result_lines.append("全問正解だ!素晴らしい。") + reward = npc_data.get("reward") + if reward: + for item_id in reward: + result_lines.append(f"【{item_id}】を手に入れた。") + self.app.items.extend(reward) + npc_data["quiz_done"] = True + else: + # 次のクイズへ + result_lines.append("正解!次の問題だ。") + self.current_quiz = quiz[self.quiz_index] + self.quiz_text_input = "" + self.window_lines = [] + self.wait_frames = 15 + return # 結果表示せずに次のクイズへ + else: + result_lines.append("正解だ!素晴らしい。") + reward = q.get("reward") + if reward: + for item_id in reward: + result_lines.append(f"【{item_id}】を手に入れた。") + self.app.items.extend(reward) + npc_data["quiz_done"] = True + else: + result_lines.append("残念、不正解だ。") + if isinstance(quiz, list): + result_lines.append("最初の問題からやり直しだ。") + self.quiz_index = 0 + self.current_quiz = quiz[self.quiz_index] + self.quiz_text_input = "" + else: + result_lines.append("もう一度挑戦してくれたまえ。") + + self.window_lines = result_lines + self.line_index = 0 + self.quiz_result_mode = True + self.wait_frames = 15 + def try_talk(self): """プレイヤーの周囲にNPCがいるか確認し、会話を開始する""" if self.is_active() or self.wait_frames > 0: @@ -236,6 +317,7 @@ def _open_dialog(self, data): self.quiz_result_mode = False self.current_quiz = None self.quiz_index = 0 + self.quiz_text_input = "" self.wait_frames = 15 def _close_dialog(self): @@ -246,6 +328,7 @@ def _close_dialog(self): self.quiz_mode = False self.quiz_result_mode = False self.quiz_index = 0 + self.quiz_text_input = "" self.wait_frames = 20 def draw(self, screen, font): @@ -259,14 +342,25 @@ def draw(self, screen, font): if self.quiz_mode and not self.quiz_result_mode: q = self.current_quiz - display_lines = [q.get("question", "")] + quiz_type = q.get("type", "choice") + + if quiz_type == "text": + # テキスト入力クイズの描画 + display_lines = [ + q.get("question", ""), + f"入力: {self.quiz_text_input}_", + ] + draw_window(screen, font, display_lines, rect) + else: + # 3択クイズの描画 + display_lines = [q.get("question", "")] - # 選択肢の構築 - for i, choice in enumerate(q.get("choices", [])): - cursor = ">" if i == self.quiz_choice else " " - display_lines.append(f"{cursor} {i + 1}. {choice}") + # 選択肢の構築 + for i, choice in enumerate(q.get("choices", [])): + cursor = ">" if i == self.quiz_choice else " " + display_lines.append(f"{cursor} {i + 1}. {choice}") - draw_window(screen, font, display_lines, rect) + draw_window(screen, font, display_lines, rect) elif self.window_lines: # 1行ずつ表示するための修正 diff --git a/src/utils.py b/src/utils.py index 2951698..8fd2e75 100644 --- a/src/utils.py +++ b/src/utils.py @@ -30,6 +30,17 @@ class KeyTracker: "s": pygame.K_s, "i": pygame.K_i, "m": pygame.K_m, + "0": pygame.K_0, + "1": pygame.K_1, + "2": pygame.K_2, + "3": pygame.K_3, + "4": pygame.K_4, + "5": pygame.K_5, + "6": pygame.K_6, + "7": pygame.K_7, + "8": pygame.K_8, + "9": pygame.K_9, + "backspace": pygame.K_BACKSPACE, } def __init__(self): From c9ae17bc54fce8df16273612a993283782fabc44 Mon Sep 17 00:00:00 2001 From: tanosou Date: Tue, 10 Feb 2026 10:50:28 +0900 Subject: [PATCH 2/4] add period --- CHANGELOG.md | 2 +- src/core/talk.py | 15 +++++++++------ src/utils.py | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4896bbb..987a26f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - `talk.py`のクイズ処理を三択問題とテキスト入力形式で分岐するように - `quiz_type`を`text`(テキスト入力問題),`choice`(選択問題)で区別 - 入力は10文字まで、backspaceで削除、zで決定 - + - `utils.py`に(0,1,2,3,4,5,6,7,8,9,backspace,period)を追加 ## v0.42.3 (2026-02-10) - ゲームタイトルから「Demo ver」を消去し、タイトルを修正 diff --git a/src/core/talk.py b/src/core/talk.py index e62bf0c..4bddfaa 100644 --- a/src/core/talk.py +++ b/src/core/talk.py @@ -29,7 +29,7 @@ def __init__(self, app): self.quiz_mode = False # クイズ中か self.quiz_result_mode = False # クイズ結果の表示中か self.current_quiz = None - self.quiz_choice = 0 # 3択時の選択番号 + self.quiz_choice = 0 self.quiz_index = 0 # 複数クイズのインデックス self.quiz_text_input = "" # テキスト入力モード時の入力内容 self.wait_frames = 0 @@ -176,12 +176,15 @@ def _handle_choice_quiz(self, keys): def _handle_text_quiz(self, keys): """テキスト入力問題の処理""" - # 数字キーの入力 - for digit in "0123456789": - if keys.get(digit): - # 10文字まで入力可能 + # 半角数字およびピリオドの入力 + for ch in "0123456789.": + if keys.get(ch): + # ピリオドは1つまで + if ch == "." and "." in self.quiz_text_input: + continue + # 入力文字数は10文字までに制限 if len(self.quiz_text_input) < 10: - self.quiz_text_input += digit + self.quiz_text_input += ch # BackSpaceキーで入力削除 if keys.get("backspace"): diff --git a/src/utils.py b/src/utils.py index 8fd2e75..357ae00 100644 --- a/src/utils.py +++ b/src/utils.py @@ -41,6 +41,7 @@ class KeyTracker: "8": pygame.K_8, "9": pygame.K_9, "backspace": pygame.K_BACKSPACE, + ".": pygame.K_PERIOD, } def __init__(self): From f6576bdfbd3f7ebb901d2f1d8210f8cecd2cd0fc Mon Sep 17 00:00:00 2001 From: tanosou Date: Tue, 10 Feb 2026 10:55:12 +0900 Subject: [PATCH 3/4] add changelog --- CHANGELOG.md | 4 +++- assets/dialogues/dialogues.json | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 987a26f..47579c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,11 @@ - クイズシステムの追加 - テキスト入力形式(今回は半角数字のみに限定)のクイズを追加 - `talk.py`のクイズ処理を三択問題とテキスト入力形式で分岐するように - - `quiz_type`を`text`(テキスト入力問題),`choice`(選択問題)で区別 + - "quiz_type"を"text"(テキスト入力問題),"choice"(選択問題)で区別 - 入力は10文字まで、backspaceで削除、zで決定 - `utils.py`に(0,1,2,3,4,5,6,7,8,9,backspace,period)を追加 + - `dialogue.json`に"npc_text_quiz"(テキスト入力問題確認用のnpc)を追加 + ## v0.42.3 (2026-02-10) - ゲームタイトルから「Demo ver」を消去し、タイトルを修正 diff --git a/assets/dialogues/dialogues.json b/assets/dialogues/dialogues.json index d4146ca..eedfaa8 100644 --- a/assets/dialogues/dialogues.json +++ b/assets/dialogues/dialogues.json @@ -396,8 +396,8 @@ "quiz": [ { "type": "text", - "question": "1+1は?半角数字で入力してね。zキーで決定だ。", - "answer": "2" + "question": "1+1.1は?半角数字で入力してね。zキーで決定だ。", + "answer": "2.1" }, { "type": "text", From 6bee7ed8c0ed00b6ed6dd55fd9e7b43092b289b0 Mon Sep 17 00:00:00 2001 From: Pantsman <214776175+pantsman-jp@users.noreply.github.com> Date: Tue, 10 Feb 2026 11:18:46 +0900 Subject: [PATCH 4/4] fix md Co-authored-by: tanosou Co-authored-by: pantsman-jp --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47579c0..ebb7106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,11 @@ ## v0.43.0 (2026-02-10) - クイズシステムの追加 - テキスト入力形式(今回は半角数字のみに限定)のクイズを追加 - - `talk.py`のクイズ処理を三択問題とテキスト入力形式で分岐するように - - "quiz_type"を"text"(テキスト入力問題),"choice"(選択問題)で区別 - - 入力は10文字まで、backspaceで削除、zで決定 - - `utils.py`に(0,1,2,3,4,5,6,7,8,9,backspace,period)を追加 - - `dialogue.json`に"npc_text_quiz"(テキスト入力問題確認用のnpc)を追加 + - `talk.py` のクイズ処理を三択問題とテキスト入力形式で分岐するように + - "quiz_type" を "text"(テキスト入力問題), "choice"(選択問題)で区別 + - 入力は10文字まで、backspace で削除、z で決定 + - `utils.py` に (0,1,2,3,4,5,6,7,8,9,backspace,period) を追加 + - `dialogue.json` に "npc_text_quiz"(テキスト入力問題確認用のnpc)を追加 ## v0.42.3 (2026-02-10) - ゲームタイトルから「Demo ver」を消去し、タイトルを修正