发作品签到
专业版

#第九届立创电赛#三子棋人机对弈游戏装置

工程标签

2.9k
0
0
11

简介

三子棋游戏装置集合了电子技术、机械工程、算法开发等方面的综合能力,为三子棋这一经典游戏带来了全新的体验。

简介:三子棋游戏装置集合了电子技术、机械工程、算法开发等方面的综合能力,为三子棋这一经典游戏带来了全新的体验。
复刻成本:350

开源协议

GPL 3.0

创建时间:2024-08-28 14:22:09更新时间:2024-08-29 11:04:51

描述

* 1、项目功能介绍


  本设计以STM32F103C8T6单片机为主控模块,设计了主要包含龙门架控制、树莓派5、A4988电机驱动模块、对弈算法策略、人机交互的运三子棋下棋装置。通过树莓派5运行Opencv各种算法进行视觉处理获得棋盘各个分区的位置以及棋局情况;采用双步进电机控制使精度更准确;三自由度龙门架更有利于电磁铁的运动。以此可实现电磁铁沿着X、Y轴方向的运动,对棋子进行吸取、放置。

 

 

*2、项目属性


  • 首次公开:该项目为原创作品。
  • 获奖情况:该项目在2024年全国大学生电子设计竞赛中获一等奖。
  • 答辩情况:该项目未曾在学校进行过答辩。

 

* 3、开源协议


GPL 3.0

 

*4、硬件部分


4.1 系统结构

将系统分为4个基本模块,包括主控模块、电控模块、视觉模块、电磁铁模块。

 

4.1.1 主控模块

  • STM32F103C8T6单片机。

 

4.1.2 电控模块

使用42步进电机与A4988驱动器。

  • 在写字机的机械结构加持下,步进电机与A4988驱动器具有较高的定位精度和控制精度,可以以精确的步进角度进行旋转。

 

4.1.3视觉模块

使用树莓派和Opencv。

  • 树莓派较强的CPU和GPU,可以处理复杂的数据和算法。这对于棋盘识别和棋子位置跟踪是重要的。
  • 功耗和散热:相比于OpenMV,树莓派在长时间运行时更好的散热措施使得其更稳定。

对于棋子对弈项目,需要进行实时的图像处理和棋子位置的精确识别,树莓派拥有强大处理能力和灵活性使其能够处理更复杂的图像识别算法,是一个好的选择。

 

4..1.4电磁铁模块

使用了12v的直流小型电磁铁,需要搭配继电器与铁块使用,才能实现棋子的吸取与放置操作。

  • 棋子是3d打印出来的,里面嵌有铁块,这个建模还是比较简单的,stl文件在附件。
  • 电磁铁某宝买的,链接放附件里了,到手后直接替换写字机上笔的位置即可。
  • 继电器就常见的那种红色的模块,给单片机IO口控制电磁铁通断用的。

 

4.2机械结构

为了节省时间追求效率,直接借用了写字机结构。

参考了大鱼写字机 https://www.bilibili.com/video/BV1Uh411Q7Zp/?spm_id_from=333.337.search-card.all.click&vd_source=89520820644971ec7d61e2c478052304

大鱼DIY有全套资料分享,有清单,有固件, 有三维模型,有STL文件, 还有绿色的EXE软件可以直接查看写字机的三维模型。很适合新手复刻。 

 

完成这个项目的背景是:处于四天三夜的全国电赛比赛环境。所以有飞线,有全局打胶,有各种不美观和混乱,因为要带着它奔波去评测,所以只考虑了实用和效率,见谅。

我觉得对于这个项目,重点在软件部分,硬件部分只需要做出来写字机结构就大差不差了,比赛的时候我也是各种模块的堆积,都是比较简单的,主要是为了快速实现功能。

 

4.3控制板原理图

模块的堆积,求放过。有个提醒就是,实际控制了三个步进电机,两个用来控制xy轴运动,一个用来控制电磁铁的升降,所以画原理图的时候记得加上去一个,因为当时在比赛,没时间重新打板子,就直接飞线了

 

 

*5、软件部分(详细代码文件已全部上传在附件)

5.1人机对弈基本算法思想

  • 极小化极大(minimax)算法顾名思义,就是让最大得情况最小,这里的最大一般是指最差的情况,比如游戏中最不利的情况。
  • 该算法需要满足零和博弈,初略的解释就是若有两个玩家进行游戏,如果其中一方得到利益那么另一方就会失去利益,游戏利益的总和为0(某些情况下为常数)。
  • 因此,零和的约束条件也使得该算法在很多游戏中图体现出很好的效果,比如大多数的棋类游戏。
  • 其实说白了,这个算法就是一个树形结构的递归算法,每个节点的孩子和父节点都是对方玩家,所有的节点被分为极大值(我方)节点和极小值(对方)节点。是一种找出失败的最大可能性中的最小值的算法。

    // minimax算法:评估当前棋盘的最佳得分
    int minimax(int board[9], int depth, bool isMax) {
        int score = checkwin(board);
        if (score == 1) return -10 + depth;  // 黑棋胜,返回负分
        if (score == 2) return 10 - depth;   // 白棋胜,返回正分
        if (!isMovesLeft(board)) return 0;   // 平局

        if (isMax) {
            int best = -1000;
            for (int i = 0; i < 9; i++) {
                if (board[i] == 0) {
                    board[i] = 2;
                    int moveVal = minimax(board, depth + 1, false);
                    board[i] = 0;
                    if (moveVal > best) {
                        best = moveVal;
                    }
                }
            }
            return best;
        } else {
            int best = 1000;
            for (int i = 0; i < 9; i++) {
                if (board[i] == 0) {
                    board[i] = 1;
                    int moveVal = minimax(board, depth + 1, true);
                    board[i] = 0;
                    if (moveVal < best) {
                        best = moveVal;
                    }
                }
            }
            return best;
        }
    }

 

5.2 STM32思想

  • 驱动电机:通过 STM32 的 PWM 输出来控制步进电机的转动,进而对三子棋装置进行运动控制。
  • 运动控制算法:位置控制:无。速度控制:无。
  • 步进电机拥有优秀的开环能力。通过多次测试发现,三子棋装置在运行中没有出现步进电机丢步的情况,因此没有加入控制算法,降低了程序方面的难度。
  • 串口通信:STM32端通过串口通信接收来自树莓派对棋盘实时状况处理过后的数据。树莓派和32端串口配置要保持一致,避免通信异常。
    基础的PWM,定时器,串口等模式具体配置就不多说了,也没啥特别的地方,附件里下载全部代码。
  • 路径规划与决策:装置接收到指令后,需要控制棋子移动到不同的位置,设计合理的路径规划以及决策算法,使用minimax算法评估当前棋盘的最佳得分,寻找当前棋盘状态下装置的最佳移动,以确保装置能够按照最优路径和最优决策移动。

    给该函数输入棋盘的状况(以数组形式),该函数会返回电脑下一步的最佳移动位置。

    // 寻找当前棋盘状态下电脑的最佳移动
    int findBestMove(int board[9]) {
        int gameStatus = checkwin(board);
        if (gameStatus != -1) {
            if(gameStatus == 0)return 99;// 游戏已经结束,无需继续寻找最佳移动
            if(gameStatus == 1)return -11; 
            if(gameStatus == 2)return 9;
        }

        int bestVal = -1000;
        int bestMove = -1;
        for (int i = 0; i < 9; i++) {
            if (board[i] == 0) {
                board[i] = 2;
                int moveVal = minimax(board, 0, false);
                board[i] = 0;
                if (moveVal > bestVal) {
                    bestMove = i;
                    bestVal = moveVal;
                }
            }
        }
        return bestMove;
    }

    通过以下四个函数,即可计算出三子棋电脑的最佳移动位置。
  • 用户交互:反馈机制:在人机博弈的过程中,通过OLED屏幕和LED灯为用户提供实时反馈,例如通过LED灯来显示装置的下棋状态。
  • 安全控制:软限位保护,代码里设置了电机的运动范围限制,防止电机超出安全范围造成的装置损坏。也可以通过硬件方面加入限位开关对运动范围进行限制。

 

5.3 树莓派opencv算法思想

树莓派端代码实现了一个图像处理系统,用于识别棋盘的旋转角度和棋盘上的棋子位置和颜色,并通过串口发送数据给另一个设备(STM32)。

Pi文件包里有两个文件,README和Python代码,都标明了步骤和注释说明,这里也不过多赘述了,附件里下载全部代码



以下是主要算法思想总结:

1.初始化:

  • 初始化串口通信。
  • 配置并启动树莓派摄像头模块(Picamera2)以获取视频流。

 

2.棋盘角度检测模式:

  • 类似于棋子识别,但寻找的是整个棋盘的大轮廓。
  • 计算找到的轮廓的旋转角度,并通过串口发送这个角度信息。

   
3. 棋盘识别定位:

  • 从摄像头获取一帧图像,并调整图像大小。
  • 图像预处理:灰度化、高斯模糊、Canny边缘检测和形态学闭运算。
  • 查找轮廓并筛选出近似为矩形的轮廓,这些轮廓代表棋盘上的格子。
  • 对找到的矩形格子进行排序,并在图像上标记它们的位置。
  • 转换到棋子颜色识别,在此模式下继续处理图像以识别棋子。

 

4. 棋子颜色识别:

  • 在每个已标记的格子中心点周围获取颜色信息。
  • 分析这些颜色,确定最可能的颜色域,并将结果存储起来。
  • 调整颜色识别结果的顺序以匹配棋盘布局。
  • 通过串口发送颜色信息。

 

5. 异常处理与退出条件:

  • 捕获并打印异常。
  • 按下键盘上的‘q’键可退出程序。
  • 清理释放OpenCV使用的资源。

该程序利用视觉实现了对棋盘上棋子位置和颜色的自动识别,并能检测整个棋盘的角度,以便下棋装置能够准确地放置或移动棋子。

 

 

*6、BOM清单


附件可下载

 

*7、大赛LOGO验证


 

 

 

* 8、演示您的项目并录制成视频上传


 

视频要求:请横屏拍摄,分辨率不低于1280×720,格式Mp4/Mov,单个视频大小限100M内;

视频标题:立创电赛:{项目名称}-{视频模块名称};如立创电赛:《自动驾驶》-团队介绍。

 

前往查看更多详情 >

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
棋盘.pdf
18
2
结构件采购清单.xlsx
14
3
代码.zip
58
4
棋子6mm.stl
28
5
BOM.xlsx
13
克隆工程
添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航