斗地主记牌器的开发

7 天前
 dhuzbb

起源

周末经常和同事一起玩 JJ 斗地主,每局输赢不大,主要以娱乐为主。由于经常输,所以萌生了开发一款记牌器来偷偷提升斗地主水平的想法。

我的本职工作是 Java 后端开发,没有接触过安卓开发,再加上最近 AI 编程的火热,让我萌生了使用 Cursor 开发一款安卓应用的想法。

思路

主要思路:如果能够每隔 1 秒截取到当前手机屏幕的内容,然后识别出截图中的所有牌张的点数及花色,那么用 54 张牌直接减去对应的牌张及花色即可得到剩余的牌张。

实现的困难点在于,不仅要识别牌的点数,还需要识别牌的花色。

因为如果只是单纯的识别牌的点数而不考虑花色,那么会产生 Bug 。

例如:先出黑桃 2 ,再出红桃 2 ,等了 3 秒后再出其它牌。由于出牌时间不是固定的,在这期间每隔 1 秒识别截图会重复识别多次牌张 2 ,导致剩余牌张数不准确。

如果同时识别牌的点数及花色,则不会出现重复多次扣减同样牌张的问题。

UI 设计

记牌器 UI 的主体借鉴了 JJ 斗地主自身的记牌器。

应用主界面如下:

由于是自己使用,所以界面做得比较简单,主界面只有一个 [开启记牌器] 按钮。点击后该按钮会变成 [结束记牌器] 。

点击 [开启记牌器] 按钮,会弹出系统屏幕录制权限,可以只录制单个应用,也可以全局录制整个屏幕。如下所示:

点击 [开始] 按钮,会在当前页面显示记牌器悬浮窗,如下所示:

整个悬浮窗由三部分组成:

点击右侧 [开始] 按钮后,开始一局的录制,同时按钮会变为 [结束] 按钮。

整个悬浮窗可以全局灵活的自由拖动:

悬浮窗还可以显示和隐藏:

记牌器显示在桌面的效果如下:

记牌器在 JJ 斗地主游戏界面显示如下:

UI 开发

期间一共开发了三个版本:

图像识别

记牌器的技术难点在于图像识别。

前期通过调研,得知 OpenCV 可以实现图像识别,并且网上可以搜索到相应的代码示例,再加上 OpenCV 有对应的 Java 包,所以优先选择了 OpenCV 来开发图像识别功能。

通过 ChatGPT 以及 DeepSeek 的辅助,花费了不少时间开发出了第一版的 OpenCV 识别算法。

核心思路大致是:

测试过程中发现 OpenCV 的识别效果不太理想,容易出现识别错误以及漏识别的问题。

对于记牌器应用来说,是不能容忍任何的漏记以及错误识别的,必须想办法提高识别的精度。

深度学习

OpenCV 的模版匹配方案还有另外 2 个致命的问题:

既然 OpenCV 存在致命的缺陷,所以不得不推倒重来。

又是新的一轮咨询 ChatGPT 以及 DeepSeek ,得到了可以通过基于深度学习框架 YOLO 来提高图像识别的准确度。

大致看了一下官网文档,看上去比较容易上手。

整体大致流程:

有了 AI 的详细指导,整个过程基本上都比较顺畅。使用 Google 免费的 Colab 很快就训练出了第一版模型。然而最终验证的识别效果还是不太理想,还是存在漏记和错记的情况。

最后得知原因在于训练的数据集太小(手动截图并标注了几十张训练图)。想要识别效果比较理想,一般的 YOLO 训练集的大小规模在几千到上万张左右。

由于手动一张张截取手机屏幕并标注,消耗的时间实在是太长了。为了解决训练集不足的问题,最后不得不写了一个程序,根据截图模版随机生成了一万张图片以及对应的 YOLO 标注文件用于训练。

当训练集规模到了一万张的时候,预计模型训练花费的时间会达到几个小时,Google 免费的 Colab 有运行时间的限制条件,无法再满足训练的需求,不得不考虑租用 GPU 服务器。

综合对比之下,最后采用了阿里云的 GPU 服务器。配置为 16G 显存的 V100 显卡。非常幸运的是,新用户前 100 个小时有很大的优惠折扣,折合 2 块/小时左右,实在是太划算了。

在阿里云上总共的训练时长不到 3 个小时。最后,识别精度意外的好,每张牌都能到达 0.98-0.99 的准确度,实际体验下来没有遇到过错记或漏记的情况。

整合

将训练好的图像识别模型与 UI 整合起来有两种方式:

方案 1 的缺点就是需要额外的服务器进行部署,且依赖网络传输截图数据。

方案 2 我个人没有尝试过,但看 ChatGPT 给出来的代码示例,感觉也许应该是可行的吧。有空会尝试一下方案 2 ,不清楚移动设备的识别效率会怎样。

由于难易程度的关系,我采用了方案 1 。通过 ChatGPT 给出的 Python 调用模型进行识别的方式,很容易就对外暴露了一个识别 API 接口供安卓 UI 调用。

最后在家里的 M4 Mac Mini 上部署之后,达到了非常完美的识别效果。

思考和总结

经常在网上看到一些所谓的完全不懂编程,我竟然 4 小时靠 AI 复刻出月入$600k 的 APP 的同款的营销文章和视频。说实话,我个人是非常反感这类文章和视频的。

从我个人的亲身体验来看,现阶段的 AI 还只能用于辅助开发。AI 的知识储备确实非常丰富,能够带领你尝试你从未涉及的领域。但是,往往由于个人本身所掌握的知识的局限性,遇到特定的问题的时候,依靠 AI 往往很难解决。

另一个方面,AI 很容易犯错。我记得让 ChatGPT 给出使用 SpringBoot 实现直接调用训练好的 YOLO 模型的时候,AI 很快给出了一段看上去像模像样的 Java 代码并贴心的给出了 Maven 依赖包。当你按照 AI 的指导写好所有代码的时候,你会惊奇的发现,Maven 包实际上并不存在,完全是 AI 瞎编造出来的,包括那些像模像样的实现代码也是一样。当你质问 AI 给出的 Maven 依赖包为何不存在的时候,只会得到 一句抱歉。

然而即使现阶段的 AI 在使用上还有着各种各样的缺陷,我对未来的 AI 编程还是抱有期望的。对比几年前,AI 的提升无疑是巨大的。这些改进和提升在往后的几十年中还会不断的上演,甚至呈现指数级的增长,直到实现普通人都能够轻松使用的真正的 AI 。

3864 次点击
所在节点    分享创造
36 条回复
1zh3n
7 天前
感谢分享👍
speedmancs
7 天前
AI 对于完全没有编程基础的小白作用不是太大。但对于有一定编程经验的人来说,AI 还是不错的,至少会给你一个大致的方向。
ASpiral
7 天前
通过图像识别记牌,每隔一秒就把图片发给后台识别,开销是不是有点大…能不能通过数据拦截获取牌面数据来记牌?
dhuzbb
7 天前
@ASpiral 破解加密数据的难度想想就不太可能吧
justdoitzZ
7 天前
非常好的分享,花了很多时间,也做出来一些成果,期待继续开发哈哈哈哈,我也深度 cursor 用户,感觉和提问人的方式和水平有很大关系
leic4u
7 天前
不跟你打牌了,哼!
as9567585
7 天前
这个有意思~~
None2
7 天前
不错,将自己的需求实现出来
canxin
7 天前
为啥不直接开发一个带记牌器功能的斗地主?(八成已经有了,估计还不少,但是你可以无广告)
sillydaddy
7 天前
感谢分享,非常翔实的分享!
towser
7 天前
你光训练模型都花了 3 个多小时,怎么可能「我竟然 4 小时靠 AI 复刻出月入$600k 的 APP 的同款的营销文章和视频」。

如果 YOLO 导出的 ONNX 模型不大,是可以部署到手机上本地推理的。你的模型大概多大体积?
CSGO
7 天前
能否再加入训练的 AI ,能直接提醒如何出牌胜率最高。
wanniwa
7 天前
@canxin 当然是想自己有记牌器别人没有啦,都有还有啥意思
dvbs2000
7 天前
我觉得记牌器倒是容易实现。 难的是逻辑推理三方的牌面。

比如通过上下家的出牌顺序,和记牌器的情况,可以很准确判断三家手牌
通过 AI 达到百战百胜效果

这个如果做的好,才有点意思
crab
7 天前
facebook47
7 天前
看来你还是打的太少了,我打牌自动就把牌记住了,没有可能会刻意,过了一遍就自动记住了
dhuzbb
7 天前
@facebook47 那你是大神,很多职业选手比赛场都无法记全牌。
fuzzsh
7 天前
为什么要识别花色?斗地主又不分花色的大小
记录寻到的点数和定位,不同就写入,相同就不写
寻到自己出牌就当一轮,然后刷新上面的循环

这点不用上模型吧。。都是规整的图像,有点杀鸡用牛刀

创意还是不错。
facebook47
7 天前
@dhuzbb 这样的嘛,主要是斗地主只有 34 张暗牌,所以并不难记🤣🤣🤣我不是大神,不过确实🈶QQ 斗地主的斗地主之圣的称号😅😅😅
dhuzbb
7 天前
@fuzzsh 说实话有点没有看懂你的思路,上面有写为什么要识别花色。使用模型主要是为了能够做得更加通用化一点,适配不同手机的不同分辨率,以及不同的斗地主游戏。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://yangjunhui.monster/t/1129288

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX