本帖最后由 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 
 
 
 
 |