ナンプレアプリの作成

プログラミング

ナンプレアプリが完成しました!🎉ダウンロードと使い方

みなさん、こんにちは!以前から開発を進めていたPython製のナンプレアプリがついに完成しました。この記事では、アプリの機能や、誰でも簡単に試せるダウンロード方法についてご紹介します。

このアプリは、プログラミング初心者の方でも楽しめるように、シンプルさを追求して作りました。ぜひ一度、お手元で試してみてください!


1. アプリの機能

このアプリは、新しいナンプレの問題を自動で生成し、答え合わせができる機能を持っています。シンプルなUIなので、直感的に操作できます。

  • 自動問題生成: アプリを起動するたびに、新しいナンプレの問題が自動で生成されます。
  • 答え合わせ機能: 自分の解答が正しいかどうかをボタン一つで確認できます。
  • シンプルなUI: 余計な機能は一切なく、ナンプレに集中できるデザインです。

2. ソースコード

このアプリは、PythonとGUIライブラリのTkinterを使って開発しました。ソースコードは以下の通りです。

Python

import tkinter as tk
from tkinter import messagebox
import random

class SudokuApp:
    def __init__(self, master):
        self.master = master
        self.master.title("ナンプレ")
        self.master.resizable(False, False)

        self.initial_board = []
        self.current_board = []
        
        self.create_widgets()
        self.new_game()

    def create_widgets(self):
        main_frame = tk.Frame(self.master, padx=10, pady=10)
        main_frame.pack()

        self.cells = [[None for _ in range(9)] for _ in range(9)]
        
        for row in range(9):
            for col in range(9):
                padx = 1 if col % 3 != 2 else 3
                pady = 1 if row % 3 != 2 else 3
                
                cell_frame = tk.Frame(main_frame, width=38, height=38, bg='black')
                cell_frame.grid(row=row, column=col, padx=(0, padx), pady=(0, pady))

                entry = tk.Entry(cell_frame, width=2, font=('Arial', 24), justify='center', bd=0)
                entry.pack(expand=True, fill='both')
                
                entry.bind('<KeyRelease>', lambda e, r=row, c=col: self.on_key_release(e, r, c))
                
                self.cells[row][col] = entry

        button_frame = tk.Frame(self.master, pady=10)
        button_frame.pack()
        
        check_button = tk.Button(button_frame, text="答え合わせ", command=self.check_solution, font=('Arial', 14))
        check_button.pack(side=tk.LEFT, padx=10)

        new_game_button = tk.Button(button_frame, text="新しいゲーム", command=self.new_game, font=('Arial', 14))
        new_game_button.pack(side=tk.LEFT, padx=10)

        self.message_label = tk.Label(self.master, text="", font=('Arial', 12))
        self.message_label.pack(pady=5)

    def generate_board(self, difficulty=40):
        board = [[0] * 9 for _ in range(9)]
        self._solve(board)
        
        cells_to_remove = difficulty
        while cells_to_remove > 0:
            row, col = random.randint(0, 8), random.randint(0, 8)
            if board[row][col] != 0:
                board[row][col] = 0
                cells_to_remove -= 1
        
        return board

    def _is_valid(self, board, row, col, num):
        for i in range(9):
            if board[row][i] == num or board[i][col] == num:
                return False
        
        start_row, start_col = 3 * (row // 3), 3 * (col // 3)
        for i in range(3):
            for j in range(3):
                if board[start_row + i][start_col + j] == num:
                    return False
        
        return True

    def _solve(self, board):
        for row in range(9):
            for col in range(9):
                if board[row][col] == 0:
                    nums = list(range(1, 10))
                    random.shuffle(nums)
                    for num in nums:
                        if self._is_valid(board, row, col, num):
                            board[row][col] = num
                            if self._solve(board):
                                return True
                            board[row][col] = 0
                    return False
        return True

    def render_board(self):
        for row in range(9):
            for col in range(9):
                entry = self.cells[row][col]
                entry.config(state='normal', fg='black')
                entry.delete(0, tk.END)

                value = self.initial_board[row][col]
                if value != 0:
                    entry.insert(0, str(value))
                    entry.config(state='readonly', bg='#e0e0e0', readonlybackground='#e0e0e0', fg='black')
                else:
                    entry.config(bg='white')
    
    def on_key_release(self, event, row, col):
        value = self.cells[row][col].get()
        if value.isdigit() and 1 <= int(value) <= 9:
            self.current_board[row][col] = int(value)
            self.message_label.config(text="")
        else:
            self.current_board[row][col] = 0

    def new_game(self):
        self.initial_board = self.generate_board()
        self.current_board = [row[:] for row in self.initial_board]
        self.render_board()
        self.message_label.config(text="")

    def check_solution(self):
        for row in range(9):
            for col in range(9):
                value = self.cells[row][col].get()
                if value.isdigit() and 1 <= int(value) <= 9:
                    self.current_board[row][col] = int(value)
                else:
                    self.current_board[row][col] = 0

        solved_board = [row[:] for row in self.initial_board]
        self._solve(solved_board)
        
        if self.current_board == solved_board:
            self.message_label.config(text="お見事!正解です!🎉", fg="green")
        else:
            self.message_label.config(text="残念、間違いがあります。もう一度挑戦してみましょう。🤔", fg="red")

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


3. アプリのダウンロードと実行方法

プログラミング環境がない方でも、exeファイルを使えば簡単にアプリを試すことができます。

  • exeファイルとは?: Windowsパソコンで、ダブルクリックするだけで実行できるプログラムファイルです。Pythonをインストールしたり、特別な設定をしたりする必要はありません。
  • ダウンロードリンク:
    • ナンプレアプリ (Windows版):
  • 実行方法:
    1. 上記のリンクをクリックして、sudoku_app.exeをダウンロードします。
    2. ダウンロードしたファイルをダブルクリックして実行します。

※セキュリティ警告が出る場合がありますが、そのまま「詳細情報」→「実行」と進んでください。


4. 最後に

この記事を読んでくださり、ありがとうございます。アプリを使ってみた感想や、改善点などがあればぜひコメントで教えていただけると嬉しいです!

それでは、どうぞナンプレを楽しんでください!

タイトルとURLをコピーしました