python实现答题游戏

ops/2025/1/23 12:33:19/

有这样一个需求:使用python实现一个游戏,一共有10个问题,依次回答每个问题,每个用户可以输入问题的答案,但是互相不能看到,有一个管理员可以看到所有人的答案,并且当所有人都填写完成后可以公布所有人的答案,并且打分。在回答的下面有一个得分表,每打完一轮问题的得分则实时计算总得分和排名。限制一个IP只能登录一个用户。

下面给出一个基于 Flask 的简化示例,演示如何用 Python 实现这样一个游戏的核心功能,主要包括:

  1. 10 个问题的答题流程。
  2. 用户只能看到自己的答案,管理员可以看到所有人的答案。
  3. 当所有人都填写完成后,管理员可以公布所有人的答案并进行打分。
  4. 显示得分表,每轮更新后实时计算总得分和排名
  5. 限制同一个 IP 地址只能登录一个用户。

为演示方便,以下示例仅做最小可行的流程说明,使用字典存储用户和答案信息;在实际生产环境中,可以结合数据库、认证机制、前端模板等进行更完善的开发。


主要功能说明

  1. 注册/登录

    • 用户首次进入时,需要填写用户名进行注册并登录。
    • 同一个 IP 地址只允许注册一个用户,后续从同一 IP 再访问则直接视为该用户登录或禁止二次注册。
  2. 答题

    • 一共 10 个问题,这里演示时以简单的问卷形式呈现。
    • 每个用户在提交完所有答案后,才能等待管理员公布结果。
  3. 管理员查看与公布答案

    • 管理员可以查看所有用户答案。
    • 管理员可进行打分,并将所有用户答案与分数公示。
    • 每完成一轮题目即可查看实时总得分并进行排名。
  4. 得分统计与排名

    • 每一轮提交答案后,管理员打分并把分数汇总到用户总分中。
    • 根据所有用户的总分动态计算排名并显示。

代码示例

下面的示例使用 Flask 进行演示,提供了若干路由(URL)以完成相应功能。请先安装 Flask:

pip install flask

然后创建一个脚本文件(如 quiz_game.py),内容如下:

python">from flask import Flask, request, session, redirect, url_for, render_template_string
import functoolsapp = Flask(__name__)
app.secret_key = "your_secret_key"  # 用于 session 加密# 记录哪些 IP 已经注册过用户
ip_to_user = {}# 存储用户信息,包括用户名、答案、分数等
# 结构示例:
# users_data = {
#   'alice': {
#       'answers': ["ans1", "ans2", ...],  # 当前轮次的答案
#       'scores': [5, ...],               # 历史每一轮的得分
#       'total_score': 5
#   },
#   'bob': {...},
#   ...
# }
users_data = {}# 定义题目,这里示例 10 个问题
QUESTIONS = ["问题1:你最喜欢的颜色是什么?","问题2:你最喜欢的动物是什么?","问题3:你的故乡在哪里?","问题4:你最喜欢吃什么?","问题5:你最喜欢哪个季节?","问题6:你最喜欢做的运动是什么?","问题7:你最喜欢的电影类型是什么?","问题8:假期里你最想去哪里旅行?","问题9:你希望学习哪项新技能?","问题10:你最喜欢的音乐类型是什么?",
]# 标记当前答题是否开放,如果轮次结束后可以由管理员统一切换
answer_open = True
# 标记这一轮是否已经公布答案
answers_revealed = False# ========== 帮助函数 ==========def login_required(func):"""需要用户已登录,否则跳转到登录页面。"""@functools.wraps(func)def wrapper(*args, **kwargs):if 'username' not in session:return redirect(url_for('login'))return func(*args, **kwargs)return wrapperdef admin_required(func):"""需要管理员权限,否则跳转到登录。此示例简单地将用户名为 'admin' 视为管理员。"""@functools.wraps(func)def wrapper(*args, **kwargs):if session.get('username') != 'admin':return "只有管理员能访问此页面。", 403return func(*args, **kwargs)return wrapperdef get_rankings():"""根据 total_score 得到排行榜信息,返回 [(username, total_score), ...] 从高到低。"""ranking = sorted(users_data.items(), key=lambda x: x[1].get('total_score', 0), reverse=True)# 转换成列表 [(用户名, 总分), ...]return [(user, info['total_score']) for user, info in ranking]# ========== 路由视图 ==========@app.route('/')
def index():"""主页,如果已登录则跳转到答题页面;否则跳转到登录。"""if 'username' in session:return redirect(url_for('quiz'))else:return redirect(url_for('login'))@app.route('/login', methods=['GET', 'POST'])
def login():"""用户登录/注册入口。同一个IP只能注册一个用户,若该IP已注册过,则自动成为该用户或禁止再次注册。"""client_ip = request.remote_addrif request.method == 'POST':username = request.form.get('username', '').strip()if not username:return "用户名不能为空", 400# 如果该IP已经注册过其他用户,则禁止重复注册if client_ip in ip_to_user and ip_to_user[client_ip] != username:return f"该IP({client_ip})已经注册过用户 {ip_to_user[client_ip]},无法重复注册。", 403# 如果该IP没有注册用户或者与现有用户名匹配,则继续ip_to_user[client_ip] = username# 如果用户第一次注册,初始化信息if username not in users_data:users_data[username] = {"answers": [""] * len(QUESTIONS),"scores": [],"total_score": 0}session['username'] = usernamereturn redirect(url_for('quiz'))# GET 请求,返回一个简单的登录表单return render_template_string("""<h2>用户登录/注册</h2><form method="post">用户名:<input type="text" name="username"><br><input type="submit" value="登录"></form>""")@app.route('/quiz', methods=['GET', 'POST'])
@login_required
def quiz():"""答题页面。提交后保存答案。这里简单演示一次性提交 10 个问题。"""global answer_openglobal answers_revealedusername = session['username']if request.method == 'POST':if not answer_open:return "当前轮次答题已关闭,等待管理员开启下一轮或公布结果。", 403# 接收 10 个问题的答案new_answers = []for i in range(len(QUESTIONS)):ans = request.form.get(f'question_{i}', '').strip()new_answers.append(ans)# 保存新的答案users_data[username]['answers'] = new_answersreturn "提交成功!等待管理员公布结果。"# GET 请求时渲染一个简单的表单user_answers = users_data[username].get('answers', [""]*len(QUESTIONS))html_form = """<h2>答题页面</h2>{% if answer_open %}<form method="post">{% for i, question in enumerate(QUESTIONS) %}<div><label>{{ question }}</label><br><input type="text" name="question_{{ i }}" value="{{ user_answers[i] }}"></div><br>{% endfor %}<input type="submit" value="提交答案"></form>{% else %}<p>答题已关闭,请等待管理员开启下一轮或查看最终结果。</p>{% endif %}"""return render_template_string(html_form,QUESTIONS=QUESTIONS,user_answers=user_answers,answer_open=answer_open)@app.route('/admin_view')
@admin_required
def admin_view():"""管理员查看所有用户答案的页面(仅管理员可访问)。"""html = "<h2>管理员查看所有答案</h2>"for user, info in users_data.items():html += f"<h3>用户:{user}</h3>"answers = info.get('answers', [])for i, ans in enumerate(answers):html += f"问题{i+1}: {ans}<br>"return html@app.route('/admin_score', methods=['GET', 'POST'])
@admin_required
def admin_score():"""管理员对本轮答案进行打分并公布。一次性给所有用户打分,然后系统更新总分、清空当前答案。"""global answer_openglobal answers_revealed# GET:显示一个打分的页面if request.method == 'GET':html = """<h2>管理员打分</h2><form method="post">"""for user in users_data:html += f"<label>给用户 {user} 的本轮答案打分:</label>"html += f"<input type='number' name='score_{user}' value='0' min='0' max='100'><br><br>"html += "<input type='submit' value='提交分数'>"html += "</form>"return html# POST:接收管理员给每个用户的分数,更新 total_scorefor user in users_data:score_str = request.form.get(f'score_{user}', '0')try:score = int(score_str)except ValueError:score = 0# 更新每个用户的分数信息users_data[user]['scores'].append(score)users_data[user]['total_score'] += scoreanswers_revealed = Trueanswer_open = False  # 关闭当前轮次答题,等待管理员手动开启下一轮(如果有的话)return redirect(url_for('results'))@app.route('/results')
@login_required
def results():"""公布所有用户本轮答案与分数(如果管理员已打分的话)。并显示当前排行榜。"""if not session.get('username'):return redirect(url_for('login'))if not users_data:return "暂无答案"html = "<h2>当前轮次结果</h2>"# 只有在管理员打完分之后才公布if not all(users_data[user]['scores'] for user in users_data):html += "<p>管理员尚未打分,无法显示分数。</p>"else:# 显示最新一轮的分数(即 scores 列表中的最后一项)for user, info in users_data.items():latest_score = info['scores'][-1] if info['scores'] else 0answers = info.get('answers', [])html += f"<h3>用户:{user}</h3>"for i, ans in enumerate(answers):html += f"问题{i+1}: {ans}<br>"html += f"<strong>本轮得分: {latest_score}</strong><br>"# 显示排行榜html += "<h2>排行榜</h2>"ranking = get_rankings()rank_str = ""for idx, (user, total_score) in enumerate(ranking, start=1):rank_str += f"{idx}. {user}{total_score}分<br>"html += rank_strreturn html@app.route('/admin_open_new_round')
@admin_required
def admin_open_new_round():"""管理员开启新一轮答题:清空当前答案,answer_open = True, 并 answers_revealed = False。"""global answer_open, answers_revealed# 把当前答案列表清空(如果希望保留可以改成其他逻辑)for user, info in users_data.items():info['answers'] = [""] * len(QUESTIONS)answer_open = Trueanswers_revealed = Falsereturn "新一轮答题已开启!"if __name__ == '__main__':# 启动Flask服务app.run(debug=True, host='0.0.0.0', port=5000)

功能说明

  1. ip_to_user 字典用于记录 IP → 用户名 的映射,确保同一 IP 无法注册多个账号。
  2. users_data 用于保存所有用户的状态,包括:
    • 当前轮的答案 answers
    • 每一轮的得分列表 scores
    • 总分 total_score
  3. answer_open 控制当前轮次是否允许答题,answers_revealed 标记本轮答案是否已公布。
  4. 提供了如下 路由
    • /login:用户登录/注册页面。
    • /quiz:用户答题页面(一次性答完 10 道题)。
    • /admin_view:管理员查看所有答案(仅管理员可访问)。
    • /admin_score:管理员对所有用户打分并公布结果(仅管理员可访问)。
    • /results:已打分后的结果页面,显示所有用户本轮答案、分数以及排行榜。
    • /admin_open_new_round:管理员开启下一轮答题,清空当前答案,重新开放答题。

使用方式

  1. 安装依赖并运行:
    pip install flask
    python quiz_game.py
    
  2. 浏览器访问 http://<服务器IP>:5000,若未登录则自动跳转到 /login
  3. 管理员可以使用特殊用户名(如 admin)登录,以访问管理员路由:
    • http://<服务器IP>:5000/admin_view 查看所有人的答案
    • http://<服务器IP>:5000/admin_score 给大家打分
    • http://<服务器IP>:5000/admin_open_new_round 开启下一轮
  4. 普通用户只能查看自己的答案并进行答题,分数公布后可查看总榜。

后续完善建议

  • 数据库:将用户数据、IP 映射等存入数据库(如 SQLite、MySQL、PostgreSQL),确保数据持久化。
  • 用户认证:对登录机制进行加固,比如密码验证、单点登录、令牌校验等,防止恶意用户冒名顶替。
  • 前端界面:可使用 Flask 的模板功能(或前端框架)美化页面,并提供更加友好易用的交互。
  • 并发/部署:考虑使用 uWSGI、Gunicorn 等部署在正式服务器上,提高并发能力。

这个示例主要演示了核心逻辑流程和数据结构,大家可以根据实际需求进行拓展和改进。祝你开发顺利!


http://www.ppmy.cn/ops/152465.html

相关文章

论文速读| A Survey on Data Synthesis and Augmentation for Large Language Models

论文地址&#xff1a;https://arxiv.org/abs/2410.12896v1 bib引用&#xff1a; misc{wang2024surveydatasynthesisaugmentation,title{A Survey on Data Synthesis and Augmentation for Large Language Models}, author{Ke Wang and Jiahui Zhu and Minjie Ren and Zeming L…

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端&#xff1a; sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端&#xff1a; sudo systemctl start ssh贰、配置SSH&#xff08;可跳过&#xff09; 配置文件 …

Tmux新手使用教程

1. 概述tmux 想象一下&#xff0c;你需要在终端中同时做很多事情&#xff1a;编辑代码、运行程序、查看日志等等。如果每个任务都开一个终端窗口&#xff0c;会很乱而且切换麻烦。 tmux 就相当于一个终端的“管理器”&#xff0c;它可以&#xff1a; 让你在一个终端窗口里打…

Docker Compose创建镜像服务

什么是Docker Compose 使用Docker Compose&#xff0c;可以使用YAML配置文件&#xff08;称为Compose文件&#xff09;来配置应用程序的服务&#xff0c;然后使用Compose CLI从配置中创建并启动所有服务 。 Compose文件的默认路径是compose.yaml&#xff08;首选&#xff09;…

图像点处理

怎么理解灰度图&#xff1f; RGB很明显有三个通道 我们看红色通道&#xff0c;因为天空中红色含量&#xff08;R值&#xff09;最少&#xff0c;因此红色通道中的天空最暗&#xff0c;而因为建筑红色含量&#xff08;R值&#xff09;最高&#xff0c;所以红色通道中的建筑最亮…

C#性能优化技巧:利用Lazy<T>实现集合元素的延迟加载

一、C#中的Lazy C#中的Lazy<T>是一个泛型类&#xff0c;它实现了延迟加载&#xff08;Lazy Initialization&#xff09;的功能。延迟加载是指对象的创建被推迟&#xff0c;直到第一次被使用时才进行实例化。这对于大型或资源密集型对象的性能优化非常有用&#xff0c;因…

计算机视觉中的目标检测技术

1. 引言 目标检测是计算机视觉中的重要任务&#xff0c;涉及识别图像或视频中的多个对象并定位它们的位置。与图像分类不同&#xff0c;目标检测不仅需要识别类别&#xff0c;还要在图像中绘制出对象的边界框(Bounding Box)。本文将探讨目标检测的核心技术和应用&#xff0c;并…

STM32 GPIO工作模式

GPIO工作模式 1. GPIO简介2. GPIO工作模式2.1 输入浮空2.2 输入上拉2.3 输入下拉2.4 模拟2.5 开漏输出2.6 推挽输出2.7 开漏式复用功能2.8 推挽式复用功能 1. GPIO简介 GPIO 是通用输入输出端口的简称&#xff0c;简单来说就是 STM32 可控制的引脚&#xff0c;STM32 芯片的 GPI…