你们要的“带代码、带步骤、带截图”的棋牌脚本教程来了。
选橙色平台房卡这个游戏当案例有两个原因:第一,后台问的人实在太多;第二,它的界面复杂度适中,非常适合当教学样本——入口按钮多、有广告弹窗、需要多状态识别,练手价值极高。
本文全程以代码说话,每一个关键步骤都会给出可以直接复用的代码片段,并且我会把踩过的坑标成“避坑提示”,帮你节省调试时间。建议你现在就打开电脑,跟着步骤一步一步敲,光看不练等于白看。
再强调一遍:本文仅供自动化技术学习,不要将任何代码用于干扰游戏公平性,后果自负。
一、环境搭建:把武器先磨快
1.1 安装Python
去 python.org 下载 Python 3.10.x 版本(3.11也行,但不建议3.12,部分库兼容性还没完全跟上)。安装时一定勾选底部的“Add Python to PATH”,然后一路下一步。
装完之后验证一下:按 Win+R 输入 cmd 回车,在黑色窗口里输入 python --version,如果打印出版本号就说明装好了。
1.2 安装Airtest
继续在刚才的命令行窗口里输入:
pip install airtest
回车,等进度条跑完。这一步会自动装上Airtest的核心库以及它依赖的opencv、numpy等。
1.3 安装Airtest IDE(可选但推荐)
虽然可以直接用VS Code写,但对零基础来说,Airtest IDE的“所见即所得”真的太香了。去 airtest.netease.com 下载对应系统的版本,安装。打开后你会看到一个带设备投屏窗口的界面,后面会用到。
二、连接橙色平台:让脚本“看”到游戏
橙色平台房卡主要有安卓客户端。我们以安卓手机为目标设备。
2.1 手机端设置
-
打开“设置”→“关于手机”,连续点击“版本号”7次,打开开发者模式。
-
回到“设置”→“开发者选项”,打开“USB调试”。
-
用数据线连接电脑,手机上会弹出“允许USB调试”的提示,勾选“一律允许”然后确定。
2.2 在脚本里连接设备
如果你用Airtest IDE,点一下“设备”面板里的“连接”按钮,选你的手机就行。如果是在VS Code里纯写代码,我们需要用airtest.core.api来连接。创建一个新文件夹叫orange_script,在里面新建一个main.py,写入:
from airtest.core.api import * # 连接安卓设备(用ADB方式,USB线连接) device = connect_device("Android:///") print("设备连接成功")
避坑提示:如果报错找不到adb,到Airtest IDE的安装目录下找到adb.exe,把它的路径加到系统环境变量里,或者直接在代码里指定adb_path:
from airtest.core.api import * from airtest.core.android.adb import ADB ADB("D:/path_to_airtest/airtest/core/android/static/adb/").connect() device = connect_device("Android:///")
连接成功后,运行脚本,控制台打印出“设备连接成功”,表示手机已经被脚本接管。
2.3 打开橙色平台APP
在代码中启动游戏,保证后续脚本运行时APP已经在前台:
from airtest.core.api import * # 先用包名启动橙色平台(包名每个手机可能不同,可用adb查) start_app("com.orange.game") # 换成实际的包名 sleep(5) # 等游戏加载完
查看APP包名的方法:手机连上电脑,命令行输入 adb shell dumpsys window | findstr mCurrentFocus,可以看到当前前台APP的包名。把com.orange.game替换为你查到的。

三、核心脚本编写:逐行敲出游戏逻辑
现在环境通了,游戏也跑起来了。我们开始写脚本的骨架。橙色平台房卡的典型流程是:主界面→选择房间→坐下准备→等待开局→游戏中自动操作→回到主界面循环。
我们先从最简单的“主界面→进入房间”开始,逐步叠加。
3.1 基础函数封装:截图并点击
Airtest用图片匹配的方式操作,我们需要先截取需要操作的按钮图片。在Airtest IDE里可以方便地框选截图,这里假设你已经截好了以下图片并放在img文件夹下:
-
room_button.png(房间入口按钮) -
sit_down.png(坐下按钮) -
ready.png(准备按钮) -
popup_close.png(广告弹窗关闭按钮)
封装一个安全的点击函数,避免找不到图片时报错:
import random from airtest.core.api import * def safe_click(img_path, threshold=0.8, timeout=5): """安全点击:如果图片存在就点击,否则返回False""" try: pos = wait(Template(img_path, threshold=threshold), timeout=timeout) if pos: touch(pos) # 加随机延迟,模拟人类 sleep(random.uniform(0.5, 1.5)) return True except TargetNotFoundError: pass return False
避坑提示:threshold是匹配阈值,设太高(0.95)可能因为手机屏幕色差导致匹配不上,设太低(0.6)可能误点。一般0.75-0.85是合理范围。
3.2 处理弹窗:游戏脚本的“保安”
橙色平台房卡在进入房间前后经常弹广告,我们必须先处理弹窗,否则后面所有点击都可能失效。写一个弹窗清理函数:
def handle_popup(): """尝试关闭可能出现的广告弹窗""" # 常见弹窗关闭按钮匹配 close_imgs = ["popup_close.png", "popup_close2.png", "cancel_btn.png"] for img in close_imgs: if safe_click(f"img/{img}", threshold=0.8, timeout=1): print(f"关闭弹窗: {img}") sleep(1) # 关掉一个后等一下,避免动画残留 return True return False
在实际游戏循环中,我们在每一个关键步骤前都调用一次handle_popup(),保证界面干净。
3.3 主循环:从大厅到房间的一键流程
def enter_room(): """从主界面进入房间并坐下准备""" print("开始进入房间流程...") # 先清一波弹窗 handle_popup() # 点击房间按钮 if safe_click("img/room_button.png", timeout=10): print("点击房间按钮成功") sleep(3) # 等待进入房间界面加载 # 再次处理可能出现的弹窗 handle_popup() # 点击坐下按钮 if safe_click("img/sit_down.png", timeout=8): print("坐下成功") sleep(1) # 点击准备按钮 if safe_click("img/ready.png", timeout=5): print("已准备,等待开局") return True else: print("未找到准备按钮,可能已开局或座位已满") return False
避坑提示:safe_click里的timeout(等待图片出现的最长时间)要据实际网络和界面动画调整。网络卡的时候设太短会漏点。

3.4 游戏中的简单自动化逻辑
以抢地主环节为例,写一个基于图片状态的自动操作。假设我们截了rob.png(抢地主按钮)和no_rob.png(不抢按钮)。
def auto_rob(): """根据策略自动抢地主""" # 循环检测,直到出现操作选项 for i in range(20): # 最多等20秒 if safe_click("img/rob.png", threshold=0.8, timeout=1): print("选择抢地主") return elif safe_click("img/no_rob.png", threshold=0.8, timeout=1): print("选择不抢") return sleep(1) print("未检测到抢地主选项")
你可以替换成自己的策略,比如根据手牌好坏判断。这里为了教学清晰,直接固定选择抢。
3.5 出牌环节的自动操作
出牌阶段通常是棋牌脚本最复杂的部分。我们这里采用最简化的“能出就出”逻辑作为框架:
def auto_play(): """自动出牌:检测出牌按钮并点击""" while True: handle_popup() # 优先检测“不出”按钮,避免失误出牌(策略先放一边) if safe_click("img/pass.png", threshold=0.8, timeout=0.5): print("选择不出") sleep(2) continue # 检测出牌按钮 if safe_click("img/play_card.png", threshold=0.8, timeout=0.5): print("出牌成功") sleep(2) # 检查是否结束 if exists(Template("img/game_over.png", threshold=0.8)): print("对局结束") sleep(3) # 点击返回或自动退出 safe_click("img/back_to_hall.png") break sleep(1)
避坑提示:出牌按钮状态在不同游戏版本中可能有多种(如出牌按钮高亮/灰暗),你可能需要截取不同状态的图片分别尝试。上面的逻辑是不断轮询play_card.png,一旦出现就点,过于粗暴,但对于简单的牌型(比如系统提示出牌后直接点确认)可以工作。
3.6 完整的脚本主函数
把上面所有的模块串起来,形成一个可以循环运行的脚本:
def main(): device = connect_device("Android:///") start_app("com.orange.game") sleep(5) while True: # 每一局开始前检查是否在大厅 if exists(Template("img/hall_icon.png", threshold=0.8)): print("检测到在大厅,开始进入房间") if enter_room(): # 等开局,可以用等待“发牌动画结束”的图片来判断 wait(Template("img/your_turn.png", threshold=0.8), timeout=120) # 自动抢地主 auto_rob() # 自动出牌循环 auto_play() else: print("进房失败,重试") else: # 可能还在上一局结算界面,尝试返回大厅 safe_click("img/back_to_hall.png") sleep(5)
避坑提示:真实环境中还需要加上电量、网络状态的判断,以及长时间运行的容灾处理(比如每周重启一次脚本)。作为入门教学,上述代码已经展示了一条完整的自动化链路。
四、打包上线:把.py变成别人能用的工具
脚本在自己电脑上跑通了,但是别人没有安装Python和Airtest环境怎么办?我们需要把它打包成exe。
4.1 使用PyInstaller打包
首先安装PyInstaller:
pip install pyinstaller
然后在脚本目录下,创建一个干净的打包配置。但因为Airtest依赖了一些图形库,直接打包可能会出错,需要用命令行指定--hidden-import:
pyinstaller --onefile --console --hidden-import=airtest --hidden-import=cv2 --hidden-import=numpy main.py
打包完成后,在dist文件夹下找到main.exe。但是图片资源不会自动打包进去,你需要把img文件夹复制到main.exe同一目录下,这样才能保证Template("img/xxx.png")能找到文件。
更推荐的做法是用代码把图片资源以base64形式硬编码,或者让脚本运行时自动解压,避免用户搞丢图片。这里给出一个简单的资源目录打包方法:在代码开头加上获取当前exe目录的代码,然后拼接图片路径。
import sys, os if getattr(sys, 'frozen', False): base_dir = sys._MEIPASS # PyInstaller临时解压路径 else: base_dir = os.path.dirname(__file__) img_dir = os.path.join(base_dir, "img")
PyInstaller打包时可以用--add-data参数把img文件夹打包进去,命令示例:
pyinstaller --onefile --add-data "img;img" main.py

4.2 给脚本加一个简单的配置界面(可选)
为了让非技术人员也能用,可以用最简单的方式——在脚本开始时读取一个config.txt文件,把一些参数(比如房间选择、阈值等)配置进去,省得每次改代码。
config = {} with open("config.txt", "r", encoding="utf-8") as f: for line in f: if "=" in line: k, v = line.strip().split("=") config[k.strip()] = v.strip() threshold_val = float(config.get("threshold", 0.8)) room_choice = config.get("room", "default")
打包时把config.txt也一起带出去,用户编辑这个文件就能调整部分行为。
五、完整代码汇总(精简注释版)
import random from airtest.core.api import * from airtest.core.android.adb import ADB # ---------- 基础函数 ---------- def safe_click(img, threshold=0.8, timeout=3): try: pos = wait(Template(img, threshold=threshold), timeout=timeout) touch(pos) sleep(random.uniform(0.3, 1.0)) return True except: return False def handle_popup(): popups = ["img/popup_close.png", "img/popup_close2.png"] for p in popups: if safe_click(p, timeout=1): sleep(1) return True return False def wait_and_click(img, timeout=10): handle_popup() return safe_click(img, timeout=timeout) # ---------- 业务流程 ---------- def enter_room(): if wait_and_click("img/room_button.png"): sleep(3) handle_popup() if wait_and_click("img/sit_down.png", timeout=8): sleep(1) return wait_and_click("img/ready.png", timeout=5) return False def auto_rob(): for _ in range(20): if safe_click("img/rob.png", timeout=0.5): return if safe_click("img/no_rob.png", timeout=0.5): return sleep(1) def auto_play(): while not exists(Template("img/game_over.png", threshold=0.8)): handle_popup() safe_click("img/pass.png", timeout=0.3) if safe_click("img/play_card.png", timeout=0.5): sleep(1.5) sleep(0.5) sleep(3) safe_click("img/back_to_hall.png") # ---------- 主循环 ---------- def main(): connect_device("Android:///") start_app("com.orange.game") sleep(5) while True: handle_popup() if exists(Template("img/hall_icon.png", threshold=0.7)): if enter_room(): wait(Template("img/your_turn.png", threshold=0.7), timeout=120) auto_rob() auto_play() else: safe_click("img/back_to_hall.png", timeout=2) sleep(5) if __name__ == "__main__": main()
把上述代码保存为main.py,准备好对应截图,你就可以拥有一套橙色平台房卡的自动化脚本骨架。你可以在此基础上增加牌型判断、出牌策略、异常恢复等模块,逐步完善。
棋牌脚本真正复杂的部分并不在于能不能跑起来,而在于跑起来之后,如何适配不同分辨率、如何抗干扰、如何做出合理的决策逻辑。这些需要大量的实机调试和经验积累,不是一个帖子能写完的。
如果你在实操过程中遇到具体卡点,或者想要更完整的橙色平台房卡脚本方案(包括多分辨率适配代码、多种牌型判断策略的完整实现),可以扫描下方二维码加微信,备注“橙色房卡脚本”。
玫瑰资源库













![[源码分享] 创胜系列定制版本嘉年华房卡源代码【开发引擎Cocos Creator2.4.3】-玫瑰资源库](https://www.264rose.com/wp-content/uploads/2024/10/c4ca4238a0b9238-10.jpg)




