基于flask实现五子棋小游戏

yizhihongxing

下面我就来详细讲解“基于flask实现五子棋小游戏”的完整攻略。

1. 确定游戏规则

在开发五子棋小游戏之前,需要明确游戏规则。五子棋规则简述:两人轮流在棋盘上落子,黑方先行。当一方先在横、竖或斜行连续放置五个棋子时,游戏结束,该方胜利。

2. 创建项目及相关文件

在命令行下进入项目文件夹,执行以下命令创建项目:

mkdir flask_gobang
cd flask_gobang
python -m venv venv
source venv/bin/activate
pip install Flask

新建一个app.py文件,作为入口文件。如下所示:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

同时,在项目文件夹中创建templates文件夹,新建index.html文件,用于渲染网页:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>Gobang Game</title>
</head>
<body>
    <h1>Gobang Game</h1>
</body>
</html>

3. 实现页面布局

五子棋棋盘由16行16列共256个小格组成。我们需要先在index.html文件中添加一个table元素,来呈现五子棋的棋盘:

<table>
    <tbody>
    {% for i in range(16) %}
        <tr>
            {% for j in range(16) %}
                <td></td>
            {% endfor %}
        </tr>
    {% endfor %}
    </tbody>
</table>

以上代码是使用flask-templates引擎的语法,for循环来生成16*16的棋盘格子。

4. 实现落子交互

接下来,需要实现落子交互功能,即用户点击空格子,会在这个格子上出现相应的棋子。

在index.html文件中添加JavaScript代码:

<script>
function fillCell(ele, row, col) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/fill/' + row + '-' + col, true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            var json = JSON.parse(xhr.responseText);
            if (json.result) {
                ele.style.backgroundImage = 'url(' + json.src + ')';
            } else {
                alert(json.msg);
            }
        }
    };
    xhr.send();
}

document.querySelector('table').addEventListener('click', function(e) {
    var ele = e.target;
    if (ele.nodeName === 'TD' && !ele.style.backgroundImage) {
        var row = ele.parentNode.rowIndex;
        var col = ele.cellIndex;
        fillCell(ele, row, col);
    }
});
</script>

以上代码中,fillCell函数会发送GET请求,请求URL为/fill/+行-列,获得后端响应后,将图片链接填充到相应的格子中。

同时,还需要在app.py中添加路由处理:

@app.route('/fill/<string:pos>')
def fill(pos):
    row, col = [int(i) for i in pos.split('-')]
    status, msg, filename = gobang.fill(row, col)
    return jsonify({'result': status, 'msg': msg, 'src': url_for('static', filename=filename)})

以上代码中,/fill/路由接收前端发送的请求,调用gobang.fill函数进行逻辑处理,返回JSON格式的数据。

5. 实现游戏逻辑

游戏的核心逻辑在gobang.py中实现。可以调用Python面向对象思想,实现类的编写。如下所示:

import os
import uuid

from PIL import Image, ImageDraw, ImageFont


UP, DOWN, LEFT, RIGHT, LEFT_UP, LEFT_DOWN, RIGHT_UP, RIGHT_DOWN = range(8)

class Gobang:
    ...

以上代码定义了一个Gobang类,用于实现游戏逻辑。可以看到,这个类的变量和函数还没有定义,下面我们进行逐个定义。

5.1 初始化函数

需要首先定义类的初始化函数,完成游戏的初始化:

def __init__(self, size=16, win=5):
    self.size = size  # 棋盘大小
    self.win = win    # 需要连成的棋子数

    self.turn = 0    # 当前轮到哪一方落子

    # 初始化棋盘
    self.board = []
    for i in range(size):
        self.board.append(['' for j in range(size)])

    # 初始化和配置字体
    self.font = ImageFont.truetype(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'DroidSans-Bold.ttf'), 64)

    # 创建存储棋子的文件夹
    self.img_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'img')
    if not os.path.exists(self.img_folder):
        os.makedirs(self.img_folder)

    # 初始化连续棋子的数量
    self.count = [[0 for j in range(size)] for i in range(size)]

以上变量的说明:
- size:棋盘大小。
- win:需要连成的棋子数。
- turn:轮到哪一方落子。0代表黑子,1代表白子。
- board:数组,表示棋盘状态。
- font:字体对象,用于绘制棋子编号。
- img_folder:字符串,表示存储棋子的文件夹路径。
- count:二维数组,表示每个点上已连续的棋子数。

5.2 其他函数

除了初始化函数之外,还需要定义其他函数,用于实现游戏的各种功能。这里我们分别介绍这些函数。

5.2.1 get_next_pos函数

get_next_pos函数用于实现AI的落子。我们可以通过枚举棋子周围的空格子,计算每个空格子对应的得分,并选取得分最高的空格子作为AI的落子点。如下所示:

def get_next_pos(self):
    scores = []
    for i in range(self.size):
        for j in range(self.size):
            if self.board[i][j] == '':
                score = 0
                for direction in range(8):
                    score += self.get_score(i, j, direction)
                scores.append(((i, j), score))
    scores.sort(key=lambda x: x[1], reverse=True)
    return scores[0][0]

以上代码中,计算得分的代码是使用get_score函数来实现的,我们将在后面介绍这个函数。

5.2.2 get_score函数

get_score函数用于计算当前空格子在棋盘上连续棋子数的得分。具体实现如下:

def get_score(self, row, col, direction):
    score = 0
    # 按照给定的方向进行遍历
    for delt_row, delt_col in self.get_directions(direction):
        cur_row, cur_col = row + delt_row, col + delt_col
        if cur_row >= self.size or cur_col >= self.size or cur_row < 0 or cur_col < 0 or self.board[cur_row][cur_col] != self.get_turn():
            continue
        score += 1
        while True:
            cur_row, cur_col = cur_row + delt_row, cur_col + delt_col
            if cur_row >= self.size or cur_col >= self.size or cur_row < 0 or cur_col < 0 or self.board[cur_row][cur_col] != self.get_turn():
                break
            score += 1
        if cur_row >= self.size or cur_col >= self.size or cur_row < 0 or cur_col < 0 or self.board[cur_row][cur_col] != '':
            continue
        if score + 1 >= self.win:
            return (10 ** score + 1) * (10 ** (self.win - score))
        score = 0
    return score

以上代码中,get_turn函数用于获取当前轮到哪一方落子。get_directions函数返回横、竖、斜向八个方向的偏移量。

5.2.3 fill函数

fill函数用于获取玩家的落子,同时也会调用AI的落子函数。具体实现如下:

def fill(self, row, col):
    if self.board[row][col] != '':
        return False, '此处已经有棋子了!', ''
    filename = str(uuid.uuid4().hex) + '.png'
    if self.turn == 0:
        self.board[row][col] = 'B'
        self.draw_chessman('BLACK', os.path.join(self.img_folder, filename))
    else:
        self.board[row][col] = 'W'
        self.draw_chessman('WHITE', os.path.join(self.img_folder, filename))
    self.count[row][col] = 1
    if self.check_win(row, col):
        return True, '你赢了!', filename
    self.turn = 1 - self.turn
    if self.turn == 1:
        next_pos = self.get_next_pos()
        self.fill(*next_pos)
    return True, '', filename

以上代码中,在玩家落子的时候,会根据当前轮到哪一方落子,记录下棋子的类型,并保存棋子图片到本地文件夹。之后检查该次落子是否导致获胜,如果是,则返回胜利信息和图片链接;否则,切换轮到哪一方,并调用AI落子函数。

5.2.4 check_win函数

check_win函数用于检测当前棋盘上是否已经有一方胜利。实现方式即枚举当前落子位置周围的八个方向,计算连串棋子的数量。如果数量>=win,那么返回True,代表已经有一方胜利;否则返回False,代表游戏未结束。具体实现如下:

def check_win(self, row, col):
    for direction in range(8):
        if self.get_score(row, col, direction) >= self.win:
            return True
    return False

以上就是实现五子棋小游戏的全部代码了。

6. 运行游戏

除了上述介绍的代码之外,还需要在运行前添加部分参数和代码。需要在app.py文件中添加如下代码:

from gobang import Gobang

gobang = Gobang(size=16, win=5)

同时,需要在app.run之前添加如下一行:

app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

这是为了防止静态资源缓存。代码添加完成后,运行命令如下:

python app.py

最后在浏览器中输入localhost:5000即可进入五子棋小游戏页面。

示例1:玩家落子

当玩家落子时,会在该处显示相应的棋子,并标注棋子编号信息。当玩家连成5个棋子时,页面会提示玩家获胜,并弹出相关对话框。

示例2:AI落子

当AI落子时,页面会出现相应的棋子,并标注棋子编号。如果AI连成5个棋子,则页面会提示AI获胜,并弹出相关对话框。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于flask实现五子棋小游戏 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • python爬取NUS-WIDE数据库图片

    下面为您介绍“python爬取NUS-WIDE数据库图片”的完整攻略,包含两条示例说明。 简介 NUS-WIDE是一个包含269,648张图片的数据库,图片来源于Flickr社交网站。这些图片被手工标注为38个不同的标签。这个数据库可以用于图像检索、多标签分类、语义注释等领域的研究。 在使用NUS-WIDE数据库进行研究时,我们通常需要把图片下载到本地。本文…

    Flask 2023年5月15日
    00
  • Flask框架利用Echarts实现绘制图形

    下面我将为您详细讲解“Flask框架利用Echarts实现绘制图形”的完整攻略。 安装Flask和Echarts 首先,我们需要安装Flask和Echarts。可以通过Python的包管理工具pip进行安装。 pip install Flask Echarts 创建Flask应用程序 我们可以通过Flask框架来创建一个Web应用程序,可以通过以下Pytho…

    Flask 2023年5月16日
    00
  • 详解Flask数据库的连接与使用

    为了详细讲解Flask数据库的连接与使用的攻略,我们需要分为以下几个步骤: 1. 安装Flask扩展 在使用Flask之前,我们需要先安装一些必要的扩展。对于连接数据库来说,常用的扩展是Flask-SQLAlchemy和Flask-MySQLdb。 pip install flask_sqlalchemy pip install flask-mysqldb …

    Flask 2023年5月15日
    00
  • 详解 python logging日志模块

    详解 Python logging 日志模块 简介 Python logging 模块是一个强大且灵活的记录日志的模块,它允许你在你的 Python 应用程序中执行大规模的日志记录,并在日志消息的不同级别中进行分类和过滤。使用 Python logging 模块可以有效地记录调试信息、错误和异常信息、警告、信息等。 Python logging 模块支持以下…

    Flask 2023年5月16日
    00
  • Flask框架debug与配置项的开启与设置详解

    让我详细讲解一下“Flask框架debug与配置项的开启与设置详解”的完整攻略。这篇攻略将分为两部分:一是debug模式的开启与设置,二是Flask配置项的介绍与设置。 一、Debug模式 1.1 Debug模式的作用 Debug模式是Flask框架中非常重要的一项功能,它可以帮助我们快速定位到出现错误的代码,并提示出错原因。在开发阶段中,通常都会开启Deb…

    Flask 2023年5月16日
    00
  • flask框架单元测试原理与用法实例分析

    Flask框架单元测试原理与用法实例分析 什么是单元测试 在软件开发中,单元测试指的是对软件中的最小可测试单元进行验证和检测的过程。最小可测试单元通常是一个函数或方法。它的目的是确保这个单元的行为符合预期并且它们在被改进之后不会破坏原有的功能。 单元测试通常是自动化的,意味着测试用例是在没有人工干预的情况下执行的。每个测试用例只测试一个特定的行为,并且不依赖…

    Flask 2023年5月15日
    00
  • 5分钟教会你用Docker部署一个Python应用

    下面我将提供一个完整的攻略,教会你如何用 Docker 部署一个 Python 应用。 第一步:安装 Docker 首先,你需要在你的机器上安装 Docker。在这里,我提供两种安装方式。 方式一:通过官方安装脚本进行安装 可以通过 Docker 官方网站提供的安装脚本进行安装。在终端中输入以下命令: curl -sSL https://get.docker…

    Flask 2023年5月16日
    00
  • 使用Python FastAPI构建Web服务的实现

    使用Python FastAPI构建Web服务的实现可以分为以下步骤: 1. 安装FastAPI FastAPI是一个基于Python的Web框架,提供了快速、简单和易于使用的方式来构建Web API。您可以使用以下命令在Python环境中安装FastAPI: pip install fastapi 2. 安装uvicorn uvicorn是一个Python…

    Flask 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部