-
-
[原创]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) { / / 循环 0 ~ 14 (根据斗地主规则从 "王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])); / / 输出更新下家出牌 } } |
赞赏
赞赏
雪币:
留言: