一款经典小游戏,为没有网络的电脑添砖加瓦

一款经典小游戏,为没有网络的电脑添砖加瓦

Southerly
2023-08-03 / 2 评论 / 223 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年01月27日,已超过103天没有更新,若内容或图片失效,请留言反馈。
由于种种原因电脑不能联网,为使摸鱼更加快乐,闲暇时间写了个小游戏!
运行界面如下图:

看到界面就知道是什么了吧!

sudu.png

没错,是它!是它!就是它————数独游戏!

由于是单机电脑,环境比较单一,只有一个python2.7版本(无其它包),仅用自带的包写了一个界面,勉强能玩,大佬勿喷!

食用方式1:保存代码为.py或者.pyw即可在有环境的电脑上运行

食用方式2:下载我打包好的exe双击运行即可游玩(附文章底部)

代码如下,如有bug,请指出

# coding:utf-8
import Tkinter as tk
import tkMessageBox
import random



class SudokuGame:
    def __init__(self, root):
        self.root = root
        self.root.title("SuDuKu Game")

        self.board = [[0 for _ in range(9)] for _ in range(9)]
        self.generate_board(70)

        self.labels = [[None for _ in range(9)] for _ in range(9)]

        self.selected_cell = (0, 0)
        self.highlighted_number = None  # 存储高亮显示的数字

        self.draw_board()

        self.root.bind("<KeyPress>", self.on_key)
        self.root.bind("<Button-1>", self.on_click)
        self.root.bind("<ButtonRelease-1>", self.on_double_click)
        self.root.bind("<Button-3>", self.clear_cell)  # 绑定鼠标右键事件

        self.create_menu()

    def create_menu(self):
        menu_bar = tk.Menu(self.root)

        # 创建"游戏"菜单
        game_menu = tk.Menu(menu_bar, tearoff=0)
        game_menu.add_command(label="restart", command=lambda: self.restart_game(70))
        menu_bar.add_cascade(label="Game", menu=game_menu)

        # 创建"难度"菜单
        difficulty_menu = tk.Menu(menu_bar, tearoff=0)
        difficulty_menu.add_radiobutton(label="s", command=lambda: self.set_difficulty(60))
        difficulty_menu.add_radiobutton(label="ss", command=lambda: self.set_difficulty(50))
        difficulty_menu.add_radiobutton(label="sss", command=lambda: self.set_difficulty(40))
        menu_bar.add_cascade(label="Difficulty", menu=difficulty_menu)

        self.root.config(menu=menu_bar)

    def restart_game(self, difficulty):
        self.generate_board(difficulty)
        self.update_board()

    def set_difficulty(self, difficulty):
        self.board=[[0 for _ in range(9)] for _ in range(9)]
        self.fill_board(0, 0)
        self.remove_numbers(difficulty)
        self.generate_board(difficulty)  # 重新生成数独盘面
        self.update_board()  # 更新界面

    def generate_board(self, difficulty):
        self.board = [[0 for _ in range(9)] for _ in range(9)]
        self.fill_board(0, 0)
        self.remove_numbers(difficulty)

    def fill_board(self, row, col):
        if col == 9:
            row += 1
            col = 0
        if row == 9:
            return True

        numbers = list(range(1, 10))
        random.shuffle(numbers)

        for num in numbers:
            if self.is_valid_move(row, col, num):
                self.board[row][col] = num
                if self.fill_board(row, col + 1):
                    return True
                self.board[row][col] = 0

        return False

    def is_valid_move(self, row, col, num):
        # Check row
        for i in range(9):
            if self.board[row][i] == num:
                return False

        # Check column
        for i in range(9):
            if self.board[i][col] == num:
                return False

        # Check 3x3 grid
        start_row = (row // 3) * 3
        start_col = (col // 3) * 3
        for i in range(start_row, start_row + 3):
            for j in range(start_col, start_col + 3):
                if self.board[i][j] == num:
                    return False

        return True

    def remove_numbers(self, difficulty):
        count = 81 - difficulty
        attempts = 0
        while count > 0:
            row = random.randint(0, 8)
            col = random.randint(0, 8)
            if self.board[row][col] != 0:
                self.board[row][col] = 0
                count -= 1
            attempts += 1
            if attempts >= 100:  # 如果尝试次数超过100次,则跳出循环
                break
        if count < 0:
            tkMessageBox.showinfo("tips", "Setting failed,please try again!!")

    def draw_board(self):
        for i in range(9):
            for j in range(9):
                number = self.board[i][j]
                if number == 0:
                    text = ''
                else:
                    text = str(number)

                label = tk.Label(self.root, text=text, font=("Arial", 16), width=2, relief=tk.SOLID)
                label.grid(row=i, column=j)
                self.labels[i][j] = label

                # 绑定鼠标双击事件
                label.bind("<Double-Button-1>", lambda event, num=number: self.highlight_number(num))

                # 判断是否需要高亮显示该数字
                if number == self.highlighted_number:
                    label.config(bg='yellow')

    def update_board(self):
        for i in range(9):
            for j in range(9):
                number = self.board[i][j]
                label = self.labels[i][j]
                if number == 0:
                    text = ''
                else:
                    text = str(number)

                # 判断是否需要高亮显示该数字
                if number == self.highlighted_number:
                    label.config(bg='yellow')
                else:
                    label.config(bg='white')

                label.config(text=text)

    def on_key(self, event):
        if event.char.isdigit() and 1 <= int(event.char) <= 9:
            num = int(event.char)
            row, col = self.selected_cell

            self.board[row][col] = num
            self.update_board()
            self.check_win()

    def select_cell(self, row, col):
        self.selected_cell = (row, col)
        num = self.board[row][col]
        for i in range(9):
            for j in range(9):
                label = self.labels[i][j]
                if (i, j) == (row, col):
                    label.config(bg='yellow')
                else:
                    label.config(bg='white')

                if num == self.highlighted_number:
                    if (i, j) == (row, col):
                        label.config(bg='yellow')
                    else:
                        label.config(bg='white')
                else:
                    if (i, j) == (row, col):
                        label.config(bg='yellow')
                    elif self.board[i][j] == self.highlighted_number:
                        label.config(bg='yellow')
                    else:
                        label.config(bg='white')

    def on_click(self, event):
        x, y = self.root.winfo_pointerxy()
        widget = self.root.winfo_containing(x, y)
        for i in range(9):
            for j in range(9):
                if widget == self.labels[i][j]:
                    self.select_cell(i, j)

    def on_double_click(self, event):
        x, y = self.root.winfo_pointerxy()
        widget = self.root.winfo_containing(x, y)
        for i in range(9):
            for j in range(9):
                if widget == self.labels[i][j]:
                    self.highlight_number(self.board[i][j])

    def clear_cell(self, event):
        row, col = self.selected_cell
        self.board[row][col] = 0
        self.update_board()
        self.check_win()

    def highlight_number(self, num):
        if self.highlighted_number is None:
            self.highlighted_number = num
        else:
            self.highlighted_number = None

        self.update_board()

    def check_win(self):
        for i in range(9):
            for j in range(9):
                if self.board[i][j] == 0:
                    return False
        tkMessageBox.showinfo("tips", "Win!")


if __name__ == "__main__":
    root = tk.Tk()
    game = SudokuGame(root)
    root.mainloop()

本文共 252 个字数,平均阅读时长 ≈ 1分钟
1

海报

打赏

评论 (2)

语录
取消
  1. 头像
    椰子
    Android · UC Browser 陕西省

    33

    回复 删除 垃圾
  2. 头像
    Southerly 超V 作者
    Android · UC Browser 陕西省

    欢迎大佬指点!

    回复 删除 垃圾