由于种种原因电脑不能联网,为使摸鱼更加快乐,闲暇时间写了个小游戏!
运行界面如下图:
看到界面就知道是什么了吧!
没错,是它!是它!就是它————数独游戏!
由于是单机电脑,环境比较单一,只有一个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分钟
33
欢迎大佬指点!