# 算术棋盘生成器 **Repository Path**: BakaAic/MathBoardGenerator ## Basic Information - **Project Name**: 算术棋盘生成器 - **Description**: 生成算术棋盘图,使用线性规划生成结果 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-31 - **Last Updated**: 2025-10-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 算术棋盘生成器 #### 介绍 生成算术棋盘图,使用线性规划生成结果 #### 软件架构 Python3 #### 依赖 pulp 线性规划库 #### 功能说明 可直接生成算术棋盘图 ![输入图片说明](image.png) 修改配置可支持生成减法操作,以及可以设置结果最大范围 ![输入图片说明](image2.png) ![输入图片说明](image3.png) 可查看答案 ![输入图片说明](image4.png) 可修改生成的最大难度等级 ![输入图片说明](image5.png) #### 开发思路说明 先生成棋盘,再通过棋盘的图形连接方式,确定每一个算式的A(第一项),B(第二项),C(结果)项对应关系,然后通过添加线性规划的约束条件来生成结果,选出算式中的屏蔽项不做输出,其他的进行输出,即可完成。 棋盘生成:用二维矩阵(python可以用二维数组或者numpy的矩阵)记录棋盘的每一个信息,未生成的地方为0,已生成的地方为1,这样就可以用笛卡尔坐标来得出每个棋盘点的位置。因为是简单算式,每条算式长度总共可视为5个部分,A项,加减号,B项,等号,C项。每个算式的A,B,C位置都可能被其他算式连接,所以先确定一个初始位置点,根据初始位置点确定初始算式的位置,以算式的结束位置作为新的算式的开始点。考虑到A,B,C三个为止都可能被链接到,所以除了A,C的连接需要全长度以外,还需要考虑B位置被连接造成的半长度,所以每次生成新的算式的开始点后,都需要随机确认使用全长或半长,以及生成的方向。为了让整个算式的逻辑关系可以闭环,我们在随机生成时要考虑完成闭环后才能结束生成。如果某一个生成的图判定为完全无法生成闭环了,那么就直接放弃本次的棋盘生成,重新开始生成流程。虽然增加了计算成本,但是可以避免很多生成方向对闭环的考虑,让一切都交给混沌吧。 算式生成:其实在生成算式链之前,需要先扫描出所有的行与列,找出已经生成了图像的框的位置,获取其坐标,根据每一个算式生成一个固定长度为5的棋盘坐标,这样的坐标组因为不会重复,既可以作为后续生成图像时的坐标点位(坐标乘以格子尺寸),本身也可以作为字典的索引,用于区分每一组算式,作为算式组的抽象名称。获得未赋值的算式组后即可开始进行算式的生成,一个算式组中,实际上第四位的等号是完全无用的,而第二位的加减符号,实际上作为单独的变量加入线性规划的计算是非常低效的,这里我们其实可以考虑,a-b实际上等于a+(-b),所以只需要通过修改第三位的约束范围,就可以让它自带正负号,后续只需要通过解析第三位是否带负号就可以修改第二位的加减显示。通过线性规划生成问题后,将A,B,C项分组保存,每一组都生成长度等于算式总数的线性规划变量,然后添加A+B=C的约束,然后通过扫描所有的算式组的坐标,确定相交情况,将相交的变量做相等约束。最后给算式中的值添加若干的随机初始值作为约束以影响整个算式链。使用线性规划输出每一项的计算结果,且检查线下规划的状态,因为整个过程完全是随机的,其实有不小概率生成的结果会导致线性规划无解,所以我们可以循环整个过程,直到找到解位置,记录每一项的结果,输出给最终的算式链,此时就得到了每一个坐标信息对应的可显示值。 显示屏蔽:此时如果直接将算式全部打印,就没有计算的必要性了,所以此时我们考虑屏蔽掉部分信息。屏蔽的方式有多种,为了让生成结果完全随机,我们这里采用的其实是先给每一个算式批准一个可显示位置。为了防止可显示位置跟其他算式相交,所以优先选择没有相交的点,如果没有不想交的点的算式,那么我们直接给这个点关联的所有算式的批准计数器+1,此时虽然仍有概率出现一个算式有两个批准项(因为顺序问题),但是对于最终输出结果来讲是可以接受的。完成所有算式的可显示位置批准之后,再随机找到一个幸运儿算式,再给它增加一个批准显示位置,这样就完成了最终的显示判断。 根据以上思路,对代码修修改改缝缝补补即可完成一个粗制滥造(但是有效)的算式生成器,本思路仅为一家之言,不代表标准答案或者最有效的方式。 #### 打包方式 pulp依赖库本地的cbc.exe,如果需要打包,需要先调用本地cbc.exe ``` from pulp.apis import COIN_CMD solver=COIN_CMD(path="CBC.exe路径") ``` 替换 `status=problem.solve()` 为 `status=problem.solve(solver)` 在打包时,需要将cbc.exe一并打包