当前位置:首页 > 经验 >

欢乐器教程(十大最简单的自学乐器)

来源:原点资讯(www.yd166.com)时间:2022-10-28 08:54:19作者:YD166手机阅读>>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接:

https://blog.csdn.net/hhladminhhl/article/details/119304504

前言

最近在网上看到一个有意思的开源项目,快手团队开发的开源AI斗地主——DouZero。今天我们就一起来学习制作一个基于DouZero的欢乐斗地主出牌器,看看AI是如何来帮助我们斗地主,赢欢乐豆,实现财富自由的吧!

首先一起来看看AI斗地主出牌器的效果:

欢乐器教程,十大最简单的自学乐器(1)


下面,我们开始介绍这个AI出牌器的制作过程。

一、核心功能设计

首先我们这款出牌器是基于DouZero开发的,核心是需要利用训练好的AI模型来帮住我们,给出最优出牌方案。

其次关于出牌器,先要需要确认一个AI出牌角色,代表我们玩家自己。我们只要给这个AI输入玩家手牌和三张底牌。确认好地主和农民的各个角色,告诉它三个人对应的关系,这样就可以确定队友和对手。我们还要将每一轮其他两人的出牌输入,这样出牌器就可以根据出牌数据,及时提供给我们最优出牌决策,带领我们取得胜利!

那么如何获取三者之间的关系呢?谁是地主?谁是农民?是自己一人作战还是农民合作?自己玩家的手牌是什么?三张底牌是什么?这些也都需要在开局后确认好。

拆解需求,大致可以整理出核心功能如下:

UI设计排版布局

  • 显示三张底牌
  • 显示AI角色出牌数据区域,上家出牌数据区域,下家出牌数据区域,本局胜率区域
  • AI玩家手牌区域
  • AI出牌器开始停止

手牌和出牌数据识别

  • 游戏刚开始根据屏幕位置,截图识别AI玩家手牌及三张底牌
  • 确认三者之间的关系,识别地主和农民角色,确认队友及对手关系
  • 识别每轮三位玩家依次出了什么牌,刷新显示对应区域

AI出牌方案输出

  • 加载训练好的AI模型,初始化游戏环境
  • 每轮出牌判断,根据上家出牌数据给出最优出牌决策
  • 自动刷新玩家剩余手牌和本局胜率预测
二、实现步骤1. UI设计排版布局

根据上述功能,我们首先考虑进行简单的UI布局设计,这里我们使用的是pyqt5。核心设计代码如下:

def setupUi(self, Form): Form.setObjectName("Form") Form.resize(440, 395) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(9) font.setBold(True) font.setItalic(False) font.setWeight(75) Form.setFont(font) self.WinRate = QtWidgets.QLabel(Form) self.WinRate.setGeometry(QtCore.QRect(240, 180, 171, 61)) font = QtGui.QFont() font.setPointSize(14) self.WinRate.setFont(font) self.WinRate.setAlignment(QtCore.Qt.AlignCenter) self.WinRate.setObjectName("WinRate") self.InitCard = QtWidgets.QPushButton(Form) self.InitCard.setGeometry(QtCore.QRect(60, 330, 121, 41)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(14) font.setBold(True) font.setWeight(75) self.InitCard.setFont(font) self.InitCard.setStyleSheet("") self.InitCard.setObjectName("InitCard") self.UserHandCards = QtWidgets.QLabel(Form) self.UserHandCards.setGeometry(QtCore.QRect(10, 260, 421, 41)) font = QtGui.QFont() font.setPointSize(14) self.UserHandCards.setFont(font) self.UserHandCards.setAlignment(QtCore.Qt.AlignCenter) self.UserHandCards.setObjectName("UserHandCards") self.LPlayer = QtWidgets.QFrame(Form) self.LPlayer.setGeometry(QtCore.QRect(10, 80, 201, 61)) self.LPlayer.setFrameShape(QtWidgets.QFrame.StyledPanel) self.LPlayer.setFrameShadow(QtWidgets.QFrame.Raised) self.LPlayer.setObjectName("LPlayer") self.LPlayedCard = QtWidgets.QLabel(self.LPlayer) self.LPlayedCard.setGeometry(QtCore.QRect(0, 0, 201, 61)) font = QtGui.QFont() font.setPointSize(14) self.LPlayedCard.setFont(font) self.LPlayedCard.setAlignment(QtCore.Qt.AlignCenter) self.LPlayedCard.setObjectName("LPlayedCard") self.RPlayer = QtWidgets.QFrame(Form) self.RPlayer.setGeometry(QtCore.QRect(230, 80, 201, 61)) font = QtGui.QFont() font.setPointSize(16) self.RPlayer.setFont(font) self.RPlayer.setFrameShape(QtWidgets.QFrame.StyledPanel) self.RPlayer.setFrameShadow(QtWidgets.QFrame.Raised) self.RPlayer.setObjectName("RPlayer") self.RPlayedCard = QtWidgets.QLabel(self.RPlayer) self.RPlayedCard.setGeometry(QtCore.QRect(0, 0, 201, 61)) font = QtGui.QFont() font.setPointSize(14) self.RPlayedCard.setFont(font) self.RPlayedCard.setAlignment(QtCore.Qt.AlignCenter) self.RPlayedCard.setObjectName("RPlayedCard") self.Player = QtWidgets.QFrame(Form) self.Player.setGeometry(QtCore.QRect(40, 180, 171, 61)) self.Player.setFrameShape(QtWidgets.QFrame.StyledPanel) self.Player.setFrameShadow(QtWidgets.QFrame.Raised) self.Player.setObjectName("Player") self.PredictedCard = QtWidgets.QLabel(self.Player) self.PredictedCard.setGeometry(QtCore.QRect(0, 0, 171, 61)) font = QtGui.QFont() font.setPointSize(14) self.PredictedCard.setFont(font) self.PredictedCard.setAlignment(QtCore.Qt.AlignCenter) self.PredictedCard.setObjectName("PredictedCard") self.ThreeLandlordCards = QtWidgets.QLabel(Form) self.ThreeLandlordCards.setGeometry(QtCore.QRect(140, 10, 161, 41)) font = QtGui.QFont() font.setPointSize(16) self.ThreeLandlordCards.setFont(font) self.ThreeLandlordCards.setAlignment(QtCore.Qt.AlignCenter) self.ThreeLandlordCards.setObjectName("ThreeLandlordCards") self.Stop = QtWidgets.QPushButton(Form) self.Stop.setGeometry(QtCore.QRect(260, 330, 111, 41)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(14) font.setBold(True) font.setWeight(75) self.Stop.setFont(font) self.Stop.setStyleSheet("") self.Stop.setObjectName("Stop") self.retranslateUi(Form) self.InitCard.clicked.connect(Form.init_cards) self.Stop.clicked.connect(Form.stop) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "AI欢乐斗地主--Dragon少年")) self.WinRate.setText(_translate("Form", "胜率:--%")) self.InitCard.setText(_translate("Form", "开始")) self.UserHandCards.setText(_translate("Form", "手牌")) self.LPlayedCard.setText(_translate("Form", "上家出牌区域")) self.RPlayedCard.setText(_translate("Form", "下家出牌区域")) self.PredictedCard.setText(_translate("Form", "AI出牌区域")) self.ThreeLandlordCards.setText(_translate("Form", "三张底牌")) self.Stop.setText(_translate("Form", "停止"))

实现效果如下:

欢乐器教程,十大最简单的自学乐器(2)

2. 手牌和出牌数据识别

下面我们需要所有扑克牌的模板图片与游戏屏幕特定区域的截图进行对比,这样才能获取AI玩家手牌、底牌、每一轮出牌、三者关系(地主、地主上家、地主下家)。

识别AI玩家手牌及三张底牌:

我们可以截取游戏屏幕,根据固定位置来识别当前AI玩家的手牌和三张底牌。核心代码如下:

# 牌检测结果滤波 def cards_filter(self, location, distance): if len(location) == 0: return 0 locList = [location[0][0]] count = 1 for e in location: flag = 1 # “是新的”标志 for have in locList: if abs(e[0] - have) <= distance: flag = 0 break if flag: count = 1 locList.append(e[0]) return count # 获取玩家AI手牌 def find_my_cards(self, pos): user_hand_cards_real = "" img = pyautogui.screenshot(region=pos) for card in AllCards: result = pyautogui.locateAll(needleImage='pics/m' card '.png', haystackImage=img, confidence=self.MyConfidence) user_hand_cards_real = card[1] * self.cards_filter(list(result), self.MyFilter) return user_hand_cards_real # 获取地主三张底牌 def find_three_landlord_cards(self, pos): three_landlord_cards_real = "" img = pyautogui.screenshot(region=pos) img = img.resize((349, 168)) for card in AllCards: result = pyautogui.locateAll(needleImage='pics/o' card '.png', haystackImage=img, confidence=self.ThreeLandlordCardsConfidence) three_landlord_cards_real = card[1] * self.cards_filter(list(result), self.OtherFilter) return three_landlord_cards_real

效果如下所示:

欢乐器教程,十大最简单的自学乐器(3)

地主、地主上家、地主下家:

同理我们可以根据游戏屏幕截图,识别地主的图标,确认地主角色。核心代码如下:

# 查找地主角色 def find_landlord(self, landlord_flag_pos): for pos in landlord_flag_pos: result = pyautogui.locateOnScreen('pics/landlord_words.png', region=pos, confidence=self.LandlordFlagConfidence) if result is not None: return landlord_flag_pos.index(pos) return None

欢乐器教程,十大最简单的自学乐器(4)

首页 12下一页

栏目热文

友谊辅助器是什么(辅助器可靠吗)

友谊辅助器是什么(辅助器可靠吗)

手工耿于12月25日,看到哈尔滨发了个招聘信,招聘雪球设计官。搞设计,这是他的强项啊,他一下心痒难耐,立刻行动起来,果然...

2022-10-28 09:08:02查看全文 >>

欢乐器什么意思(欢乐机是什么)

欢乐器什么意思(欢乐机是什么)

9月8日,“将宠爱进行到底”2022金科大社区中秋特别活动在全国190多个城市陆续开展。月饼烘焙、中秋灯谜、星空电影、欢...

2022-10-28 09:19:33查看全文 >>

欢乐器有用吗(欢乐器到底是什么东西)

欢乐器有用吗(欢乐器到底是什么东西)

随着时代的发展,游戏已经成为了人们生活中不可或缺的组成部分,就以这次春节为例,春节期间各个网吧都基本上达到了人满为患的程...

2022-10-28 08:55:37查看全文 >>

为什么有的人不能使用欢乐器(老年人在家无聊时解闷玩具)

为什么有的人不能使用欢乐器(老年人在家无聊时解闷玩具)

来源:南国今报家住南宁经开区的李先生,长期受到楼下广场舞的音响声困扰,经提醒和报警未能解决问题。近日,他在网上购买到一个...

2022-10-28 08:41:47查看全文 >>

欢乐器是什么东西(欢乐器是什么)

欢乐器是什么东西(欢乐器是什么)

不知不觉,DNF公测至今已经有了13年的时间了!在这13年期间,虽然每个版本都有无数的装备被淘汰,但是每个版本都会推出一...

2022-10-28 08:47:24查看全文 >>

漫游器干什么用的(漫游器怎么工作)

漫游器干什么用的(漫游器怎么工作)

大约几年之前,我们在另一个星球----火星的表面上,成功降落了一个2吨重的SUV(Sports Utility Vehi...

2022-10-28 09:21:21查看全文 >>

激活器是用来做什么的(自动激活器弊端)

激活器是用来做什么的(自动激活器弊端)

IT之家 3 月 2 日消息,据网友投稿,微软 Windows 商店竟然上架了以破解 Windows 系统和 Offic...

2022-10-28 08:49:37查看全文 >>

乌兰木桶位置图(乌南木桶)

乌兰木桶位置图(乌南木桶)

蒙古是马背上的民族,蒙古帝国铁骑能横扫欧亚,蒙古马功不可没,而其中在不同品种的蒙古马中阿巴嘎的黑马又名(僧僧黑马)品种尤...

2022-10-28 09:14:26查看全文 >>

世界常见木桶分类(世界木桶特性)

世界常见木桶分类(世界木桶特性)

大家在花卉市场上买花看花的时候有没有发现这样一个问题,同样的一种花,自己都已经养爆盆了,开得比花市的还旺盛,可整体看下来...

2022-10-28 09:09:17查看全文 >>

什么是碳化木桶(碳化木桶是不是不容易烂)

什么是碳化木桶(碳化木桶是不是不容易烂)

在英国人眼里,威士忌(whisky)是一种堪比“生命之水”的酒精饮料,当然它也是最受全球男士喜爱的烈酒之一。不管你是威士...

2022-10-28 09:01:44查看全文 >>

文档排行