Pythonツール ゲーム

Pythonで簡単にタイピング練習!スコア付きのタイピングゲームを作成しよう

概要

Pythonを使ってタイピング練習ができるスコア付きのタイピングゲームを作成する方法をご紹介します。このゲームは、JSONファイルから日本語とローマ字のペアを読み込み、ユーザーがタイピングを練習できるように設計されています。ゲーム終了後にエンターキーを押すことで、同じJSONファイルで新しいゲームを開始できる機能も実装しています。

使用例

このタイピングゲームは、日本語とそのローマ字表記を使ってタイピングの練習ができます。ゲームは10問出題し、各問題に対して正確にローマ字を入力することで得点が加算されます。ゲーム終了後、エンターキーを押すことで同じJSONファイルを使って新しいゲームを開始することができます。

必要なPythonライブラリとインストール方法

このタイピングゲームを作成するためには、以下のPythonライブラリが必要です。

  • tkinter:Pythonに標準で含まれているため、追加のインストールは不要です。

使用手順

  1. JSONファイルを準備する
    • JSONファイルには、日本語とそのローマ字表記のペアを10つ以上含める必要があります。以下のような形式で保存してください。
    { "words": [ {"japanese": "りんご", "romaji": "ringo"}, {"japanese": "ばなな", "romaji": "banana"}, {"japanese": "さくらんぼ", "romaji": "sakuranbo"}, {"japanese": "なし", "romaji": "nashi"}, {"japanese": "ぶどう", "romaji": "budou"}, {"japanese": "みかん", "romaji": "mikan"}, {"japanese": "いちご", "romaji": "ichigo"}, {"japanese": "すいか", "romaji": "suika"}, {"japanese": "もも", "romaji": "momo"}, {"japanese": "めろん", "romaji": "meron"} ] }
  2. Pythonプログラムの作成
    • 下記のコードをメモ帳などに丸々コピーしてtyping.pyというPythonファイルにしてください
  3. プログラムの実行
    • コマンドラインで以下のコマンドを実行してプログラムを開始します。
    python typing.py
  4. タイピングゲームのプレイ
    • プログラムを実行すると、ファイル選択ダイアログが表示されます。事前に準備したJSONファイルを選択してください。
    • ゲームが開始され、画面に日本語が表示されます。そのローマ字を入力してゲームを進めます。
    • 10問終了するとゲームが終了します。エンターキーを押すと、同じJSONファイルを使って新しいゲームを開始します。

下記に435個の言葉を収録したjsonファイルを用意しましたので必要に応じてダウンロードしてください。

また、csvで"japanese"と"romaji"のペアのcsvファイルを作ってドラッグアンドドロップでjsonファイルにするプログラムを作成したので、自分で用意したい方は是非下記リンクを参考に作成してみてください。

注意点

  • JSONファイルには10つ以上の日本語とローマ字のペアが含まれている必要があります。
  • JSONファイルのフォーマットが正しくない場合、エラーメッセージが表示されます。
  • ゲーム中に表示されるローマ字を正確に入力することで、1文字ずつ表示が消えていきます。

プログラム

下記のコードをメモ帳などに丸々コピーしてtyping.pyというPythonファイルにしてください。

import json
import random
import tkinter as tk
from tkinter import filedialog, messagebox
import time

class TypingPractice:
def __init__(self, master):
self.master = master
self.master.title("タイピング練習")
self.score = 0
self.current_word = ""
self.words = []
self.index = 0
self.current_round = 0
self.total_rounds = 10
self.start_time = None
self.timer_id = None
self.game_active = False
self.file_path = None

self.label_japanese = tk.Label(master, text="", font=("Helvetica", 18))
self.label_japanese.pack(pady=10)

self.label_romaji = tk.Label(master, text="", font=("Helvetica", 18))
self.label_romaji.pack(pady=10)

self.entry = tk.Entry(master, font=("Helvetica", 18))
self.entry.pack(pady=10)
self.entry.bind("<KeyRelease>", self.check_input)

self.label_score = tk.Label(master, text="スコア: 0", font=("Helvetica", 18))
self.label_score.pack(pady=10)

self.label_progress = tk.Label(master, text="", font=("Helvetica", 18))
self.label_progress.pack(pady=10)

self.label_timer = tk.Label(master, text="タイマー: 0 秒", font=("Helvetica", 18))
self.label_timer.pack(pady=10)

self.button_start = tk.Button(master, text="JSONファイルを選択して開始", command=self.start_game, font=("Helvetica", 14))
self.button_start.pack(pady=20)

self.master.bind("<Return>", self.restart_game)

def load_words(self, file_path):
try:
with open(file_path, 'r', encoding='utf-8') as file:
data = json.load(file)
if len(data['words']) < 10:
raise ValueError("ファイル内の単語が不足しています。")
return random.sample(data['words'], 10)
except (json.JSONDecodeError, KeyError, ValueError) as e:
messagebox.showerror("エラー", f"ファイルの読み込みに失敗しました: {e}")
return None

def start_game(self):
self.file_path = filedialog.askopenfilename(
title="Select JSON file",
filetypes=(("JSON files", "*.json"), ("All files", "*.*"))
)
if self.file_path:
self.words = self.load_words(self.file_path)
if self.words:
self.reset_game()
self.game_active = True
self.start_time = time.time()
self.update_timer()
self.update_score()
self.next_word()

def restart_game(self, event):
if not self.game_active and self.file_path:
self.words = self.load_words(self.file_path)
if self.words:
self.reset_game()
self.game_active = True
self.start_time = time.time()
self.update_timer()
self.update_score()
self.next_word()

def reset_game(self):
self.score = 0
self.current_round = 0
self.entry.config(state="normal")
self.label_japanese.config(text="")
self.label_romaji.config(text="")
self.label_progress.config(text="")
self.label_timer.config(text="タイマー: 0 秒")
self.label_score.config(text="スコア: 0")
if self.timer_id:
self.master.after_cancel(self.timer_id)

def next_word(self):
if self.current_round >= self.total_rounds:
self.label_japanese.config(text="ゲーム終了")
self.label_romaji.config(text="")
self.entry.config(state="disabled")
self.game_active = False
self.master.after_cancel(self.timer_id)
return

self.current_pair = self.words.pop()
self.current_word = self.current_pair['romaji']
self.index = 0

self.label_japanese.config(text=self.current_pair['japanese'])
self.label_romaji.config(text=self.current_word)
self.label_progress.config(text=f"{self.current_round + 1}/{self.total_rounds}")
self.entry.delete(0, tk.END)

self.current_round += 1

def check_input(self, event):
if not self.game_active:
return

user_input = self.entry.get()

if user_input == self.current_word[:len(user_input)]:
if user_input == self.current_word:
self.score += 10
self.next_word()
else:
self.label_romaji.config(text=self.current_word[len(user_input):])
self.index += 1
else:
self.score -= 5
self.entry.delete(len(user_input) - 1, tk.END)

self.update_score()

def update_score(self):
self.label_score.config(text=f"スコア: {self.score}")

def update_timer(self):
elapsed_time = int(time.time() - self.start_time)
self.label_timer.config(text=f"タイマー: {elapsed_time} 秒")
self.timer_id = self.master.after(1000, self.update_timer)

if __name__ == "__main__":
root = tk.Tk()
app = TypingPractice(root)
root.mainloop()

あるいは、下のテキストファイルをダウンロードし、「.txt」を「.py」に変えることでそのまま使えます。

まとめ

このPythonプログラムを使ってタイピング練習ができるGUI付きのタイピングゲームを簡単に作成することができます。JSONファイルから日本語とローマ字のペアを読み込み、ゲーム終了後にエンターキーを押すことで再度同じファイルで新しいゲームを開始することができます。プログラムを実行して、楽しくタイピングスキルを向上させましょう!

なお、webで動くHTML5、javascript版は下記になります。参考にどうぞ!

-Pythonツール, ゲーム