本帖最后由 fhjym 于 2018-8-1 20:36 编辑
我做了一个双扣记牌器,因为是图色识别的,所以仅适用于我制作记牌器电脑的分辨率
用的版本是tc7.0,分享源码给像我这样的新手。
记牌器窗口的最小化最好改成false,编辑框的只读属性改成true。
2018年7月31日改贴,添加了大量注释说明,发现写注释能加深理解,并修改了一些BUG。
源码:需回复后查看
变量 线程1,线程2,线程3,线程4//线程1用来开局,线程2用来统计开局手牌,线程4,3分别为左右家出牌检测
变量 剩=数组()//用来统计剩余手牌
var 输出剩牌="",输出炸弹="",输出左家="",输出右家="",左上次出牌="X",右上次出牌="X"//用来记录出牌数据
变量 左花,右花,左上花,右上花,记=0//用来判断本次出牌和上次出牌的花色,若花色和出牌均相等,不进行记录
变量 time
功能 一鸣记牌器_初始化()
//这里添加你要执行的代码
变量 窗口句柄=窗口查找("一鸣记牌器")
窗口置顶(窗口句柄,真)//窗口始终置顶
变量 x,y
time=当前时间()
系统获取分辨率(x,y)
窗口设置位置(窗口句柄,30,y-300) //把记牌器放到屏幕左下角
结束
//点击关闭_执行操作
功能 一鸣记牌器_关闭()
线程关闭(线程1,0)
线程关闭(线程2,0)
线程关闭(线程3,0)
线程关闭(线程4,0)//关闭时先安全关闭所有线程,以免出现未响应的报错
if(记<11)
消息框("您本次一共玩了"&记&"局")//弹出消息框进行提示,以便线程有时间进行关闭。
end
if(记>10)
消息框("您本次一共玩了"&记&"局,请注意休息")//温馨提示
end
控件关闭子窗口("一鸣记牌器",0)
结束
功能 start_点击()
//这里添加你要执行的代码
线程关闭(线程1,0)
线程关闭(线程2,0)
线程关闭(线程3,0)
线程关闭(线程4,0)
记=记+1//本次打开记牌器玩的牌局数+1
剩=数组("王"="王王王王","A"="AAAAAAAA","2"="22222222","3"="33333333","4"="44444444","5"="55555555","6"="66666666","7"="77777777","8"="88888888","9"="99999999","⑩"="⑩⑩⑩⑩⑩⑩⑩⑩","J"="JJJJJJJJ","Q"="QQQQQQQQ","K"="KKKKKKKK")//初始化两副牌
编辑框设置文本("左家","")
编辑框设置文本("右家","")//开局清空出牌记录
线程1=线程开启("开局","")
结束
//从这里开始执行
功能 开局()//1开局
//判断牌局是否开始//嫌三线程太卡,之前的判断线程删了,加了个开局按钮,每次开始牌局发完牌后需要手动点一下开局按钮
if(记>20)
变量 t=当前时间()
变量 ti=时间间隔("m",t,time)
消息框("您已经在双扣战场上奋斗了"&ti/60&"小时,为了您的身体健康,请注意休息!")
end
线程2=线程开启("手牌","")
线程关闭(线程1,0)//现在看来这个线程1只是用来开启线程2,不过不改了,如果你想把开局按钮也去掉,自行判断是否开局,就在线程1里写开局判断语句。
结束
功能 手牌()//2手牌 //总共三个字库,别.txt用来识别其他三家的牌,色.txt用来识别其他三家的花色,我.txt用来识别自己的手牌
变量 我=获取资源路径("rc:我.txt")//字库靠游戏截图来的,截取牌的一部分做字库,然后自己调试14张牌的识别准确率
字库设置(我,0)
字库切换(0)
//270,550,1038,595
变量 my=识字(270,550,1038,595,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
//在屏幕下方识别自己的手牌,000000是黑色牌的颜色值,bb2008和bf2f19是红色牌的颜色值,发现这个游戏用0.9的相似度识字效果不错
变量 别=获取资源路径("rc:别.txt")
字库设置(别,1)
字库切换(1)
变量 ot=识字(343,58,976,87,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
//在屏幕上方识别对家手牌,双扣的明扣打法中,对家手牌是可见的,对家手牌图案较小,所以新做一个字库找字
变量 两家=字符串拼接(my,ot)
//将两家手牌混合
//消息框(手牌长度+对家长度)//本来想判断混合后手牌长度是否等于54,判断牌局是否开始的,后来牌局开始的线程删了,手牌长度的变量也没用了
//当然还要对手牌进行计数...
var pk="a23456789⑩jqk王"//取A到王共14张不同的牌
var i=0
输出剩牌=""
输出炸弹=""
循环(i<14)//循环识别54张手牌,统计每张牌的数量
var p=字符串截取(pk,i,i+1)//取pk变量中第i个字符,放进变量p中
var lm1=字符串长度(两家)//计算当前牌组长度
两家=字符串替换(两家,p,"")//将当前牌组中的所有p牌删除
var lm2=字符串长度(两家)//计算当前牌组长度
i=i+1
var pn=lm1-lm2 //计算牌p有pn张,放进变量pn中
剩[p]=字符串截取左侧(剩[p],字符串长度(剩[p])-pn)//处理剩余牌库中牌p的数量
if(字符串长度(剩[p])>3)//判断剩余牌库中牌p的数量是否大于3
输出炸弹=输出炸弹&p//大于3张的有可能是炸弹
end
输出剩牌=输出剩牌&剩[p]//将剩余牌库混合到一个变量中,准备输出到编辑框中
//消息框(p&"有"&pn&"张")
//p为牌名,pn为p的数量
//计算现有牌数量
结束
编辑框设置文本("剩牌",输出剩牌)
编辑框设置文本("炸弹",字符串转大写(输出炸弹))
线程3=线程开启("右出","")
线程4=线程开启("左出","")
线程关闭(线程2,0)
结束 //手牌
//下面识别左家出牌
功能 左出()//4
//还需左右家出牌记录
//138,315左家出牌位置486,344
//23.4乘以15=420
左上次出牌="X"
左上花="H"
var x,y
变量 别=获取资源路径("rc:别.txt")
变量 色=获取资源路径("rc:色.txt")
字库设置(色,2)
字库设置(别,1)
循环(真)
sleep(1000)
字库切换(1)
变量 le=识字(120,300,600,350,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
字库切换(2)
变量 左王=找字(120,345,600,380,"王","000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9,x,y)+1
字库切换(2)
左花=识字(130,343,600,380,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
if(le==左上次出牌)
if(左花==左上花)
sleep(1000)//如果和上次出牌相同,休息1+1=2秒再进行识字
continue
end
end
左上花=左花
左上次出牌=le
输出剩牌=""
if(左王)//假如花色中找到王,说明有大小王被当做其他牌打出,需进行置换
剩["王"]=字符串移除(剩["王"],1,假)//剩余牌库中减少一张王牌
字库切换(1)
变量 当=识字(x-5,300,x+20,350,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)//识别王上方的牌,看看王被当成了什么牌打出
剩[当]=字符串拼接(剩[当],当)//剩余牌库中增加一张被当的牌
le=字符串拼接(le,"当")
字库切换(2)
变量 左王1=找字(x+20,345,600,380,"王","000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9,x,y)+1
if(左王1)//有时候可能会有两张王同时被当做其他牌打出,进行第二次判断
剩["王"]=字符串移除(剩["王"],1,假)
字库切换(1)
当=识字(x-5,300,x+20,350,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
剩[当]=字符串拼接(剩[当],当)
le=字符串拼接(le,"当")//同时有三张王被当做其他牌打出的概率非常小,而且一般是游戏结束时才会这样打,所以不进行判断了。
end
end
输出左家=编辑框获取文本("左家")&le
编辑框设置文本("左家",字符串转大写(输出左家))
输出炸弹=""
输出剩牌=""
var pk="a23456789⑩jqk王"
var i=0
循环(i<14)//循环识别左家出牌各张牌的数量,与上面开局识别手牌的语句类似
var p=字符串截取(pk,i,i+1)
var lm1=字符串长度(le)
le=字符串替换(le,p,"")
var lm2=字符串长度(le)
i=i+1
var pn=lm1-lm2
剩[p]=字符串截取左侧(剩[p],字符串长度(剩[p])-pn)
if(字符串长度(剩[p])>3)
输出炸弹=输出炸弹&p
end
输出剩牌=输出剩牌&剩[p]
//消息框(p&"有"&pn&"张")
//p为牌名,pn为p的数量
//计算现有牌数量
结束
//消息框(输出剩牌)
编辑框设置文本("剩牌",输出剩牌)
编辑框设置文本("炸弹",字符串转大写(输出炸弹))
sleep(2000)//和上面的sleep都加起来,在左家出过新牌的情况下,每三秒进行一次判断,如果左家没有新出过牌
//时间改短可能变卡,一般刚开局,出的牌都可以留存3秒时间(一轮四个人出牌)
//快结束时2-3人出牌可能出得很快,但是玩家因为要看记牌器,没法出特别快,3秒一般也够用
//除非玩家不看记牌器,很快出牌,可能导致左右家出牌记录读不到,那记牌器也没必要记牌了对吧!
结束
结束//左出4
//下面是识别右家出牌,与上面线程4识别左家出牌类似,大家可以不用看了。
功能 右出()//3
//836,316 右家出牌位置 1183,343
右上花="H"
右上次出牌="X"
var x,y
变量 别=获取资源路径("rc:别.txt")
变量 色=获取资源路径("rc:色.txt")
字库设置(别,1)
字库设置(色,2)
循环(真)
sleep(1000)
字库切换(1)
变量 ri=识字(725,300,1200,350,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
字库切换(2)
变量 右王=找字(725,345,1200,380,"王","000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9,x,y)+1
字库切换(2)
右花=识字(1140,345,1185,380,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
if(ri==右上次出牌)
if(右花==右上花)
sleep(1000)
continue
end
end
右上花=右花
右上次出牌=ri
输出剩牌=""
if(右王)
剩["王"]=字符串移除(剩["王"],1,假)
字库切换(1)
变量 当=识字(x-5,300,x+20,350,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
剩[当]=字符串拼接(剩[当],当)
ri=字符串拼接(ri,"当")
字库切换(2)
变量 右王1=找字(x+20,345,600,380,"王","000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9,x,y)+1
if(右王1)
剩["王"]=字符串移除(剩["王"],1,假)
字库切换(1)
当=识字(x-5,300,x+20,350,"000000-333333|bb2008-bb2222|bf2f19-bf2222",0.9)
剩[当]=字符串拼接(剩[当],当)
ri=字符串拼接(ri,"当")
end
end
输出右家=编辑框获取文本("右家")&ri
编辑框设置文本("右家",字符串转大写(输出右家))
输出炸弹=""
输出剩牌=""
var pk="a23456789⑩jqk王"
var i=0
循环(i<14)
var p=字符串截取(pk,i,i+1)
var lm1=字符串长度(ri)
ri=字符串替换(ri,p,"")
var lm2=字符串长度(ri)
i=i+1
var pn=lm1-lm2
剩[p]=字符串截取左侧(剩[p],字符串长度(剩[p])-pn)
if(字符串长度(剩[p])>3)
输出炸弹=输出炸弹&p
end
输出剩牌=输出剩牌&剩[p]
//消息框(p&"有"&pn&"张")
//p为牌名,pn为p的数量
//计算现有牌数量
结束
编辑框设置文本("剩牌",输出剩牌)
编辑框设置文本("炸弹",字符串转大写(输出炸弹))
sleep(2000)
结束
结束//右出3
|