基于flask实现五子棋小游戏

下面我就来详细讲解“基于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日

相关文章

  • JQuery异步post上传表单数据标准化模板

    JQuery异步post上传表单数据标准化模板是一种常用的前端技术。本攻略将详细讲解此过程,并提供两条示例说明。具体步骤如下: 一、设置请求 url 和 data 请求 url 可以指向一个后台处理请求的页面。 data 是现有表单的序列化数据和其他要提交的数据的对象。对象的主要属性应与表单中的输入字段的“name”属性匹配。 二、设置异步ajax请求 设置…

    Flask 2023年5月16日
    00
  • Flask之flask-script模块使用

    下面是关于“Flask之flask-script模块使用”的完整攻略,包含两个示例说明。 什么是 Flask-Script 模块? Flask-Script 是 Flask 外部扩展库之一,它提供了一组命令行快捷方式,可用于管理应用程序的各种任务,例如初始化数据库、运行开发 web 服务器,等等。Flask-Script 使命令行交互更加方便。 安装 Fla…

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

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

    Flask 2023年5月15日
    00
  • python异步Web框架sanic的实现

    我可以给您提供一份“python异步Web框架sanic的实现”的攻略,其中包含以下几个方面的内容: Sanic是什么 Sanic的特点和优势 Sanic的应用场景 Sanic的实现流程及示例说明 1. Sanic是什么 Sanic是一个使用Python编写的异步Web框架,它在异步I/O操作上表现非常出色,是一个非常优秀的异步Web框架。 2. Sanic…

    Flask 2023年5月16日
    00
  • python的flask框架难学吗

    Python的Flask框架是一个用于web应用程序开发的微框架,它拥有简洁的代码结构,易于学习和使用。而对于初学者而言,学习一门新技术是有难度的,但对于Flask框架而言,它并不难学。下面,我将为您提供详细的攻略。 一、Flask框架的安装 Flask框架的安装十分便捷,您可以通过以下命令行进行Flask框架的安装: pip install Flask 在…

    Flask 2023年5月16日
    00
  • Python3创建Django项目的几种方法(3种)

    下面给你详细讲解Python3创建Django项目的几种方法。 方法一:使用django-admin.py 安装 Django,使用 pip install Django 命令进行安装。 在终端中输入 django-admin.py startproject projectname,其中 projectname 为你要创建的项目名称。 在终端中输入 cd p…

    Flask 2023年5月16日
    00
  • Vue+Flask实现简单的登录验证跳转的示例代码

    下面是“Vue+Flask实现简单的登录验证跳转的示例代码”的完整攻略,包含两个示例说明。 示例一 前端部分(Vue) 在前端部分,我们需要使用 axios 进行登录请求。登录成功后我们将会在 cookie 中存储 token,以便随后的访问都可以带上该 token。 <template> <form> <input v-mod…

    Flask 2023年5月16日
    00
  • python flask 如何修改默认端口号的方法步骤

    想要修改Python Flask默认端口号,需要对Flask应用程序进行一些修改。最常见的方法是使用命令行选项,但也有其他方法。下面是介绍两种常用的修改Flask默认端口的方法。 方法一:使用命令行选项 您可以通过使用命令行选项来轻松地为Flask应用程序指定一个不同的端口。只需在启动应用程序时添加–port参数并指定端口号即可。 示例1:将默认端口修改为…

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