.程序集 血战麻将AI
.程序集变量 牌型缓存, 哈希表
.程序集变量 决策库, 决策记录, 数组
.子程序 __启动窗口_创建完毕
加载牌型库("mahjong_patterns.dat")
初始化决策库()
' ====== 核心算法模块 ======
.子程序 换三张决策, 文本型
.参数 手牌, 麻将牌, 数组
.局部变量 花色分布, 整数型, , "3" ' 万/条/筒
.局部变量 总牌数, 整数型
.局部变量 熵值, 小数型
.局部变量 i, 整数型
总牌数 = 取数组成员数(手牌)
.计次循环首 (总牌数, i)
.判断开始 (手牌[i].类型 == "万")
花色分布[1] = 花色分布[1] + 1
.判断 (手牌[i].类型 == "条")
花色分布[2] = 花色分布[2] + 1
.判断 (手牌[i].类型 == "筒")
花色分布[3] = 花色分布[3] + 1
.默认
.判断结束
.计次循环尾()
' 计算熵值 (牌型混乱度)
熵值 = 0
.计次循环首 (3, i)
.如果真 (花色分布[i] > 0)
概率 = 花色分布[i] / 总牌数
熵值 = 熵值 - 概率 * 求对数(概率, 2)
.如果真结束
.计次循环尾()
' 决策逻辑
.判断开始 (熵值 < 1.2) ' 牌型集中
返回 保留主花色(手牌, 取数组最大值索引(花色分布))
.判断 (熵值 > 1.8) ' 牌型分散
返回 弃边缘牌(手牌)
.默认
返回 弃中间牌(手牌) ' 平衡策略
.判断结束
' ====== 牌型分析引擎 ======
.子程序 分析牌型, 小数型
.参数 手牌, 麻将牌, 数组
.局部变量 花色分布, 整数型, , "3"
.局部变量 主花色, 整数型
.局部变量 清一色概率, 小数型
.局部变量 对子数, 整数型
.局部变量 i, 整数型
' 计算花色分布
.计次循环首 (取数组成员数(手牌), i)
.判断开始 (手牌[i].类型 == "万")
花色分布[1] = 花色分布[1] + 1
.判断 (手牌[i].类型 == "条")
花色分布[2] = 花色分布[2] + 1
.判断 (手牌[i].类型 == "筒")
花色分布[3] = 花色分布[3] + 1
.默认
.判断结束
.计次循环尾()
主花色 = 取数组最大值索引(花色分布)
清一色概率 = 花色分布[主花色] / 14 * 0.85 ' 经验系数
' 小七对检测
手牌排序(手牌) ' 按牌值排序
对子数 = 0
i = 1
.循环判断首 ()
.如果真 (i < 取数组成员数(手牌))
.如果真 (手牌[i].值 == 手牌[i+1].值)
对子数 = 对子数 + 1
i = i + 2 ' 跳过对子
.否则
i = i + 1
.如果真结束
.如果真结束
.循环判断尾 (i <= 取数组成员数(手牌))
.局部变量 小七对概率, 小数型
小七对概率 = 对子数 / 7 * 0.9 ' 经验系数
' 胜率预测公式: $P_{win} = 0.7 + 0.2P_{清一色} + 0.15P_{小七对} + 0.1\frac{N_{有效牌}}{14}$
.局部变量 有效牌数, 整数型
有效牌数 = 计算有效牌数(手牌, 主花色)
.局部变量 预测胜率, 小数型
预测胜率 = 0.7 + 0.2 * 清一色概率 + 0.15 * 小七对概率 + 0.1 * (有效牌数 / 14)
返回 预测胜率
' ====== 决策树引擎 ======
.子程序 生成决策, 文本型
.参数 当前牌局, 牌局状态
.局部变量 动作表, 小数型, , "4" ' 出牌/碰/杠/胡
.局部变量 胜率, 小数型
胜率 = 当前牌局.胜率
' 动作评分公式: $S_i = w_i \times (P_{win} + C_i)$
动作表[1] = 0.6 * (胜率 + 出牌收益(当前牌局)) ' 出牌
动作表[2] = 1.2 * (胜率 + 碰牌收益(当前牌局)) ' 碰牌
动作表[3] = 1.5 * (胜率 + 杠牌收益(当前牌局)) ' 杠牌
动作表[4] = 2.0 * (胜率 + 胡牌收益(当前牌局)) ' 胡牌
' 选择最优动作
.局部变量 最佳动作, 整数型
最佳动作 = 取数组最大值索引(动作表)
.判断开始 (最佳动作 == 1)
返回 "出牌:" + 选择出牌(当前牌局.手牌)
.判断 (最佳动作 == 2)
返回 "碰牌"
.判断 (最佳动作 == 3)
返回 "杠牌"
.判断 (最佳动作 == 4)
返回 "胡牌"
.默认
返回 "出牌"
.判断结束
' ====== 学习系统 ======
.子程序 更新模型
.参数 对局结果, 逻辑型 ' true=赢
.参数 决策路径, 文本型
.局部变量 学习率, 小数型
学习率 = 0.05 ' 动态调整系数
.如果真 (对局结果)
决策库.更新胜率(决策路径, 学习率)
.否则
决策库.更新胜率(决策路径, -学习率)
.如果真结束
' 权重衰减公式: $w_{new} = w_{old} \times (1 - \lambda) + \Delta w$
.计次循环首 (取数组成员数(决策库), i)
决策库[i].权重 = 决策库[i].权重 * 0.98 + 决策库[i].增量
.计次循环尾()
' ====== 辅助函数 ======
.子程序 保留主花色, 文本型
.参数 手牌, 麻将牌, 数组
.参数 主花色索引, 整数型
' 实现略:保留主花色牌,弃掉其他花色牌
.子程序 弃边缘牌, 文本型
.参数 手牌, 麻将牌, 数组
' 实现略:优先弃掉字牌和边张(1,9)
.子程序 计算有效牌数, 整数型
.参数 手牌, 麻将牌, 数组
.参数 主花色, 整数型
' 实现略:计算能组成顺子、刻子的有效牌数量
.子程序 出牌收益, 小数型
.参数 当前牌局, 牌局状态
' 实现略:根据当前牌局计算出牌收益
' ====== 缓存优化 ======
.子程序 获取决策, 文本型
.参数 牌型指纹, 文本型
.如果真 (牌型缓存.存在(牌型指纹))
返回 牌型缓存[牌型指纹]
.否则
.局部变量 结果, 文本型
结果 = 计算决策(牌型指纹)
牌型缓存.添加(牌型指纹, 结果, 600) ' 缓存10分钟
返回 结果
.如果真结束
这个程序还有要改进的地方吗
' ====== 多线程处理 ======
.子程序 异步决策
.参数 当前状态, 牌局状态
.局部变量 线程ID, 整数型
线程ID = 启动线程(&计算最优决策, 当前状态)
等待线程(线程ID, 500) ' 超时500ms
最新发布