20252417 2025-2026-2 《Python程序设计》实验四报告
20252417 2025-2026-2 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 2524
姓名: 艾家程
学号:20252417
实验教师:王志强
实验日期:2026年5月11日
必修/选修: 公选课
1.实验内容
基于Python的AI绘画鉴别小游戏设计与实现
一.实验选题:基于Python的AI绘画鉴别小游戏设计与实现
直接来玩
http://1.95.85.72
这游戏没有第二关
1.程序源代码,运行过程
源代码
代码托管到gitee
https://gitee.com/aaa213213/python-homework
运行过程
1.用python脚本爬取彼岸图网获取非ai图片 (pic.netbian.com)
用python脚本爬取即梦官网获取ai图片jimeng.jianying.com
2.本地游戏运行
3.服务器游戏运行
2.实验分析
随着AI绘画工具的发展,AI生成图片越来越逼真,普通人越来越难以分辨。本程序通过一个小游戏的形式,测试玩家分辨ai绘图的能力。
功能需求分析:
- 图片管理: 从本地文件夹加载AI图片和人工图片,随机抽取,50%概率出现,不连续重复
- 限时模式: 60秒倒计时,每次判断后给出正确/错误反馈,得分=50+正确-错误
- 无尽模式: 无限图片流,允许2次错误,第3次错误结束,得分=正确数
- 结算系统: 根据得分给出S/A/B/C/D/F评级和评价语,显示AI正确率与手工正确率
- 全球统计: 使用json文件储存玩家游玩的信息,显示全球排名
GUI工具包:
tkinter:Python标准GUI库,无需额外安装,适合初学者
Pillow:处理多种图片格式(jpg/png/webp),实现等比缩放
random + time:随机选取图片,时间作为随机种子保证每次不同
pathlib.Path:跨平台的文件路径操作
3.实验设计
1. 整体架构
实验4/
├── aijudge.py # 游戏主程序(约570行)
├── ai_images/ # AI生成图片(10张)
├── non_ai_images/ # 人工图片(10张)
└── aicatch.py # 图片爬虫工具(辅助)
class AIJudgeGame
├── 图片管理 _load_images() / _pick_random_image() / _resize_image()
├── 主菜单界面 _show_main_menu()
├── 游戏界面 _build_game_ui() / _show_image() / _update_info()
├── 判断逻辑 _check_answer() / _show_feedback() / _after_feedback()
├── 倒计时 _start_timer() / _update_timer() / _stop_timer()
├── 结算界面 _show_result() / _get_rating() / _get_rating_timed()
└── 工具方法 _clear_window() / _return_to_menu()
2. 核心算法流程
图片选取:从对应列表随机选一张然后与上一张路径比较,重复则重选
图片缩放:读取原图宽高,使用LANCZOS算法缩放
无限模式得分:正确判断的数量
限时模式得分:50 + 正确判断数 - 错误判断数
4.实验过程
网站调研
1.经过调研决定使用彼岸图网爬取非ai生成图片,页面结构简单,几乎没有什么反爬的措施,容易爬

2.ai图片直接爬取即梦官网的橱窗,爬取略有难度,在ai的帮助下完成

图片爬取
一、彼岸图网的图片爬取
1.枚举列表页,获取所有详情页的链接

2.从详情页获取全尺寸的url,最后爬取图片

二、即梦官网的图片爬取,在ai的帮助下完成
即梦是字节跳动的AI图片生成平台,网站是纯JS渲染的SPA。
必须用 Selenium 驱动浏览器来加载页面并提取图片。
策略:
- 打开即梦首页 (ai-tool/home/)
- 滚动页面加载图片卡片
- 提取所有大尺寸图片URL (过滤掉图标/logo)
- 下载图片
本地aijudge程序的实验过程
步骤1:项目初始化
导入所需库:
import random, time, json, tkinter as tk
from pathlib import Path
from PIL import Image, ImageTk
在实验4目录下创建ai_images和non_ai_images两个文件夹,放入AI图片和人工图片各50张
步骤2:搭建窗口框架
创建 AIJudgeGame 类,在 __init__ 方法中初始化窗口、设置标题和大小、禁止调整窗口尺寸。定义游戏状态变量,调用 mainloop() 启动事件循环。

步骤3:实现图片管理模块
扫描两个文件夹,用 iterdir() 遍历并用列表推导式筛选支持的格式,分别存入 self.ai_images 和 self.nonai_images 列表。
编写 _pick_random_image() 实现50%概率的随机选取与去重。
编写 _resize_image() 用 Pillow 打开图片,计算缩放比例,转为 PhotoImage 对象。
步骤4:实现主菜单界面
展示标题"你能否鉴别AI绘画?",分别放置限时模式和无尽模式的描述文字和"开始游戏"按钮。两个按钮分别绑定 _start_timed_mode 和 _start_endless_mode 。
步骤5:实现游戏界面
编写 _build_game_ui() 构建游戏界面:
顶部栏:左侧"返回主菜单"按钮,右侧纵向排列 No.X 和 剩余时间/失误次数
中部:固定尺寸的图片显示,防止按钮晃动
底部:AI 和 手工 两个判断按钮

步骤6:实现判断逻辑
正确:score+1,更新对应类型的正确计数
错误:wrong_count+1
无尽模式:wrong_count > 2则进入结算
限时模式:调用 _show_feedback() 闪现反馈,100ms后自动进入下一张
步骤7:实现结算界面
计算AI正确率和手工正确率
限时模式得分 = 50 + 正确 - 错误
无尽模式得分 = 正确数
显示评级字母、得分、评价语、统计信息、排名百分比
分数通过 scores.json 文件持久化存储,便于实现排名百分比

5.实验结果
主菜单:显示标题"你能否鉴别AI绘画?",限时模式和无尽模式的说明文字及开始游戏。
游戏界面:顶部显示返回按钮和No.X / 剩余时间;中间显示随机抽取的图片;底部显示AI和手工两个按钮。
限时模式:图片上方闪现正确或错误,0.1秒后进入下一张。
结算界面:显示评级字母、得分、正确错误判断数、评价语、排名信息、AI正确率、手工正确率。
6.附加项目:在华为云服务器上部署,实现在线游玩
源代码
代码托管到gitee
https://gitee.com/aaa213213/python-homework
运行过程
视频在前面,这里就只放网址
http://1.95.85.72
实验过程
在ai的帮助下把aijudge.py代码转换为aijudge_server.py服务器代码

使用gitee克隆上传代码
cd /root
git clone https://gitee.com/aaa213213/python-homework.git AAA_server

服务器运行

二.全课知识点总结
一、Python切片
list[ : : ]切片
list[start: stop: step]
切片范围 x ∈ [start, stop) 左闭右开
索引:
正索引: 0 1 2 3 4 5
负索引:-6 -5 -4 -3 -2 -1
反向切片时索引一定要为负数
用slice( )基本类切片
aslice = slice(2, 5) # 创建一个slice类并初始化
list = [1, 2, 3, 4, 5, 6, 7,]
list[aslice]
二、Python字符串
字符串为不可变对象
不能remove,append之类的,不能用列表的操作
三、Python元组
格式为
(element1, element2)
常用函数
| 使用场景 | 实例代码 | 结果与说明 |
|---|---|---|
| 转换字符串 | tuple("abc") |
('a', 'b', 'c'),字符串被拆分为单个字符 |
| 转换列表 | tuple([1, 2, 3]) |
(1, 2, 3),列表转为元组 |
| 转换字典 | tuple({'a': 1, 'b': 2}) |
('a', 'b'),默认只转换字典的键 |
| 转换元组自身 | tuple((1, 2, 3)) |
(1, 2, 3),返回原元组的一个拷贝 |
四、Python字典
定义:dict = {key1: val1, key2: val2}
key的类型不可变,不能为列表,可以为[[python元组]]
语句:
key in dict
判断key是否在字典中,返回True/False
del dict[key]
以key为索引删除元素
dict.update(dict1)
dict.setdefault(key, val)
.keys() 返回所有键
.values() 返回所有值
.items() 返回所有键值对
五、Python函数
- 函数内定义的变量为局部变量,在函数外无法访问
- 函数return之后,函数停止运行
- 调用函数:function(参数)
- 传入的参数n不需要在函数内声明类型
例如:
def function(n):
传入的参数n不需要在函数内声明类型
想在函数内部使用全局变量,需要声明 global a
六、Python类
定义对象属性:
class Cat:
def __init__(self, name):
self.name = name
定义对象方法:
def function(self):
print(self.name)
实例化:
Cat(参数1, 参数2)
可以把实例化传入变量储存,也可以直接使用实例化
获取属性
在class模块里面:
self. 属性名
在class模块外:
实例 .属性名
类继承:
class Son(Father):
def init(self, name, id, salary):
super().init(name, id) # 使用传入的参数并给到父类函数
七、Python异常处理
try:
weight = float(input())
height = float(input())
BMI = weight / height 2
except ValueError:
print("数值错误") ValueError:输入非数字
except:
print("发生其他错误") 其他错误时执行
else:
print("BMI" str(BMI)) 无错误时执行
finally:
print("finish") 无论是否发生错误都执行
常见异常类型:
IndexError:索引超出列表范围
ZeroDivisionError:除以零
FileNotFoundError:打开的文件不存在
TypeError:类型错误(如字符串和数字拼接)
八、Python文件操作
打开文件:
文件对象名 = open("路径", "mode", encoding="编码方式")
mode: 默认为"r"
"r"(只读)
"w"(只写,会覆盖原文件)
"a"(追加,在文件末尾添加)
"r+":同时支持读写,指针初始在文件开头
with open("路径") as 文件对象名: # 操作完成后自动关闭文件
文件对象方法:
对象.close():关闭文件
对象.read(n):读取n字节
对象.read():读取所有内容
对象.readline():读取一行
对象.readlines():读取全部内容,每行作为元素存入列表
读取所有内容后返回""(空字符串)
三.课程感想体会、意见和建议
这门Python公选课是我本学期收获最大的课程之一。从只会写hello world到能完成一个带GUI的游戏程序、甚至部署到云服务器上让别人在线玩,这个进步是实实在在的。
编程学习最大的体会是:代码是敲出来的,上课听懂和能写出来之间隔着大量练习,而每个Bug都是最好的老师,逼着我去查文档、读报错、理解底层逻辑。
感谢老师的指导和耐心。

浙公网安备 33010602011771号