关灯游戏及扩展


7.8    图形界面应用案例——关灯游戏

题目:

[案例]游戏初步——关灯游戏。    

关灯游戏是很有意思的益智游戏,玩家通过单击关掉(或打开)一盏灯。如果关(掉(或打开)一个电灯,其周围(上下左右)的电灯也会触及开关,成功地关掉所有电灯即可过关。


图7-43 关灯游戏运行效果
分析:游戏中采用二维列表存储灯的状态,'you'表示电灯亮(黄色的圆),'wu'表示电灯关掉(背景色的圆)。在Canvas画布单击事件中,获取鼠标单击位置从而换算成棋盘位(x1,y1),并处理四周灯的状态转换。
案例代码:

from tkinter import *
from tkinter import messagebox
root = Tk()
l= [['wu', 'wu', 'you', 'you', 'you'] ,['wu', 'you', 'wu', 'wu', 'wu'],['wu', 'wu', 'wu', 'wu', 'wu'],['wu', 'wu', 'wu', 'you', 'wu'],['you', 'you', 'you', 'wu', 'wu']]
#绘制灯的状态情况图
def huaqi():for i in range (0,5):for u in range (0,5):if l[i][u]=='you':cv.create_oval(i * 40 + 10,u * 40 + 10,(i+1)* 40+10,(u+1)*40 + 10,outline='white', fill='yellow', width=2)#亮灯else:cv.create_oval(i*40 + 10,u*40 +10,(i+1) *40+10,(u+1)*40 + 10,outline='white', fill='white', width=2)	#灭灯
#反转(x1,yl)处灯的状态
def reserve(x1,y1):if l[x1][y1] =='wu':l[x1][y1]='you'else:l[x1][y1] = 'wu'
#单击事件函数
def luozi(event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 !=0:reserve(x1 - 1, y1)# 右侧灯的状态反转if x1!=4:reserve(x1 + 1, y1)# 上侧灯的状态反转if y1!=0:reserve(x1, y1 - 1)# 下侧灯的状态反转if y1!=4:reserve(x1, y1 + 1)huaqi()
# 主程序
cv = Canvas(root, bg='white', width=210, height=210)
for i in range(0, 6):  # 绘制网格线cv.create_line(10, 10 + 1 * 40,210, 10 + i * 40, arrow = 'none')cv.create_line(10 + i * 40,10,10 + 1 * 40, 210, arrow = 'none' )
huaqi()  # 绘制灯的状态情况图
p = 0
for i in range(0, 5):for u in l[i]:if u == 'wu':p= p + 1
if p == 25:messagebox.showinfo('win', '你过关了')  # 显示赢信息的消息窗口
cv.bind('<Button-1>', luozi)
cv.pack()
root.mainloop ()

这段代码是一个基于Tkinter库的灯泡游戏。游戏界面是一个5x5的网格,每个网格代表一个灯泡。初始状态下,所有的灯泡都是灭的(白色)。玩家的目标是通过点击灯泡,将所有的灯泡都点亮(黄色)。

代码中的主要函数和操作包括:

1. `huaqi()`函数:根据灯泡的状态情况,绘制灯泡的图形。如果灯泡是亮的,则绘制一个黄色的圆形;如果灯泡是灭的,则绘制一个白色的圆形。

2. `reserve(x1, y1)`函数:根据给定的坐标`(x1, y1)`,反转该位置的灯泡的状态。如果灯泡是亮的,则变为灭的;如果灯泡是灭的,则变为亮的。

3. `luozi(event)`函数:处理鼠标点击事件。根据点击的位置,确定对应的灯泡,并进行状态反转。同时,还会反转该灯泡周围的灯泡状态。

4. 主程序部分:创建一个画布(Canvas)对象,并设置背景色为白色。然后,使用循环绘制网格线。接着,调用`huaqi()`函数绘制灯泡的初始状态。最后,绑定鼠标左键点击事件到`luozi()`函数,并将画布显示在窗口中。

在游戏过程中,玩家通过点击灯泡来改变它的状态,并且反转周围灯泡的状态。当所有的灯泡都点亮时,会弹出一个消息窗口显示玩家胜利的信息。

注(Tkinter库):

Tkinter是Python的标准图形用户界面(GUI)工具包,它提供了创建和管理GUI应用程序所需的组件和功能。Tkinter是基于Tcl/Tk工具包的Python接口,Tcl是一种脚本语言,而Tk是一个用于创建图形用户界面的工具包。

Tkinter库包含了许多常用的GUI组件,比如按钮、标签、文本框、复选框、单选按钮、菜单等,同时也支持布局管理器来帮助开发者设计和布局界面。开发者可以使用Tkinter来创建各种类型的应用程序,从简单的工具到复杂的桌面应用程序都可以使用Tkinter来实现。

Tkinter的优点包括:

1. **易于学习和使用**:Tkinter是Python的标准库,因此无需额外安装即可使用。它的接口简单直观,适合初学者入门。

2. **跨平台性**:Tkinter可以在多个平台上运行,包括Windows、Linux和Mac OS等。

3. **丰富的组件**:Tkinter提供了丰富的GUI组件,可以满足大部分应用程序的需求。

4. **灵活性**:Tkinter支持自定义组件和样式,开发者可以根据自己的需求进行定制。

总之,Tkinter是一个功能强大且易于使用的GUI工具包,适合用于开发Python图形界面应用程序。

扩展题目:

题目要求:

请完成《7.8关灯游戏》(课本p.170),并完成以下扩展内容:

扩展内容:

1. 请设计并实现界面功能,允许玩家选择初始地图的大小,分别为:小(5x5),中(8x8),大(12x10),玩家选择之后立即刷新窗口界面并重设地图

2. 请设计并实现界面功能,允许玩家选择游戏难度,分别为:

容易:一开始有20%的格子状态为翻转状态

中等:一开始有40%的格子状态为翻转状态

困难:一开始有60%的格子状态为翻转状态

3. 游戏开始之前,提示玩家输入唯一的用户名,用于保留该玩家的闯关记录

4. 按照玩家选择的地图大小和难度开始游戏,游戏过程中记录玩家闯关的总时间以及翻转次数(即开关灯的次数)

5. 玩家通关成功后,保存相关信息到数据库,表结构可以自定,但应当至少包含以下信息:

 - 玩家选择的地图大小

 - 玩家选择的难度

 - 玩家通关的日期时间

 - 玩家通关所用的总时间

 - 玩家通关所用的总点击次数

6. 设计窗口界面,显示通关排行榜,具体说明如下:

 - 根据不同地图大小以及不同难度显示各自排名,例如:大地图中等难度与中地图困难难度的排名是分开的

 - 可以选择显示总排名(所有玩家的记录)与个人排名(玩家自己的所有记录)

 - 可以选择根据通关时间排名,以及根据点击次数排名,两个排名都是按从小到大排列

扩展完第一个功能的代码

(1. 请设计并实现界面功能,允许玩家选择初始地图的大小,分别为:小(5x5),中(8x8),大(12x10),玩家选择之后立即刷新窗口界面并重设地图):

from tkinter import *
from tkinter import messagebox
import randomclass LightsOutGame:def __init__(self, master=None, size=5):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.create_widgets()self.random_open_lights()  # 随机打开一些灯def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size*40+10, height=self.size*40+10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size+1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()def random_open_lights(self):num_of_lights = random.randint(1, self.size*self.size)  # 随机选择要打开的灯的数量positions = random.sample(range(self.size*self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def reset_game(size):game.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size*40+10, height=size*40+10)game.draw_grid()game.random_open_lights()game.huaqi()def on_small():reset_game(5)def on_medium():reset_game(8)def on_large():reset_game(12)root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)root.mainloop()

扩展完功能二的代码:

请设计并实现界面功能,允许玩家选择游戏难度,分别为:

容易:一开始有20%的格子状态为翻转状态

中等:一开始有40%的格子状态为翻转状态

困难:一开始有60%的格子状态为翻转状态

from tkinter import *
from tkinter import messagebox
import randomclass LightsOutGame:def __init__(self, master=None, size=5, difficulty='medium'):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.create_widgets()self.random_open_lights(difficulty)  # 随机打开一些灯def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size*40+10, height=self.size*40+10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size+1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()def random_open_lights(self, difficulty):if difficulty == 'easy':num_of_lights = int(self.size * self.size * 0.2)  # 20%的格子状态为翻转状态elif difficulty == 'medium':num_of_lights = int(self.size * self.size * 0.4)  # 40%的格子状态为翻转状态elif difficulty == 'hard':num_of_lights = int(self.size * self.size * 0.6)  # 60%的格子状态为翻转状态positions = random.sample(range(self.size*self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def reset_game(size, difficulty):game.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size*40+10, height=size*40+10)game.draw_grid()game.random_open_lights(difficulty)game.huaqi()def on_small():reset_game(5, difficulty_var.get())def on_medium():reset_game(8, difficulty_var.get())def on_large():reset_game(12, difficulty_var.get())root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()difficulty_var = StringVar()
difficulty_var.set('medium')small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)difficulty_frame = Frame(root)
difficulty_frame.pack()easy_radio = Radiobutton(difficulty_frame, text="容易", variable=difficulty_var, value='easy')
easy_radio.pack(side=LEFT)medium_radio = Radiobutton(difficulty_frame, text="中等", variable=difficulty_var, value='medium')
medium_radio.pack(side=LEFT)hard_radio = Radiobutton(difficulty_frame, text="困难", variable=difficulty_var, value='hard')
hard_radio.pack(side=LEFT)root.mainloop()

扩展完功能三的代码:

3. 游戏开始之前,提示玩家输入唯一的用户名,用于保留该玩家的闯关记录

from tkinter import *
from tkinter import messagebox
import randomclass LightsOutGame:def __init__(self, master=None, size=5, difficulty='medium'):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.username = None  # 存储玩家的用户名self.create_widgets()self.random_open_lights(difficulty)  # 随机打开一些灯def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size*40+10, height=self.size*40+10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)self.username_label = Label(self.master, text="用户名:")self.username_label.pack()self.username_entry = Entry(self.master)self.username_entry.pack()self.username_button = Button(self.master, text="确认", command=self.set_username)self.username_button.pack()def set_username(self):self.username = self.username_entry.get()self.username_label.config(text="用户名:" + self.username)# 移除用户名输入框和确认按钮self.username_entry.pack_forget()self.username_button.pack_forget()def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size+1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()def random_open_lights(self, difficulty):if difficulty == 'easy':num_of_lights = int(self.size * self.size * 0.2)  # 20%的格子状态为翻转状态elif difficulty == 'medium':num_of_lights = int(self.size * self.size * 0.4)  # 40%的格子状态为翻转状态elif difficulty == 'hard':num_of_lights = int(self.size * self.size * 0.6)  # 60%的格子状态为翻转状态positions = random.sample(range(self.size*self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def reset_game(size, difficulty, username):game.username = usernamegame.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size*40+10, height=size*40+10)game.draw_grid()game.random_open_lights(difficulty)game.huaqi()def on_small():reset_game(5, difficulty_var.get(), game.username)def on_medium():reset_game(8, difficulty_var.get(), game.username)def on_large():reset_game(12, difficulty_var.get(), game.username)root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()difficulty_var = StringVar()
difficulty_var.set('medium')small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)difficulty_frame = Frame(root)
difficulty_frame.pack()easy_radio = Radiobutton(difficulty_frame, text="容易", variable=difficulty_var, value='easy')
easy_radio.pack(side=LEFT)medium_radio = Radiobutton(difficulty_frame, text="中等", variable=difficulty_var, value='medium')
medium_radio.pack(side=LEFT)hard_radio = Radiobutton(difficulty_frame, text="困难", variable=difficulty_var, value='hard')
hard_radio.pack(side=LEFT)root.mainloop()

扩展完功能四的代码:

按照玩家选择的地图大小和难度开始游戏,游戏过程中记录玩家闯关的总时间以及翻转次数(即开关灯的次数)

from tkinter import *
from tkinter import messagebox
import random
import timeclass LightsOutGame:def __init__(self, master=None, size=5, difficulty='medium'):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.username = None  # 存储玩家的用户名self.create_widgets()self.random_open_lights(difficulty)  # 随机打开一些灯self.total_time = 0self.flip_count = 0self.start_time = 0def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size*40+10, height=self.size*40+10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)self.username_label = Label(self.master, text="用户名:")self.username_label.pack()self.username_entry = Entry(self.master)self.username_entry.pack()self.username_button = Button(self.master, text="确认", command=self.set_username)self.username_button.pack()def set_username(self):self.username = self.username_entry.get()self.username_label.config(text="用户名:" + self.username)# 移除用户名输入框和确认按钮self.username_entry.pack_forget()self.username_button.pack_forget()def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size+1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()self.flip_count += 1def random_open_lights(self, difficulty):if difficulty == 'easy':num_of_lights = int(self.size * self.size * 0.2)  # 20%的格子状态为翻转状态elif difficulty == 'medium':num_of_lights = int(self.size * self.size * 0.4)  # 40%的格子状态为翻转状态elif difficulty == 'hard':num_of_lights = int(self.size * self.size * 0.6)  # 60%的格子状态为翻转状态positions = random.sample(range(self.size*self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def reset_game(size, difficulty, username):game.username = usernamegame.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size*40+10, height=size*40+10)game.draw_grid()game.random_open_lights(difficulty)game.huaqi()game.total_time = 0game.flip_count = 0game.start_time = 0def on_small():reset_game(5, difficulty_var.get(), game.username)def on_medium():reset_game(8, difficulty_var.get(), game.username)def on_large():reset_game(12, difficulty_var.get(), game.username)root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()difficulty_var = StringVar()
difficulty_var.set('medium')small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)difficulty_frame = Frame(root)
difficulty_frame.pack()easy_radio = Radiobutton(difficulty_frame, text="容易", variable=difficulty_var, value='easy')
easy_radio.pack(side=LEFT)medium_radio = Radiobutton(difficulty_frame, text="中等", variable=difficulty_var, value='medium')
medium_radio.pack(side=LEFT)hard_radio = Radiobutton(difficulty_frame, text="困难", variable=difficulty_var, value='hard')
hard_radio.pack(side=LEFT)root.mainloop()

扩展完功能五的代码:

 玩家通关成功后,保存相关信息到数据库,表结构可以自定,但应当至少包含以下信息:

 - 玩家选择的地图大小

 - 玩家选择的难度

 - 玩家通关的日期时间

 - 玩家通关所用的总时间

 - 玩家通关所用的总点击次数

import sqlite3
from tkinter import *
from tkinter import messagebox
import random
from datetime import datetimeclass LightsOutGame:def __init__(self, master=None, size=5, difficulty='medium'):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.username = None  # 存储玩家的用户名self.create_widgets()self.random_open_lights(difficulty)  # 随机打开一些灯self.total_time = 0self.flip_count = 0self.start_time = 0# 连接到数据库self.conn = sqlite3.connect('game.db')self.cursor = self.conn.cursor()# 创建表self.cursor.execute('''CREATE TABLE IF NOT EXISTS game_records (id INTEGER PRIMARY KEY AUTOINCREMENT,map_size INTEGER,difficulty TEXT,completion_time DATETIME,total_clicks INTEGER)''')def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size*40+10, height=self.size*40+10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)self.username_label = Label(self.master, text="用户名:")self.username_label.pack()self.username_entry = Entry(self.master)self.username_entry.pack()self.username_button = Button(self.master, text="确认", command=self.set_username)self.username_button.pack()def set_username(self):self.username = self.username_entry.get()self.username_label.config(text="用户名:" + self.username)# 移除用户名输入框和确认按钮self.username_entry.pack_forget()self.username_button.pack_forget()def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size+1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()self.flip_count += 1def random_open_lights(self, difficulty):if difficulty == 'easy':num_of_lights = int(self.size * self.size * 0.2)  # 20%的格子状态为翻转状态elif difficulty == 'medium':num_of_lights = int(self.size * self.size * 0.4)  # 40%的格子状态为翻转状态elif difficulty == 'hard':num_of_lights = int(self.size * self.size * 0.6)  # 60%的格子状态为翻转状态positions = random.sample(range(self.size*self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def save_game_record(self):# 保存通关信息到数据库map_size = self.sizedifficulty = difficulty_var.get()completion_time = datetime.now()total_clicks = self.flip_countself.cursor.execute('''INSERT INTO game_records (map_size, difficulty, completion_time, total_clicks)VALUES (?, ?, ?, ?)''', (map_size, difficulty, completion_time, total_clicks))self.conn.commit()def reset_game(size, difficulty, username):game.username = usernamegame.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size*40+10, height=size*40+10)game.draw_grid()game.random_open_lights(difficulty)game.huaqi()game.total_time = 0game.flip_count = 0game.start_time = 0def on_small():reset_game(5, difficulty_var.get(), game.username)def on_medium():reset_game(8, difficulty_var.get(), game.username)def on_large():reset_game(12, difficulty_var.get(), game.username)root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()difficulty_var = StringVar()
difficulty_var.set('medium')small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)difficulty_frame = Frame(root)
difficulty_frame.pack()easy_radio = Radiobutton(difficulty_frame, text="容易", variable=difficulty_var, value='easy')
easy_radio.pack(side=LEFT)medium_radio = Radiobutton(difficulty_frame, text="中等", variable=difficulty_var, value='medium')
medium_radio.pack(side=LEFT)hard_radio = Radiobutton(difficulty_frame, text="困难", variable=difficulty_var, value='hard')
hard_radio.pack(side=LEFT)save_button = Button(root, text="保存通关信息", command=game.save_game_record)
save_button.pack()root.mainloop()# 关闭数据库连接
game.conn.close()

扩展完功能六的代码:

设计窗口界面,显示通关排行榜,具体说明如下:

 - 根据不同地图大小以及不同难度显示各自排名,例如:大地图中等难度与中地图困难难度的排名是分开的

 - 可以选择显示总排名(所有玩家的记录)与个人排名(玩家自己的所有记录)

 - 可以选择根据通关时间排名,以及根据点击次数排名,两个排名都是按从小到大排列

import sqlite3
from tkinter import *
from tkinter import messagebox
import random
from datetime import datetimeclass LightsOutGame:def __init__(self, master=None, size=5, difficulty='medium'):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.username = None  # 存储玩家的用户名self.create_widgets()self.random_open_lights(difficulty)  # 随机打开一些灯self.total_time = 0self.flip_count = 0self.start_time = 0# 连接到数据库self.conn = sqlite3.connect('game.db')self.cursor = self.conn.cursor()# 创建表self.cursor.execute('''CREATE TABLE IF NOT EXISTS game_records (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT,map_size INTEGER,difficulty TEXT,completion_time DATETIME,total_clicks INTEGER)''')def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size * 40 + 10, height=self.size * 40 + 10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)self.username_label = Label(self.master, text="用户名:")self.username_label.pack()self.username_entry = Entry(self.master)self.username_entry.pack()self.username_button = Button(self.master, text="确认", command=self.set_username)self.username_button.pack()self.show_leaderboard_button = Button(self.master, text="显示排行榜", command=self.show_leaderboard)self.show_leaderboard_button.pack()def set_username(self):self.username = self.username_entry.get()self.username_label.config(text="用户名:" + self.username)# 移除用户名输入框和确认按钮self.username_entry.pack_forget()self.username_button.pack_forget()def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size + 1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()self.flip_count += 1def random_open_lights(self, difficulty):if difficulty == 'easy':num_of_lights = int(self.size * self.size * 0.2)  # 20%的格子状态为翻转状态elif difficulty == 'medium':num_of_lights = int(self.size * self.size * 0.4)  # 40%的格子状态为翻转状态elif difficulty == 'hard':num_of_lights = int(self.size * self.size * 0.6)  # 60%的格子状态为翻转状态positions = random.sample(range(self.size * self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def save_game_record(self):# 保存通关信息到数据库map_size = self.sizedifficulty = difficulty_var.get()completion_time = datetime.now()total_clicks = self.flip_countself.cursor.execute('''INSERT INTO game_records (username, map_size, difficulty, completion_time, total_clicks)VALUES (?, ?, ?, ?, ?)''', (self.username, map_size, difficulty, completion_time, total_clicks))self.conn.commit()  # 确保数据被写入数据库def show_leaderboard(self):leaderboard_window = Toplevel(self.master)leaderboard_window.title("通关排行榜")leaderboard_frame = Frame(leaderboard_window)leaderboard_frame.pack()map_size = self.sizedifficulty = difficulty_var.get()self.cursor.execute('''SELECT username, completion_time, total_clicks FROM game_recordsWHERE map_size=? AND difficulty=?ORDER BY completion_time, total_clicks''', (map_size, difficulty))records = self.cursor.fetchall()if len(records) == 0:messagebox.showinfo("提示", "暂无记录")else:for i, record in enumerate(records):username_label = Label(leaderboard_frame, text=record[0])username_label.grid(row=i, column=0)completion_time_label = Label(leaderboard_frame, text=record[1])completion_time_label.grid(row=i, column=1)total_clicks_label = Label(leaderboard_frame, text=record[2])total_clicks_label.grid(row=i, column=2)def reset_game(size, difficulty, username):game.username = usernamegame.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size * 40 + 10, height=size * 40 + 10)game.draw_grid()game.random_open_lights(difficulty)game.huaqi()game.total_time = 0game.flip_count = 0game.start_time = 0def on_small():reset_game(5, difficulty_var.get(), game.username)def on_medium():reset_game(8, difficulty_var.get(), game.username)def on_large():reset_game(12, difficulty_var.get(), game.username)root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()difficulty_var = StringVar()
difficulty_var.set('medium')small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)difficulty_frame = Frame(root)
difficulty_frame.pack()easy_radio = Radiobutton(difficulty_frame, text="容易", variable=difficulty_var, value='easy')
easy_radio.pack(side=LEFT)medium_radio = Radiobutton(difficulty_frame, text="中等", variable=difficulty_var, value='medium')
medium_radio.pack(side=LEFT)hard_radio = Radiobutton(difficulty_frame, text="困难", variable=difficulty_var, value='hard')
hard_radio.pack(side=LEFT)save_button = Button(root, text="保存通关信息", command=game.save_game_record)
save_button.pack()root.mainloop()# 关闭数据库连接
game.conn.close()

扩展添加了一个查询次数和时间的代码(最终):

import sqlite3
from tkinter import *
from tkinter import messagebox
import random
from datetime import datetimeclass LightsOutGame:def __init__(self, master=None, size=5, difficulty='medium'):self.master = masterself.size = sizeself.lights = [['wu' for _ in range(size)] for _ in range(size)]self.username = None  # 存储玩家的用户名self.create_widgets()self.random_open_lights(difficulty)  # 随机打开一些灯self.total_time = 0self.flip_count = 0self.start_time = 0# 连接到数据库self.conn = sqlite3.connect('game.db')self.cursor = self.conn.cursor()# 创建表self.cursor.execute('''CREATE TABLE IF NOT EXISTS game_records (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT,map_size INTEGER,difficulty TEXT,completion_time DATETIME,total_clicks INTEGER)''')def create_widgets(self):self.cv = Canvas(self.master, bg='white', width=self.size * 40 + 10, height=self.size * 40 + 10)self.cv.pack()self.draw_grid()  # 绘制网格self.huaqi()  # 绘制灯的状态情况图self.cv.bind('<Button-1>', self.luozi)self.username_label = Label(self.master, text="用户名:")self.username_label.pack()self.username_entry = Entry(self.master)self.username_entry.pack()self.username_button = Button(self.master, text="确认", command=self.set_username)self.username_button.pack()self.show_leaderboard_button = Button(self.master, text="显示排行榜", command=self.show_leaderboard)self.show_leaderboard_button.pack()self.stats_button = Button(self.master, text="查询统计", command=self.show_game_stats)self.stats_button.pack()self.stats_label = Label(self.master, text="")self.stats_label.pack()def set_username(self):self.username = self.username_entry.get()self.username_label.config(text="用户名:" + self.username)# 移除用户名输入框和确认按钮self.username_entry.pack_forget()self.username_button.pack_forget()def draw_grid(self):self.cv.delete("grid")  # 清除之前的网格for i in range(self.size + 1):  # 绘制网格线self.cv.create_line(10, 10 + i * 40, 10 + self.size * 40, 10 + i * 40, arrow='none', tags="grid")self.cv.create_line(10 + i * 40, 10, 10 + i * 40, 10 + self.size * 40, arrow='none', tags="grid")def huaqi(self):self.cv.delete("lights")  # 清除之前的灯for i in range(self.size):for u in range(self.size):if self.lights[i][u] == 'you':self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='yellow', width=2, tags="lights")  # 亮灯else:self.cv.create_oval(i * 40 + 10, u * 40 + 10, (i + 1) * 40 + 10, (u + 1) * 40 + 10,outline='white', fill='white', width=2, tags="lights")  # 灭灯def reserve(self, x1, y1):if self.lights[x1][y1] == 'wu':self.lights[x1][y1] = 'you'else:self.lights[x1][y1] = 'wu'def luozi(self, event):x1 = (event.x - 10) // 40y1 = (event.y - 10) // 40print(x1, y1)self.reserve(x1, y1)  # 翻转(x1,y1)处灯的状态# 以下翻转(x1,yI)周围的灯的状态#左侧灯的状态反转if x1 != 0:self.reserve(x1 - 1, y1)# 右侧灯的状态反转if x1 != self.size - 1:self.reserve(x1 + 1, y1)# 上侧灯的状态反转if y1 != 0:self.reserve(x1, y1 - 1)# 下侧灯的状态反转if y1 != self.size - 1:self.reserve(x1, y1 + 1)self.huaqi()self.flip_count += 1def random_open_lights(self, difficulty):if difficulty == 'easy':num_of_lights = int(self.size * self.size * 0.2)  # 20%的格子状态为翻转状态elif difficulty == 'medium':num_of_lights = int(self.size * self.size * 0.4)  # 40%的格子状态为翻转状态elif difficulty == 'hard':num_of_lights = int(self.size * self.size * 0.6)  # 60%的格子状态为翻转状态positions = random.sample(range(self.size * self.size), num_of_lights)  # 随机选择要打开的灯的位置for pos in positions:x = pos // self.sizey = pos % self.sizeself.reserve(x, y)def save_game_record(self):# 保存通关信息到数据库map_size = self.sizedifficulty = difficulty_var.get()completion_time = datetime.now()total_clicks = self.flip_countself.cursor.execute('''INSERT INTO game_records (username, map_size, difficulty, completion_time, total_clicks)VALUES (?, ?, ?, ?, ?)''', (self.username, map_size, difficulty, completion_time, total_clicks))self.conn.commit()  # 确保数据被写入数据库def show_leaderboard(self):leaderboard_window = Toplevel(self.master)leaderboard_window.title("通关排行榜")leaderboard_frame = Frame(leaderboard_window)leaderboard_frame.pack()map_size = self.sizedifficulty = difficulty_var.get()self.cursor.execute('''SELECT username, completion_time, total_clicks FROM game_recordsWHERE map_size=? AND difficulty=?ORDER BY completion_time, total_clicks''', (map_size, difficulty))records = self.cursor.fetchall()if len(records) == 0:messagebox.showinfo("提示", "暂无记录")else:for i, record in enumerate(records):username_label = Label(leaderboard_frame, text=record[0])username_label.grid(row=i, column=0)completion_time_label = Label(leaderboard_frame, text=record[1])completion_time_label.grid(row=i, column=1)total_clicks_label = Label(leaderboard_frame, text=record[2])total_clicks_label.grid(row=i, column=2)def get_game_stats(self):self.cursor.execute('''SELECT SUM(completion_time), SUM(total_clicks) FROM game_recordsWHERE username=?''', (self.username,))result = self.cursor.fetchone()return resultdef show_game_stats(self):stats = self.get_game_stats()total_time = stats[0]total_clicks = stats[1]self.stats_label.config(text=f"总时间:{total_time} 秒,翻转次数:{total_clicks} 次")def reset_game(size, difficulty, username):game.username = usernamegame.size = sizegame.lights = [['wu' for _ in range(size)] for _ in range(size)]game.cv.config(width=size * 40 + 10, height=size * 40 + 10)game.draw_grid()game.random_open_lights(difficulty)game.huaqi()game.total_time = 0game.flip_count = 0game.start_time = 0game.stats_label.config(text="")def on_small():reset_game(5, difficulty_var.get(), game.username)def on_medium():reset_game(8, difficulty_var.get(), game.username)def on_large():reset_game(12, difficulty_var.get(), game.username)root = Tk()
game = LightsOutGame(root)menu_frame = Frame(root)
menu_frame.pack()difficulty_var = StringVar()
difficulty_var.set('medium')small_button = Button(menu_frame, text="小", command=on_small)
small_button.pack(side=LEFT)medium_button = Button(menu_frame, text="中", command=on_medium)
medium_button.pack(side=LEFT)large_button = Button(menu_frame, text="大", command=on_large)
large_button.pack(side=LEFT)difficulty_frame = Frame(root)
difficulty_frame.pack()easy_radio = Radiobutton(difficulty_frame, text="容易", variable=difficulty_var, value='easy')
easy_radio.pack(side=LEFT)medium_radio = Radiobutton(difficulty_frame, text="中等", variable=difficulty_var, value='medium')
medium_radio.pack(side=LEFT)hard_radio = Radiobutton(difficulty_frame, text="困难", variable=difficulty_var, value='hard')
hard_radio.pack(side=LEFT)save_button = Button(root, text="保存通关信息", command=game.save_game_record)
save_button.pack()root.mainloop()# 关闭数据库连接
game.conn.close()

相关问题:

  1. 请描述你的系统详细设计(提示:按照需求分析列出概要功能点)

答:系统详细设计:

创建一个名为LightsOutGame的类,用于实现Lights Out游戏的逻辑和界面。

在初始化方法中,设置游戏的大小、难度,并创建一个二维数组来表示灯的状态。

创建游戏界面,包括一个Canvas用于绘制网格和灯的状态,一个Label用于显示用户名,一个Entry和一个Button用于输入和确认用户名,以及一些按钮用于选择游戏难度和操作。

实现灯的状态翻转和绘制网格、灯的方法。

实现随机打开一些灯的方法,根据难度设置打开的灯的数量。

实现保存通关记录到数据库的方法,包括用户名、地图大小、难度、完成时间和翻转次数。

实现显示排行榜和查询统计的方法,从数据库中获取相应的记录并展示在界面上。

实现重置游戏的方法,根据选择的地图大小和难度重新设置游戏参数,并清空灯的状态和统计数据。

创建一个主窗口,并将游戏对象放入其中,启动主循环。

  1. 请通过原型图+说明的方式展示你的界面详细设计

答:

界面详细设计:

主界面包括一个Canvas用于绘制网格和灯的状态,一个Label用于显示用户名,一个Entry和一个Button用于输入和确认用户名,以及一些按钮用于选择游戏难度和操作。

用户名输入框和确认按钮位于顶部,用于输入和确认用户名。

网格和灯的状态绘制在Canvas上,根据灯的状态绘制不同的颜色和形状。

游戏难度选择按钮位于中间,用于选择不同的难度。

排行榜和查询统计按钮位于底部,用于显示排行榜和查询统计信息。

  1. 请通过ER图+表结构说明的方式展示你的数据库详细设计

答:

数据库详细设计:

创建一个名为game_records的表,用于存储通关记录。

表中包含以下字段:id(主键,自增),username(用户名),map_size(地图大小),difficulty(难度),completion_time(完成时间),total_clicks(翻转次数)。

使用SQLite数据库,通过Python的sqlite3模块连接和操作数据库。

在游戏开始时创建表,如果表已存在则不创建。

在保存通关记录时,将相关信息插入到game_records表中。

在显示排行榜和查询统计时,从game_records表中查询相应的记录,并按照完成时间和翻转次数排序。

  1. 请按功能点顺序(1-6)依次展示你的程序运行截图:

答:功能1:

功能2:

功能3:

功能4:

功能5:

功能6:

  1. 请讨论说明图形界面设计(GUI)包括哪些重要组成部分?

答:图形界面设计(GUI)的重要组成部分包括:

窗口:用于承载界面的容器,提供标题栏、边框和关闭按钮等功能。

组件:用于构建界面的可视化元素,如按钮、标签、文本框、下拉框等。

布局管理器:用于控制组件在窗口中的位置和大小,如pack、grid和place等。

事件处理:用于响应用户的操作,如点击按钮、输入文本等,触发相应的事件处理函数。

图形绘制:用于绘制图形元素,如绘制网格、绘制灯的状态等。

2、请讨论说明在本实验中,你应如何使用数据库支撑整个应用程序的正确运行?

答:在本实验中,数据库用于支持整个应用程序的正确运行,具体包括:

创建数据库表game_records用于存储游戏记录。

在游戏通关时,将通关信息插入到game_records表中。

在显示排行榜时,从game_records表中查询对应难度和地图大小的游戏记录,并在界面上显示。

3、其他关于完成本次实验作业中的心得与讨论

答:本次实验是一个简单的游戏的实现,通过使用Tkinter库构建了一个图形界面,并使用SQLite数据库存储游戏记录。通过这个实验,我学习到了如何使用Tkinter库创建图形界面,以及如何使用SQLite数据库进行数据存储和查询。同时,我也了解到了图形界面设计的重要组成部分和数据库的应用场景。这个实验对于我进一步掌握Python编程和图形界面开发有很大的帮助,也提升了我的数据库操作能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/137978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSON可视化管理工具JSON Hero

本文软件由网友 zxc 推荐&#xff1b; 什么是 JSON Hero &#xff1f; JSON Hero 是一个简单实用的 JSON 工具&#xff0c;通过简介美观的 UI 及增强的额外功能&#xff0c;使得阅读和理解 JSON 文档变得更容易、直观。 主要功能 支持多种视图以便查看 JSON&#xff1a;列视图…

css:clip元素裁剪实现Loading加载效果边框

clip 属性定义了元素的哪一部分是可见的。clip 属性只适用于 position:absolute 的元素。 警告&#xff1a; 这个属性已被废弃。建议使用 clip-path 文档 https://developer.mozilla.org/zh-CN/docs/Web/CSS/cliphttps://developer.mozilla.org/zh-CN/docs/Web/CSS/clip-path …

Linux安装MySQL8.0服务

Linux安装MySQL8.0服务 文章目录 Linux安装MySQL8.0服务一、卸载1.1 查看mariadb1.2 卸载 二、安装2.1 下载2.2 上传2.3 解压2.4 重命名2.5 删除2.6 创建目录2.7 环境变量2.8 修改配置2.9 配置文件2.9 用户与用户组2.10 初始化2.11 其它 三、开启远程连接MySQL 一、卸载 首先第…

【数据结构】树与二叉树(八):二叉树的中序遍历(非递归算法NIO)

文章目录 5.2.1 二叉树二叉树性质引理5.1&#xff1a;二叉树中层数为i的结点至多有 2 i 2^i 2i个&#xff0c;其中 i ≥ 0 i \geq 0 i≥0。引理5.2&#xff1a;高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点&#xff0c;其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…

【postgresql】CentOS7 安装pgAdmin 4

CentOS7 安装PostgreSQL Web管理工具pgAdmin 4。 pgAdmin 是世界上最先进的开源数据库 PostgreSQL 最受欢迎且功能丰富的开源管理和开发平台。 下载地址&#xff1a; pgadmin-4 download pgAdmin 4分为桌面版和服务器版。 我们这里部署服务器版本。 安装RPM包。 安装源 s…

现在学编程还能够月薪过万吗?

当我们谈到职业选择时&#xff0c;一项常受人关注的问题是&#xff0c;现在学编程还能月薪过万吗&#xff1f;这似乎是一个不断挂在年轻人嘴边的问题&#xff0c;尤其是在数字化时代&#xff0c;编程的需求越来越大。 所以今天让我们一起探讨这个问题&#xff0c;看看现实生活…

汽车标定技术(九)--标定常量与#pragma的趣事

目录 1. 不添加#pragma语句 2. 添加#pragma语句 3. 标定量只给flash空间&#xff0c;不给ram指定空间 4. 总结 在之前不会使用overlay机制的时候&#xff0c;我们想要做汽车标定&#xff0c;标定常量编译出来的地址一般都应该是ram的地址&#xff0c;而且在链接文件中都会指…

6.5对称二叉树(LC101-E)

算法&#xff1a; 其实就是比较左右子树是否可以翻转 比较的时候&#xff1a; 比较外面的节点是否相等&#xff0c;如示例1中的节点3 比较里面的节点是否相等&#xff0c;如示例1中的节点4 基本思路是这样的&#xff0c;那怎么遍历呢&#xff1f; 二叉树的题一定要掌握到…

更安全的ssh协议与Gui图形化界面使用

目录 前言&#xff1a; 一.Gui图形化界面的使用 二.ssh协议 SSH的主要作用包括&#xff1a; 相比其他网络协议&#xff0c;SSH的优势包括&#xff1a; 三.idea集成Git 前言&#xff1a; 上一篇讲解了git的命令用法以及https协议&#xff0c;但是这个协议放在做团队项目的…

Git系列之Git集成开发工具及git扩展使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Git实战开发》。&#x1f3af;&#x1f3af; &a…

我的月光宝盒初体验失败了

哈哈哈&#xff0c;我爱docker, docker 使我自由&#xff01;&#xff01;&#xff01; docker make me free! 菠萝菠萝蜜口号喊起来。 https://github.com/vivo/MoonBox/ windows上安装好了docker之后&#xff0c;docker-compose是自带的。 docker-compose -f docker-compo…

王学岗visibility改变后调用onLayout()

自定义控件的时候发现了一个bug。 Button位移动画执行结束后我设置了一个不相关的TextView的可见性由gone变为visible.令人郁闷的是&#xff0c;只要我注释的地方放开。动画执行结束后button都会重新绘制在位移动画开始的位置。注释掉这段代码就正常。 经过分析后得知 View的Vi…

C# OpenCvSharp DNN HybridNets 同时处理车辆检测、可驾驶区域分割、车道线分割

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Numerics; using System.Text; using System.Windows.Forms;namespace OpenCvSharp_D…

城市内涝积水的原因有哪些?万宾科技内涝积水监测仪工作原理

一旦有暴雨预警出现多地便会立即响应&#xff0c;以防城市内涝问题出现。随着人口迁移&#xff0c;越来越多的人口涌入城市之中&#xff0c;为了完善城市基础设施建设&#xff0c;城市应急管理部门对内涝的监测越来越严格&#xff0c;在信息化时代&#xff0c;城市管理也趋向于…

G2406C是一款高效的直流-直流降压开关稳压器,能够提供高达1A输出电流。

G2406C 1.5MHz&#xff0c;1A高效降压DC-DC转换器 概述: G2406C是一款高效的直流-直流降压开关稳压器&#xff0c;能够提供高达1A输出电流。G2406C在2.7V至5.5V的宽范围输入电压下工作&#xff0c;使IC是低压电源转换的理想选择。在1.5MHz的固定频率下运行允许使用具有小电感…

【C++】异常 智能指针

C异常 & 智能指针 1.C异常1.1.异常的抛出与捕获1.2.异常体系1.3.异常安全与规范1.4.异常优缺点 2.智能指针2.1.RAII2.2.智能指针的使用及原理2.2.1.auto_ptr2.2.2.unique_ptr2.2.3.shared_ptr2.2.4.shared_ptr的循环引用问题 & weak_ptr 2.3.定制删除器 1.C异常 C异常…

伦敦金冬令时开市时间怎样调整

在刚刚过去的一周&#xff0c;欧美的金融市场已经正式进入了冬令时&#xff0c;这对伦敦金市场的交易时间也产生了影响。由于美国于今年11月5日(星期日&#xff09;开始正式实施冬令时间&#xff0c;所以香港的伦敦金平台的交易时间也随之而有所调整。 从今年11月6日开始&#…

增强地理热图:Highcharts Maps v11.2.0 Crack

Highcharts Maps v11.2.0 添加了对地理热图插值的支持&#xff0c;允许您在类似温度图的图表的已知数据点之间添加估计值。 Highcharts Maps 提供了一种符合标准的方法&#xff0c;用于在基于 Web 的项目中创建逻辑示意图。它扩展了用户友好的 Highcharts JavaScript API&#…

Milvus Cloud——什么是 Agent?

什么是 Agent? 根据 OpenAI 科学家 Lilian Weng 的一张 Agent 示意图 [1] 我们可以了解 Agent 由一些组件来组成。 规划模块 子目标分解:Agent 将目标分为更小的、易于管理的子目标,从而更高效地处理复杂的任务。 反省和调整:Agent 可以对过去的行为进行自我批评和自我反思…

pyOCD

pyOCD 目录结构