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绘图的能力。

功能需求分析:

  1. 图片管理: 从本地文件夹加载AI图片和人工图片,随机抽取,50%概率出现,不连续重复
  2. 限时模式: 60秒倒计时,每次判断后给出正确/错误反馈,得分=50+正确-错误
  3. 无尽模式: 无限图片流,允许2次错误,第3次错误结束,得分=正确数
  4. 结算系统: 根据得分给出S/A/B/C/D/F评级和评价语,显示AI正确率与手工正确率
  5. 全球统计: 使用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 驱动浏览器来加载页面并提取图片。
策略:

  1. 打开即梦首页 (ai-tool/home/)
  2. 滚动页面加载图片卡片
  3. 提取所有大尺寸图片URL (过滤掉图标/logo)
  4. 下载图片

本地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_imagesself.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函数

  1. 函数内定义的变量为局部变量,在函数外无法访问
  2. 函数return之后,函数停止运行
  3. 调用函数:function(参数)
  4. 传入的参数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都是最好的老师,逼着我去查文档、读报错、理解底层逻辑。
感谢老师的指导和耐心。

posted @ 2026-06-02 19:06  AAA213213  阅读(71)  评论(0)    收藏  举报