首页
社区
课程
招聘
[原创]Autox.js淘宝斗地主记牌器V1.0
发表于: 2025-3-27 11:10 351

[原创]Autox.js淘宝斗地主记牌器V1.0

2025-3-27 11:10
351


【文件及目录截图】

【28001264部分内容截图】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
插入代码
```/////////////////////////////////////////////////////////////////////////////////
//脚本名称:淘宝斗地主记牌器V1.0
//设计作者:刘俊宾(踏雪无痕)
//联系方式:WeChat[txwh171162612],QQ[171162612]
//编写日期:2025.03.11
//测试环境:荣耀Magic7,MagicOS9.0,Android15,
//          分辨率2800X1264,Autox.js_6.3.4。测试通过!
//设计思路:(1)识别纸牌:截图->灰度处理->加载图片[纸牌]->灰度处理->
//          识别结果存入全局变量。按识别区域轮询。
//          (2)识别区域:分为自己拿牌区、上家出牌区、下家出牌区
//          以及操作按钮识别区[text("文本")方法识别按钮不稳定]
//          (3)轮询研判:通过操作按钮变化评判不同时机做不同的识别任务。
//           a.检测到"X地主"时,初始化纸牌数据全局变量;
//           b.检测到"加倍"时,轮询自己拿牌区,更新自己拿牌变量;
//           c.检测到"出牌"时,轮询上家出牌区和下家出牌区,更新相应变量;
//           d.未识别检测到以上按钮时,判定为进入下一轮出牌。
//使用方法:因为机型和分辨率的差异性,第一次使用前,需要进入游戏将游戏过程
//          进行截图(所保存到的图像能体现14张不同纸牌为限(自己拿牌区和他人
//          出牌区2个区域是独立的),编辑图片把14张不同纸牌进行裁切另存为到
//          存储器(适应代码路径和名称),以及按钮操作区按钮的识别图片相应截
//          图。相关截图裁切时应考虑其唯一性,也要考虑其共通性。
//          [可参考现有截图的基本特征和技巧],准备就绪后,直接运行即可测试
//          和使用。
// 其  他:(1)智慧分析(按常理分析):加入了简单的以常理分析"智慧"猜测剩余
//          牌在上家或下家手中(可能仅适用于炸弹场);
//         (2)字体颜色特征说明:剩余牌[白色]、疑似炸弹[红色],当剩余牌显示
//          为蓝色时,表示该牌在上家手中;绿色时在下家手中。
//          上家出牌[蓝色],下家出牌[绿色]。
//         (3)文件夹及文件命名规则:
//          --------------------------------------------------------------
//              └─card_tb
//                  │  jpq2_bg.png
//                  │  记牌器(pic).js
//                 
//                  └─28001264
//                         R0.png~R13.png
//                         R0m.png~R13m.png
//                         tb_cp.png
//                         tb_jb.png
//                         tb_jdz.png
//                         tb_ybq.png
//          --------------------------------------------------------------
//          card_tb[主目录],28001264[识牌目录]
//          jpq2_bg.png[背景图片]
//          R0.png~R13.png[自己拿牌区14张截图,R意为红色]
//          R0m.png~R13m.png[他人出牌区14张截图,m意为中尺寸]
//          tb_cp.png[出牌按钮截图],tb_jb.png[加倍按钮截图]
//          tb_jdz.png[X地主按钮截图],tb_ybq.png[要不起按钮截图]
//
/////////////////////////////////////////////////////////////////////////////////
 
//请求截图
if (!requestScreenCapture()) {
    toast("请求截图失败");
    exit();
}
 
//不同手机分辨率不同,出牌区域不同,牌尺寸不同
var pathHW = String(device.height) + String(device.width); //取回设备屏幕分辨率高和宽
var basePath = "/sdcard/pclink/card_tb/" + pathHW + "/"; //找图路径
var operXY = [20, 1500, 1224, 200]; //游戏操作区
var OwnXY = [20, 1780, 1100, 350]; //自己拿牌区
var prevXY = [20, 860, 480, 240]; //上家出牌区
var NextXY = [700, 860, 480, 240]; //下家出牌区
var floatyXY = [140, 140]; //浮窗显示坐标
 
//纸牌数据记录变量
var cardCount = [2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]; //剩余牌变量
var card_Own = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //自己拿牌
var card_Iyu = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //自己剩余牌
var card_Prev = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //上家出牌
var card_Next = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //下家出牌
var New_flag = 0; //游戏过程标记
 
//创建浮窗显示记牌器
var window = floaty.window(
    <frame id="text" w="286dp" h="76dp">
        <!-- 背景图层 -->
        <img src="file:///sdcard/pclink/card_tb/jpq2_bg.png" w="286dp" h="76dp" scaleType="centerCrop" />
        <!-- 表格内容层 -->
        <vertical w="*" h="76dp" marginTop="2dp">
            <horizontal id="dataRows1" margin="46 18 5 0">
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
                <text text="" w="17" textSize="13" textColor="#FFFFFFFF"/>
            </horizontal>
            <horizontal id="dataRows2" margin="46 -1 5 0">
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
                <text text="" w="17" textSize="13" textColor="#FF0000FF"/>
            </horizontal>
            <horizontal id="dataRows3" margin="46 -1 5 0">
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
                <text text="" w="17" textSize="13" textColor="#FF00FF00"/>
            </horizontal>
        </vertical>
    </frame>
);
window.exitOnClose();
//浮窗操作菜单
window.text.click(() => {
    window.setAdjustEnabled(!window.isAdjustEnabled());
});
//定时器
setInterval(() => {
    ui.run(function() {
        checkOper(); //检测
        outCard(); //输出
    });
}, 800);
 
window.setPosition(floatyXY[0], floatyXY[1]); //定位浮窗位置
//操作区出现"加倍"按钮,找图路径(预先加载)
var tb_jb = images.read(basePath + "tb_jb.png"); //加载图片
tb_jb = images.grayscale(tb_jb); //灰度处理
 
//操作区出现"要不起"按钮,找图路径(预先加载)
var tb_ybq = images.read(basePath + "tb_ybq.png"); //加载图片
tb_ybq = images.grayscale(tb_ybq); //灰度处理
 
//操作区出现"出牌"按钮,找图路径(预先加载)
var tb_cp = images.read(basePath + "tb_cp.png"); //加载图片
tb_cp = images.grayscale(tb_cp); //灰度处理
 
//操作区出现"叫地主""抢地主"按钮,这里使用"地主"替代了两个按钮识别,找图路径(预先加载)
var tb_jdz = images.read(basePath + "tb_jdz.png"); //加载图片
tb_jdz = images.grayscale(tb_jdz); //灰度处理
 
// 初始化牌(新开局)
function initCard() {
    cardCount = [2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]; //初始时各牌的最大数量
    card_Own = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //自己拿牌
    card_Iyu = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //自己剩余牌
    card_Prev = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //上家出牌
    card_Next = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //下家出牌
}
 
//检测操作区出现的按钮,判断游戏过程
function checkOper() {
    var img = images.captureScreen(); //截屏
    img = images.grayscale(img); //灰度处理
    //images.save(img, "/sdcard/pclink/CS_tempb01.jpg");
     
    //检测是否出现"出牌"按钮
    var oper = images.findImage(img, tb_cp, {
        region: operXY,
        threshold: 0.9
    })
    if (oper) { //如果出现"出牌"按钮,说明他人或出牌在其出牌区域
        if (New_flag == 2) { //New_flag=2意为正在牌局中
            New_flag = 3; //修改New_flag=3,意为已经查询并记录他人出牌数据
            findAllNum(img, "prev", prevXY, "m"); //查询上家出牌
            findAllNum(img, "next", NextXY, "m"); //查询下家出牌
            log("到我出牌:可出牌");
        }
    } else { //没有出现"出牌"按钮,继续检测是不是"要不起"
        var oper = images.findImage(img, tb_ybq, {
            region: operXY,
            threshold: 0.9
        })
        if (oper) { //如果是"要不起",说明他人也或出牌在其出牌区域
            if (New_flag == 2) { //New_flag=2意为正在牌局中
                New_flag = 3; //修改New_flag=3,意为已经查询并记录他人出牌数据
                //延时600毫秒后再查询出牌,避免飞机、炸弹等特效遮挡
                setTimeout(() => {
                    var Ownimg = images.captureScreen(); //截屏
                    Ownimg = images.grayscale(Ownimg); //灰度处理
                    findAllNum(Ownimg, "prev", prevXY, "m"); //查询上家出牌
                    findAllNum(Ownimg, "next", NextXY, "m"); //查询下家出牌
                    findAllNum(Ownimg, "iyu", OwnXY, ""); //查询自己剩余的牌
                    Ownimg.recycle(); //释放img(截屏图像)
                }, 600);
                log("到我出牌:要不起");
            }
        } else { //没有出现"出牌""要不起"按钮,那就可能别人在出牌或者游戏还没有开局,检测有没有"加倍"按钮
            var oper = images.findImage(img, tb_jb, {
                region: operXY,
                threshold: 0.9
            })
            if (oper) { //如果出现了"加倍"按钮,说明游戏正在新开局
                if (New_flag == 1) { //New_flag=1意为准备开始游戏
                    initCard(); //初始化牌变量数据
                    //延时1200毫秒后再查询自己拿牌,避免自己做地主时底牌还没发到
                    setTimeout(() => {
                        var Ownimg = images.captureScreen(); //截屏
                        Ownimg = images.grayscale(Ownimg); //灰度处理
                        New_flag = 2; //修改标记New_flag=2意为正在牌局中
                        findAllNum(Ownimg, "own", OwnXY, ""); //查询自己拿到的牌
                        Ownimg.recycle(); //释放img(截屏图像)
                    }, 1200);
                    log("找到加倍,新开局");
                }
            } else { //没有出现"加倍"按钮,继续检测是不是游戏在准备中
                var oper = images.findImage(img, tb_jdz, {
                    region: operXY,
                    threshold: 0.9
                })
                if (oper) { //如果出现"叫地主""抢地主"说明游戏正在准备开局
                    if (New_flag != 1) { //出现"叫地主""抢地主"说明游戏正在准备,任何状态都要"回归"准备记录自己拿牌
                        New_flag = 1; //修改New_flag=1意为准备开始游戏
                        log("找到叫地主,准备牌局");
                    }
                } else { //什么都没有检测到,要么他人在出牌,要么没有在游戏
                    if (New_flag == 3) { //New_flag=3,意为已经查询并记录他人出牌数据
                        New_flag = 2; //修改标记New_flag=2意为准备下一回合记录
                        log("到他人出牌");
                    }
                    //log("什么都没有检测到");
                }
            }
        }
    }
    img.recycle(); //释放img(截屏图像)
}
 
//查询检测自己拿牌、上家出牌、下家出牌,存储到全局变量
function findAllNum(img, mode, tmpXY, tmpN) {
    //循环014(根据斗地主规则从"王2AKQJ109876543"排列,检测图片的文件命名同)
    for (var nl = 0; nl < 14; nl++) {
        var mydes = images.read(basePath + "R" + nl + tmpN + ".png");
        mydes = images.grayscale(mydes); //灰度处理
        //images.save(mydes, "/sdcard/pclink/CS_tempa5.jpg");
         
        var point = images.matchTemplate(img, mydes, {
            region: tmpXY,
            threshold: 0.9,
            max: 4,
            level: 0
        });
        switch (mode) {
            case "own": //查询自己拿牌
                card_Own[nl] = point.matches.length; //直接替换更新
                card_Iyu[nl] = card_Own[nl];
                break;
            case "iyu": //查询自己剩余的牌
                card_Iyu[nl] = point.matches.length; //直接替换更新
                break;
            case "prev": //查询上家出牌
                card_Prev[nl] = card_Prev[nl] + point.matches.length; //累加更新
                break;
            case "next": //查询下家出牌
                card_Next[nl] = card_Next[nl] + point.matches.length; //累加更新
                break;
        }
    }
    //调试输出纸牌查询结果
    switch (mode) {
        case "own":
            log(mode + "=" + card_Own);
            break;
        case "iyu":
            log(mode + "=" + card_Iyu);
            break;
        case "prev":
            log(mode + "=" + card_Prev);
            break;
        case "next":
            log(mode + "=" + card_Next);
            break;
    }
    mydes.recycle(); //释放mydes(检测图像)
}
 
//尝试智慧分析(按常理分析)
function ddz_Wisdom(cardN, cardC, aColor) {
    if (cardC > 0 && cardN != 1) { //有牌才处理,且牌不为2(排除拆2的极大可能性)
        window.dataRows1.getChildAt(cardN).setTextColor(aColor); //设置颜色
    }
}
 
//输出到浮窗显示
function outCard() {
    //"王2AKQJ109876543"循环
    for (var i = 0; i < cardCount.length; i++) {
        //临时计算剩余牌(总牌量-自己拿牌-上家出牌-下家出牌)
        var t = cardCount[i] - card_Own[i] - card_Prev[i] - card_Next[i]; //剩余牌=总牌数量-我拿牌-上家出牌-下家出牌
        window.dataRows1.getChildAt(i).setText(String(t)); //输出更新剩余牌
        //设置透明度
        if (t <= 0) { //0,剩余牌没这个牌了,设置20%透明,减少视线干扰
            window.dataRows1.getChildAt(i).setAlpha(0.2); //20%透明度
        } else {
            window.dataRows1.getChildAt(i).setAlpha(1); //不透明
        }
        //按常理分析他人拿牌情况(仅适用炸弹场)
        ddz_Wisdom(i, card_Prev[i], android.graphics.Color.GREEN); //上家打出了这个牌,剩下的牌推测为在下家
        ddz_Wisdom(i, card_Next[i], android.graphics.Color.BLUE); //下家打出了这个牌,剩下的牌推测为在上家
 
        //设置颜色
        if ((t == 4) || (i == 0 && t == 2)) { //王炸或者炸弹设置红色
            window.dataRows1.getChildAt(i).setTextColor(android.graphics.Color.RED); //红色
        } else { //不是炸弹
            var textColor = window.dataRows1.getChildAt(i).getPaint().getColor(); //返回当前颜色值
            if (textColor == android.graphics.Color.RED) { //如果当前是红色就设置为白色
                window.dataRows1.getChildAt(i).setTextColor(android.graphics.Color.WHITE); //白色
            }
        }
        if (card_Prev[i] <= 0) { //0,上家没这个牌了,设置20%透明,减少视线干扰
            window.dataRows2.getChildAt(i).setAlpha(0.2); //20%透明度
        } else {
            window.dataRows2.getChildAt(i).setAlpha(1); //不透明
        }
        if (card_Next[i] <= 0) { //0,下家没这个牌了,设置20%透明,减少视线干扰
            window.dataRows3.getChildAt(i).setAlpha(0.2); //20%透明度
        } else {
            window.dataRows3.getChildAt(i).setAlpha(1); //不透明
        }
        window.dataRows2.getChildAt(i).setText(String(card_Prev[i])); //输出更新上家出牌
        window.dataRows3.getChildAt(i).setText(String(card_Next[i])); //输出更新下家出牌
    }
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回