Flask开发成语接龙游戏,以后闲了手机玩玩自己写的游戏吧!

简介: Flask开发成语接龙游戏,以后闲了手机玩玩自己写的游戏吧!

接龙规则


成语接龙是中华民族传统的文字游戏。它不仅有着悠久的历史和广泛的社会基础,同时还是体现我国文字、文化、文明的一个缩影,是老少皆宜的民间文化娱乐活动。

成语接龙规则多样,大家一般熟知的是采用成语字头与字尾相连不断延伸的方法进行接龙;用四个字成语的最后一个字与下一句成语的第一个相同的字【音同就可以】,首尾相接不断延伸,形成长龙。


实现分析



数据库信息

先来看看我们的数据库信息:


网络异常,图片无法展示
|

数据库信息


数据库表idiom分为id,name,speak,meaning,example,hot 几个字段,hot是当时搜索的网站热词排行,跟咱们没有太大关系...主要是name和speak字段。


登陆排行

为了能增强可玩性,我们在每次开场前,允许用户随机输入一个名字。在挑战过程中,针对用户坚持的接龙次数进行排名。


网络异常,图片无法展示
|

挑战者记录


创建用户排名表:

CREATE TABLE rank (
    name  VARCHAR (50) NOT NULL,
    round_num INT      NOT NULL
);

这里为什么不设置主键呢?主要是排名取前5,用户使用一个名字多次参战,如果犀利的话包揽前5看这也很帅气啊,清一色的都是我,想想都觉得自我满足感爆棚。


游戏界面

首先映入眼帘的是ROUND 1的接龙次数显示,有没有儿时拳皇对打的感觉...

为了帮助大家在玩游戏的同时能学习成语知识,也避免有些生僻字不认识,所以在界面中显示了成语、注音、解释和示例,当然示例不是每个成语都有,网站有啥我就展示啥呗...

网络异常,图片无法展示
|

游戏界面


成语判断

首先必须是四字的成语,用户输入非四字的成语会弹出警示栏,其次用户填写完成语后,会将成语在数据库中进行检索,如果是成语则进行接龙后返回电脑的匹配结果,进行第二轮的基隆,如果数据库中无此成语会弹出游戏结束的提示“挑战结束:用户输入的成语是自己编的吧!”,返回登陆页,并将用户的挑战结果入库rank表进行排行。

这里需要注意,成语接龙的收尾字可以不一样但音必须相同,包括==声调==哦!


拼音识别

数据库中的成语我们存在拼音了,但用户输入的是汉字,我们如何进行拼音转化呢?这里需要使用到python的一个模块pypinyin。针对这个模块的使用,之前写过一篇文章Python为文档批量注音(生僻字歌词为例),喜欢的朋友可以去看看。用法很简单,但我们需要做到和数据库中相对应才行。

from pypinyin import pinyin
pinyin('唇枪舌剑')
# output:
[['chún'], ['qiāng'], ['shé'], ['jiàn']]
# 此处为一个嵌套列表,我们需要转化为数据库中的格式
'  '.join(map(lambda x: x[0], pinyin('唇枪舌剑')))
# output:
'chún  qiāng  shé  jiàn'


代码编写



Jinjia2模板

大家看到不管是用户登录还是游戏界面,外框内容基本一致,基于这种场景使用Jinjia2的模板继承是个很不错的选择:

layout.html主要负责大体框架及相关css和js的引入工作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1 ,user-scalable=no">
    <title>清风python</title>
    <link rel="icon" href="{{ url_for('static',filename='favicon.ico') }}">
    <link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}">
    <link rel="stylesheet" href="{{ url_for('static',filename='css/main.css') }}">
    <script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
</head>
<body>
<div class="container container-small">
    <div class="content">
        <div class="header">
            成语接龙
        </div>
        <div class="block-info">
            {% block contents %}
            {% endblock %}
        </div>
    </div>
    <div class="footer">
        ©2019-欢迎关注我的公众号:<a href="https://www.jianshu.com/u/d23fd5012bed">清风Python</a>
    </div>
</div>
</body>
</html>

login.html涉及到挑战者排行和用户名提交与页面跳转

{% extends "layout.html"%}
{% block contents %}
<form method="post">
    <div class="form-group has-success">
        <div class="input-group">
            <div class="input-group-addon">
                选手姓名:
            </div>
            <input id='name' name="name" class="form-control" required autofocus>
        </div>
    </div>
    <div class="form-group ">
        <button type="submit" class="form-control btn-primary" id="load">火前留名</button>
    </div>
</form>
<div class="form-group ">
    <span class="label label-info">如果战绩足够出色,你的名字也将出现在下方!</span>
</div>
<div class="form-group table_show">
    <table class="table table-hover  table-bordered">
        <thead>
        <tr>
            <th>排名</th>
            <th>挑战者</th>
            <th>对答次数</th>
        </tr>
        </thead>
        <tbody>
        {% if rank_list|length %}
            {% for rank in rank_list %}
            <tr>
                <th scope="row">{{ loop.index }}</th>
                <td>{{rank.name}}</td>
                <td>{{rank.round_num}}</td>
            </tr>
            {% endfor %}
        {% endif %}
        </tbody>
    </table>
</div>
{% endblock %}

game.html主要负责成语接龙游戏的监控与AJAX数据的后台刷新。

{% extends "layout.html"%}
{% block contents %}
<div class="form-group has-success">
    <h3 id='round_num' class="round_num">ROUND 1</h3>
</div>
<div class="form-group rank">
    <table class="table table-hover  table-bordered table_show table-condensed">
        <tbody>
        <tr>
            <th>成语</th>
            <td id="idiom_name"> {{idiom.name}} ({{idiom.speak}})</td>
        </tr>
        <tr>
            <th>解释</th>
            <td id="idiom_meaning">{{idiom.meaning}}</td>
        </tr>
        <tr>
            <th>示例</th>
            <td id="idiom_example"> {{idiom.example}}</td>
        </tr>
        </tbody>
    </table>
</div>
<div class="form-group has-success">
    <div class="input-group">
        <div class="input-group-addon" required autofocus>
            成语:
        </div>
        <input id='user_idiom' class="form-control">
    </div>
</div>
<div class="form-group ">
    <button class="form-control btn-primary" id="load">用户:{{user}} 作答</button>
</div>
<script type="text/javascript">
    $(function () {
        $('#load').click(function () {
            let user_idiom = $('#user_idiom').val();
            if (user_idiom.length != 4) {
                alert("请填写四字成语...");
            } else {
                $.ajax({
                    url: '/more/' + user_idiom,
                    type: 'get',
                    success: function (data) {
                        $('.result').html(data);
                        if (data['code'] == 200) {
                            $('#round_num').html('ROUND ' + data['round']);
                            $('#idiom_name').html(data['info']['name'] + ' (' + data['info']['speak'] + ')');
                            $('#idiom_meaning').html(data['info']['meaning']);
                            $('#example').html('ROUND ' + data['info']['example']);
                        } else {
                            alert(data['error']);
                            $(location).attr('href', data['url']);
                        }
                    }
                })
            }
        })
    })
</script>
{% endblock %}

Flask装饰器

首先,我们的游戏涉及到SQLite数据库的交互,所以在每次请求前,需要建立数据库,请求结束后需要释放连接。此时我们需要使用到两个装饰器,@app.before_request@app.teardown_request,before_request见名知意就是在请求访问前调动该装饰器,那么为什么不用对应的@app.after_request呢?因为即便用户代码在执行过程中,出现任何错误,也可以通过@app.teardown_request装饰器最终释放数据库连接,但@app.after_request可不行...


Flask整体代码如下

import sqlite3
from flask import Flask, render_template, request, g, session, redirect, url_for, jsonify
import random
from pypinyin import pinyin
app = Flask(__name__)
DATABASE = 'static/db/database.db'
app.secret_key = 'Breeze Python'
def connect_db():
    return sqlite3.connect(DATABASE)
@app.before_request
def before_request():
    g.db = connect_db()
@app.teardown_request
def teardown_request(exception):
    if hasattr(g, 'db'):
        g.db.close()
def query_db(query, args=(), one=True):
    cur = g.db.execute(query, args)
    rv = [dict((cur.description[idx][0], value)
               for idx, value in enumerate(row)) for row in cur.fetchall()]
    if not query.startswith('select'):
        g.db.commit()
    return (rv[0] if rv else None) if one else rv
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        user = request.form.get('name')
        session['user'] = user
        session['round'] = 1
        return redirect(url_for('game'))
    rank_list = query_db('select * from rank order by round_num desc limit 5',one=False)
    print(rank_list)
    return render_template('login.html', rank_list=rank_list)
@app.route('/game')
def game():
    if not session.get('user'):
        return redirect(url_for('index'))
    id = random.randint(1, 30000)
    idiom = query_db('select * from idiom where id = ?',
                     [id])
    return render_template('game.html', user=session.get('user'), idiom=idiom)
@app.route('/more/<user_idiom>')
def more(user_idiom):
    speak_list = pinyin(user_idiom)
    print(speak_list[0][-1])
    idiom_speak = '  '.join(map(lambda x: x[0], speak_list))
    if query_db('select * from idiom where speak = ?',
                [idiom_speak]):
        new_idiom = query_db("select * from idiom where speak like ('%s%%')" % speak_list[-1][0])
        session['round'] = session.get('round') + 1
        print({'code': 200, 'round': session.get('round'), 'info': new_idiom})
        return jsonify({'code': 200, 'round': session.get('round') + 1, 'info': new_idiom})
    else:
        query_db('replace into rank (name,round_num) values (?,?)',
                 [session.get('user'), session.get('round')])
        return jsonify({'code': 404, 'error': "挑战结束:用户输入的成语是自己编的吧!", 'url': request.host_url})

游戏演示


说了这么多,让我们来开一局:

网络异常,图片无法展示
|

游戏展示


我们使用一个Neo的新用户来进行游戏,随便接龙了几次,然后我编了一个“蝉鸣鸟叫”的成语结束这次演示,不然好好答不来个几百轮的那里能结束啊,哈哈...可以看到游戏结束后退回到首页,并进行了挑战排序。还好没几个号,不然排不到前五都看不到效果了...


手机搭建项目


既然上一篇的天气预报工程可以搭建到手机,那么这篇成语接龙,也一样来试试呗。


代码clone

代码我已经上传到了我的git仓库,手机登陆Termux直接clone下载即可:

git clone https://github.com/KingUranus/IdiomsGame.git


pipenv导入

进入clone好的代码路径,之后输入pipenv install创建虚拟环境并下载依赖的模块

键入pipenv shell 进入虚拟环境

通过flask run运行我们的Flask app程序...

网络异常,图片无法展示
|

image.png

网络异常,图片无法展示
|

image.png

网络异常,图片无法展示
|

image.png


The End


今天的Flask项目开发成语接龙游戏就到这里。



相关文章
|
2月前
|
数据库 Python
如何使用Flask进行开发?
【9月更文挑战第1天】如何使用Flask进行开发?
50 3
|
1月前
|
小程序 JavaScript API
微信小程序开发之:保存图片到手机,使用uni-app 开发小程序;还有微信原生保存图片到手机
这篇文章介绍了如何在uni-app和微信小程序中实现将图片保存到用户手机相册的功能。
558 0
微信小程序开发之:保存图片到手机,使用uni-app 开发小程序;还有微信原生保存图片到手机
|
2月前
|
移动开发 Android开发 数据安全/隐私保护
移动应用与系统的技术演进:从开发到操作系统的全景解析随着智能手机和平板电脑的普及,移动应用(App)已成为人们日常生活中不可或缺的一部分。无论是社交、娱乐、购物还是办公,移动应用都扮演着重要的角色。而支撑这些应用运行的,正是功能强大且复杂的移动操作系统。本文将深入探讨移动应用的开发过程及其背后的操作系统机制,揭示这一领域的技术演进。
本文旨在提供关于移动应用与系统技术的全面概述,涵盖移动应用的开发生命周期、主要移动操作系统的特点以及它们之间的竞争关系。我们将探讨如何高效地开发移动应用,并分析iOS和Android两大主流操作系统的技术优势与局限。同时,本文还将讨论跨平台解决方案的兴起及其对移动开发领域的影响。通过这篇技术性文章,读者将获得对移动应用开发及操作系统深层理解的钥匙。
|
3月前
|
Web App开发 Android开发
FFmpeg开发笔记(四十六)利用SRT协议构建手机APP的直播Demo
实时数据传输在互联网中至关重要,不仅支持即时通讯如QQ、微信的文字与图片传输,还包括音视频通信。一对一通信常采用WebRTC技术,如《Android Studio开发实战》中的App集成示例;而一对多的在线直播则需部署独立的流媒体服务器,使用如SRT等协议。SRT因其优越的直播质量正逐渐成为主流。本文档概述了SRT协议的使用,包括通过OBS Studio和SRT Streamer进行SRT直播推流的方法,并展示了推流与拉流的成功实例。更多细节参见《FFmpeg开发实战》一书。
64 1
FFmpeg开发笔记(四十六)利用SRT协议构建手机APP的直播Demo
|
3月前
|
SQL 缓存 数据库
神秘编程领域惊现宝藏!Flask 扩展生态究竟隐藏着怎样的神奇力量?快来揭开提升开发效率的秘密!
【8月更文挑战第31天】在 Flask 的世界里,其简洁而强大的核心框架搭配丰富多彩的扩展生态,为开发者带来了无尽可能性。从数据库集成到用户认证,从表单验证到缓存管理,Flask 提供了众多高质量插件,如 Flask-SQLAlchemy、Flask-WTF 和 Flask-Login,大幅提升了开发效率和代码质量。这些扩展如同宝库中的珍宝,等待着我们去探索和利用,但需谨慎选择以避免不必要的复杂性和性能问题。总之,Flask 的扩展生态助力我们更高效地开发 Web 应用,创造更多优秀作品。
34 0
|
3月前
|
存储 监控 开发工具
Django 后端架构开发:手机与邮箱验证码接入、腾讯云短信SDK和网易邮箱
Django 后端架构开发:手机与邮箱验证码接入、腾讯云短信SDK和网易邮箱
63 0
|
4月前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
4月前
|
API 数据库 开发者
逆袭之路!Django/Flask助你成为Web开发界的璀璨新星!
【7月更文挑战第13天】在Python Web开发中,Django和Flask各具优势。Django适合快速构建大型项目,如在线书店,其ORM和内置功能让复杂应用轻松上手。Flask则以其轻量和灵活性见长,适用于个人博客等小型应用。选择框架应根据项目需求和个人偏好,两者都能助开发者在Web开发领域大放异彩。
50 2
|
4月前
|
数据库 开发者 Python
从菜鸟到大神,Django/Flask 让你秒变 Web 开发界的‘头号玩家’!
【7月更文挑战第12天】在Python Web开发中,Django和Flask框架各具特色。Flask轻量灵活,适合快速搭建简单应用,如博客,基本代码仅需几行。Django则功能全面,适用于复杂项目,如电商网站,内置ORM和管理后台。两者都助力开发者从新手进阶。选择取决于项目需求和个人偏好。学习和实践这两个框架,能助你成为Web开发专家。
57 2
|
4月前
|
前端开发 小程序
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
409 0