From c5265add08e7a9d7243ea62ad11e71bad3990b31 Mon Sep 17 00:00:00 2001 From: sairate Date: Fri, 4 Jul 2025 15:36:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=AC=AC7=E8=AE=B2=20=E5=AD=97=E6=AF=8D?= =?UTF-8?q?=E5=8D=A1=E7=89=8C):=20=E5=AE=9E=E7=8E=B0=E8=AE=B0=E5=BF=86?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 jiyi.py 文件,实现字母翻牌记忆游戏功能 - 添加 youxijiemian.py 文件,创建游戏开始界面 - 使用 turtle 和 tkinter 模块分别实现游戏和界面 - 支持选择不同难度的游戏模式 --- test.py | 78 ++++++++++++++++- 第22讲手势识别/课堂成果/README.md | 4 + 第22讲手势识别/课堂成果/手势识别.py | 76 +++++++++++++++++ 第6讲太阳系/课堂成果/base.py | 1 + 第6讲太阳系/课堂成果/交换井字棋.py | 85 +++++++++++++++++++ .../课堂成果/随机打点法.py | 10 +-- 第9讲世界时钟/课堂成果/世界时钟.py | 2 +- 7 files changed, 244 insertions(+), 12 deletions(-) create mode 100644 第22讲手势识别/课堂成果/README.md create mode 100644 第22讲手势识别/课堂成果/手势识别.py create mode 100644 第6讲太阳系/课堂成果/交换井字棋.py diff --git a/test.py b/test.py index 59bd554..b73199a 100644 --- a/test.py +++ b/test.py @@ -1,4 +1,74 @@ -import turtle -turtle.listen() -turtle.onscreenclick(print) -turtle.done() \ No newline at end of file +students={ + "0001":{ + "name":"张三", + "sex":"男", + "age":18, + "score":[90,80,70] + }, + "0002":{ + "name":"李四", + "sex":"女", + "age":19, + "score":[80,90,80] + } +} + +while True: + print("="*5+"学生管理系统"+"="*5) + print("1.查询学生信息") + print("2.添加学生信息") + print("3.删除学生信息") + print("4.修改学生信息") + print("5.列出所有学生信息") + print("6.退出") + choice=input("请输入你的选择:") + if choice=="1": + name=input("请输入学生姓名:") + for k,v in students.items(): + if v["name"]==name: + print("学号 \t姓名 \t性别 \t年龄 \t语文成绩 \t数学成绩 \t英语成绩") + print("%s \t%s \t%s \t%d \t%d \t%d \t%d" % (k, v["name"], v["sex"], v["age"], v["score"][0], v["score"][1], v["score"][2])) + break + else: + print("没有此学生") + elif choice=="2": + sid=input("请输入学号:") + if students.get(sid): + print("此学号已存在") + else: + name=input("请输入学生姓名:") + sex=input("请输入学生性别:") + age=int(input("请输入学生年龄:")) + score=[int(x) for x in input("请输入学生成绩:").split(",")] + students[sid]={"name":name,"sex":sex,"age":age,"score":score} + print("添加成功") + elif choice== "3": + name=input("请输入学生姓名:") + for k,v in students.items(): + if v["name"]==name: + del students[k] + print("删除成功") + break + else: + print("没有此学生") + elif choice=="4": + name=input("请输入学生姓名:") + for k,v in students.items(): + if v["name"]==name: + v["name"]=input("请输入学生姓名:") + v["sex"]=input("请输入学生性别:") + v["age"]=int(input("请输入学生年龄:")) + v["score"]=[int(x) for x in input("请输入学生成绩:").split(",")] + print("修改成功") + break + else: + print("没有此学生") + elif choice=="5": + print("所有学生信息为:") + print("学号 \t姓名 \t性别 \t年龄 \t语文成绩 \t数学成绩 \t英语成绩") + for k,v in students.items(): + print("%s\t%s \t%s \t%d \t%d \t%d \t%d"%(k,v["name"],v["sex"],v["age"],v["score"][0],v["score"][1],v["score"][2])) + elif choice== "6": + break + else: + print("输入错误") \ No newline at end of file diff --git a/第22讲手势识别/课堂成果/README.md b/第22讲手势识别/课堂成果/README.md new file mode 100644 index 0000000..3f32055 --- /dev/null +++ b/第22讲手势识别/课堂成果/README.md @@ -0,0 +1,4 @@ +```bash +#阿里云镜像源 +pip install -i https://mirrors.aliyun.com/pypi/simple/ opencv-python mediapipe +``` \ No newline at end of file diff --git a/第22讲手势识别/课堂成果/手势识别.py b/第22讲手势识别/课堂成果/手势识别.py new file mode 100644 index 0000000..a17814b --- /dev/null +++ b/第22讲手势识别/课堂成果/手势识别.py @@ -0,0 +1,76 @@ +import cv2 # 导入 OpenCV,用于视频捕获和图像处理 +import mediapipe as mp # 导入 MediaPipe,用于手部关键点检测 + +# =================== 初始化 MediaPipe 模块 =================== + +# 获取 MediaPipe 手部识别模块 +mp_hands = mp.solutions.hands + +# 创建 Hands 对象,用于处理图像中的手部关键点 +# 默认参数含义: +# - static_image_mode=False:处理连续视频流(非静态图片) +# - max_num_hands=2:最多检测2只手 +# - min_detection_confidence=0.5:置信度低于0.5的检测结果将被忽略 +hands = mp_hands.Hands() + +# 获取用于绘制关键点和连接线的工具 +mp_draw = mp.solutions.drawing_utils + +# =================== 初始化摄像头 =================== + +# 打开默认摄像头(设备编号为0) +cap = cv2.VideoCapture(0) + +# =================== 主循环,逐帧处理 =================== + +while True: + # 捕获一帧图像 + ret, frame = cap.read() + + # 如果捕获失败,退出循环 + if not ret: + break + + # 水平翻转图像(摄像头默认是镜像视角,翻转后更自然) + frame = cv2.flip(frame, 1) + + # OpenCV 默认使用 BGR 格式,而 MediaPipe 要求输入 RGB 格式图像 + rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + + # 使用 MediaPipe 的 hand 模块处理当前帧,检测手部关键点 + results = hands.process(rgb_frame) + + # =================== 处理检测结果 =================== + + # 如果检测到了手部 + if results.multi_hand_landmarks: + # 遍历每只手 + for landmarks in results.multi_hand_landmarks: + # 在原图上绘制21个关键点及其连接骨骼(HAND_CONNECTIONS) + mp_draw.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS) + + # 提取21个关键点的 Landmark 对象(含 x, y, z 三维坐标) + landmark_points = [landmarks.landmark[i] for i in range(21)] + + # =================== 手势识别部分(可拓展) =================== + # 例如:判断是否为“比赞”手势(此处未实现具体函数) + # if detect_thumb_up(landmark_points): + # cv2.putText(frame, "Thumb Up!", (50, 100), + # cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) + + # =================== 显示图像 =================== + + # 显示处理后的视频帧(窗口标题为 Hand Gesture Detection) + cv2.imshow('Hand Gesture Detection', frame) + + # 等待键盘事件,如果按下 'q' 键则退出程序 + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# =================== 清理资源 =================== + +# 释放摄像头 +cap.release() + +# 销毁所有 OpenCV 窗口 +cv2.destroyAllWindows() diff --git a/第6讲太阳系/课堂成果/base.py b/第6讲太阳系/课堂成果/base.py index 7b3c7a4..b2963b3 100644 --- a/第6讲太阳系/课堂成果/base.py +++ b/第6讲太阳系/课堂成果/base.py @@ -1,5 +1,6 @@ import turtle +#右键点击两个格,内容会交换 qipan=[(-50,150),(50,150),(-150,50),(-150,-50)] t1=turtle.Turtle() diff --git a/第6讲太阳系/课堂成果/交换井字棋.py b/第6讲太阳系/课堂成果/交换井字棋.py new file mode 100644 index 0000000..b895ac9 --- /dev/null +++ b/第6讲太阳系/课堂成果/交换井字棋.py @@ -0,0 +1,85 @@ +import tkinter as tk +from tkinter import messagebox + +class SneakyTicTacToe: + def __init__(self, root): + self.root = root + + self.size = 7 # 实际棋盘大小 + self.board = [["" for _ in range(self.size)] for _ in range(self.size)] + self.current_player = "X" + + self.buttons = [[None for _ in range(self.size)] for _ in range(self.size)] + + # 记录右键点击的两个格子 + self.swap_selection = [] + + for i in range(self.size): + for j in range(self.size): + btn = tk.Button(root, text="", font=("Arial", 24), width=3, height=1) + btn.grid(row=i+1, column=j) + btn.config(command=lambda r=i, c=j: self.on_click(r, c)) + btn.bind("", lambda e, r=i, c=j: self.on_right_click(r, c)) # 右键绑定 + self.buttons[i][j] = btn + + + root.geometry(f"{3*65}x{3*63}") # 默认窗口大小 + + def on_click(self, r, c): + if self.board[r][c] != "": + return + self.board[r][c] = self.current_player + self.buttons[r][c].config(text=self.current_player) + + if self.check_winner(self.current_player): + messagebox.showinfo("🎉 游戏结束", f"玩家 {self.current_player} 获胜!") + self.reset() + elif self.is_draw(): + messagebox.showinfo("😐 游戏结束", "平局") + self.reset() + else: + self.current_player = "O" if self.current_player == "X" else "X" + + def on_right_click(self, r, c): + # 只允许选择非空格子进行交换 + if self.board[r][c] == "": + return + + self.swap_selection.append((r, c)) + if len(self.swap_selection) == 2: + (r1, c1), (r2, c2) = self.swap_selection + # 交换 board 内容 + self.board[r1][c1], self.board[r2][c2] = self.board[r2][c2], self.board[r1][c1] + self.buttons[r1][c1].config(text=self.board[r1][c1]) + self.buttons[r2][c2].config(text=self.board[r2][c2]) + self.swap_selection.clear() + + def check_winner(self, player): + for i in range(self.size): + for j in range(self.size): + if j + 2 < self.size and all(self.board[i][j+k] == player for k in range(3)): + return True + if i + 2 < self.size and all(self.board[i+k][j] == player for k in range(3)): + return True + if i + 2 < self.size and j + 2 < self.size and all(self.board[i+k][j+k] == player for k in range(3)): + return True + if i + 2 < self.size and j - 2 >= 0 and all(self.board[i+k][j-k] == player for k in range(3)): + return True + return False + + def is_draw(self): + return all(self.board[i][j] != "" for i in range(self.size) for j in range(self.size)) + + def reset(self): + for i in range(self.size): + for j in range(self.size): + self.board[i][j] = "" + self.buttons[i][j].config(text="") + self.current_player = "X" + self.swap_selection.clear() + +# 启动游戏 +if __name__ == "__main__": + root = tk.Tk() + game = SneakyTicTacToe(root) + root.mainloop() diff --git a/第8讲蒙特卡洛法求圆周率/课堂成果/随机打点法.py b/第8讲蒙特卡洛法求圆周率/课堂成果/随机打点法.py index 9a2a571..6c1ff97 100644 --- a/第8讲蒙特卡洛法求圆周率/课堂成果/随机打点法.py +++ b/第8讲蒙特卡洛法求圆周率/课堂成果/随机打点法.py @@ -1,21 +1,17 @@ from turtle import * import random -tracer(False) +tracer(False)#跳过绘画过程 bgpic("dot.png") setup(1200,800) - t=Pen() -t.ht() +t.ht()#隐藏画笔 t.penup() - nei=0 total=0 - t2=Pen() t2.ht() t2.penup() t2.goto(380,-50) - while True: x=random.randint(-200,200) y=random.randint(-200,200) @@ -29,4 +25,4 @@ while True: pai=4*nei/total t2.clear() t2.write("{}\n\n{}\n\n{}".format(nei,total,round(pai,4)),font=("宋体",25,'bold')) - update() + update() \ No newline at end of file diff --git a/第9讲世界时钟/课堂成果/世界时钟.py b/第9讲世界时钟/课堂成果/世界时钟.py index ca08cfe..59629c2 100644 --- a/第9讲世界时钟/课堂成果/世界时钟.py +++ b/第9讲世界时钟/课堂成果/世界时钟.py @@ -3,7 +3,7 @@ from turtle import * bgpic("China.png") setup(1200,800) -tracer(False) +tracer(False)#画笔不刷新 h=Pen() m=Pen()