结算与算奖(§6.3/§7/§8) - 扣底倍数改线性:单张×1、主对×2、N连对×2N - 算子实现常规算子 + 爬坡两套(大光×3、Q=40 / 爬坡分段),X=基础子数×判定倍率 - 常规算奖只计庄家;连对链修复(传实际主花色);移除 ≥10 老主误加奖与设计外的 「冲关必叫/四王必踢」作废;算奖快照取庄家埋牌后28张(新增 get_seat_cards_award) - 算奖并入结算改为 X×(2Ni−Nj−Nk);傍王按房间开关、庄闲每王1奖 出牌与甩牌(§5.4) - 副牌绝对禁甩;甩牌最大性按对手全部手牌逐分量判定(新增 trump_rank/ decompose_trump/opp_can_beat_flush);甩错惩罚(收回、只打最小一张、下发 shuaicuo) - 修复 can_followcard 引用未定义 tuolaji_list 的崩溃、can_playcard 14张上限失效 开局/投降/暗牌(§4) - 投降改为选主阶段(step2)与选主互斥、不埋牌、算奖用庄家36张;埋牌后直进出牌(删废弃step4) - 70分暗牌摸牌前向所有玩家亮3秒(+ancard3s),非70分不再泄露暗牌给闲家;叫分上限≤70 查牌/亮牌(§8.2/§9) - 新增亮牌 get_liangpai(庄家埋牌后28张按阈值统计);报无主统计与亮牌按查牌位门控 - 新增 mingpai 明牌 RPC(可查牌+已报无主时查看他家全部主牌) 房间与配置(§10) - 局数6/12、房主扣卡2/4;新增 class.config.js 以位串解析 roomtype(唯一入口 SSOT) - 清理 do_choiceflower 死代码 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
210 lines
7.2 KiB
JavaScript
210 lines
7.2 KiB
JavaScript
///////////////////////////////////////////////////
|
||
/////// cls_youle_erqiwang_export: 输出接口 ///////
|
||
///////////////////////////////////////////////////
|
||
var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
|
||
|
||
new: function() {
|
||
|
||
var exp = {};
|
||
|
||
//解析roomtype获取开房所需房卡(design §10.1)
|
||
exp.get_needroomcard = function(roomtype){
|
||
var cfg = cls_youle_erqiwang_config.parse(roomtype);
|
||
if (cfg.deductAA){
|
||
//AA每人扣卡:6局每人1张 / 12局每人2张
|
||
return cfg.aset12 ? 2 : 1;
|
||
}
|
||
//房主扣卡:6局2张 / 12局4张
|
||
return cfg.aset12 ? 4 : 2;
|
||
}
|
||
|
||
//解析roomtype获取总局数(design §10.1:6局 / 12局)
|
||
exp.get_asetcount = function(roomtype){
|
||
var cfg = cls_youle_erqiwang_config.parse(roomtype);
|
||
return cfg.aset12 ? 12 : 6;
|
||
}
|
||
|
||
//加入房间时根据roomtype获取需要的房卡数量
|
||
exp.get_needroomcard_joinroom = function(roomtype){
|
||
var cfg = cls_youle_erqiwang_config.parse(roomtype);
|
||
if (cfg.deductAA){
|
||
//AA每人扣卡:加入者按自己那份扣(6局1张 / 12局2张)
|
||
return cfg.aset12 ? 2 : 1;
|
||
}
|
||
//房主扣卡:加入者不扣
|
||
return 0;
|
||
}
|
||
|
||
//开战
|
||
exp.makewar = function(o_room){
|
||
//牌桌对象
|
||
o_room.o_desk = cls_youle_erqiwang_desk.new(o_room);
|
||
for (var i = 0; i < o_room.seatlist.length; i++) {
|
||
o_room.seatlist[i].gameinfo.isbet = 1;
|
||
}
|
||
|
||
//开始第一局
|
||
var do_newpaiju = function(){
|
||
o_room.o_desk.method.do_new_paiju(0);
|
||
}
|
||
min_ontimeout(do_newpaiju, 1000);
|
||
}
|
||
|
||
//获取某个玩家的牌桌整桌当前信息
|
||
exp.get_deskinfo = function(o_room, seat){
|
||
if (!o_room.o_desk){
|
||
return null;
|
||
}
|
||
var paiju = o_room.o_desk.method.curr_paiju();
|
||
var deskinfo = {};
|
||
deskinfo.count = o_room.asetcount; //总局数
|
||
deskinfo.idx = paiju.idx; //当前局数
|
||
deskinfo.PlayerInfo = []; //玩家当前累积得分
|
||
for (var i = 0; i < o_room.o_desk.seatlist.length; i++) {
|
||
deskinfo.PlayerInfo.push(o_room.o_desk.seatlist[i][0]);
|
||
};
|
||
deskinfo.step = paiju.step; //牌局状态
|
||
deskinfo.MyCards = paiju.method.get_seat_cards(seat); //我手上的牌
|
||
switch (paiju.step){
|
||
case 1: //发完牌叫分
|
||
deskinfo.CallRun = {};
|
||
//当前叫分位置
|
||
deskinfo.CallRun.seat = paiju.method.get_callgrade_seat();
|
||
//叫分倒计时
|
||
deskinfo.CallRun.countdown = o_room.o_desk.method.get_countdown_jiaofen();
|
||
//当前叫分
|
||
deskinfo.CallRun.nowcall = paiju.method.get_callgrade_value();
|
||
//当前叫分倍数
|
||
deskinfo.CallRun.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(deskinfo.CallRun.nowcall);
|
||
//所有玩家的叫分情况
|
||
deskinfo.CallRun.call = [null, null, null];
|
||
deskinfo.CallRun.call[0] = paiju.method.get_seat_callgrade(0);
|
||
deskinfo.CallRun.call[1] = paiju.method.get_seat_callgrade(1);
|
||
deskinfo.CallRun.call[2] = paiju.method.get_seat_callgrade(2);
|
||
break;
|
||
case 2: //选主
|
||
deskinfo.ChooseMain = {};
|
||
//庄家
|
||
deskinfo.ChooseMain.banker = paiju.banker;
|
||
//庄家叫分
|
||
deskinfo.ChooseMain.call = paiju.call;
|
||
//庄家叫分倍数
|
||
deskinfo.ChooseMain.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call);
|
||
//选主倒计时
|
||
deskinfo.ChooseMain.countdown = o_room.o_desk.method.get_countdown_xuanzhu();
|
||
//底牌:暗牌只有庄家可见(70分的3秒亮牌是上庄时的一次性事件,重连不重放)
|
||
if (seat == paiju.banker){
|
||
deskinfo.ChooseMain.bottomcards = paiju.method.get_bottomcards();
|
||
}
|
||
//是否可投降
|
||
if (paiju.call != 70){
|
||
deskinfo.ChooseMain.touxiang = 0;
|
||
} else {
|
||
deskinfo.ChooseMain.touxiang = 1;
|
||
}
|
||
break;
|
||
case 3: //埋牌
|
||
deskinfo.BuryCards = {};
|
||
//庄家
|
||
deskinfo.BuryCards.banker = paiju.banker;
|
||
//庄家叫分
|
||
deskinfo.BuryCards.call = paiju.call;
|
||
//庄家叫分倍数
|
||
deskinfo.BuryCards.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call);
|
||
//埋牌倒计时
|
||
deskinfo.BuryCards.countdown = o_room.o_desk.method.get_countdown_maipai();
|
||
//底牌:暗牌只有庄家可见
|
||
if (seat == paiju.banker){
|
||
deskinfo.BuryCards.bottomcards = paiju.method.get_bottomcards();
|
||
}
|
||
//主牌花色
|
||
deskinfo.BuryCards.flower = paiju.flower;
|
||
//埋牌阶段无投降(投降是选主阶段与选主互斥的选择)
|
||
break;
|
||
case 5: //出牌
|
||
deskinfo.PushCards = {};
|
||
//庄家
|
||
deskinfo.PushCards.banker = paiju.banker;
|
||
//庄家叫分
|
||
deskinfo.PushCards.call = paiju.call;
|
||
//庄家叫分倍数
|
||
deskinfo.PushCards.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call);
|
||
//出牌倒计时
|
||
deskinfo.PushCards.countdown = o_room.o_desk.method.get_countdown_chupai();
|
||
//主牌花色
|
||
deskinfo.PushCards.flower = paiju.flower;
|
||
//捡分
|
||
var jian_grade = paiju.method.get_jian_grade();
|
||
if (seat == paiju.banker){
|
||
//埋的牌
|
||
deskinfo.PushCards.bottomcards = paiju.method.get_burycard();
|
||
} else {
|
||
//闲家当前的捡分分牌
|
||
deskinfo.PushCards.gradecards = jian_grade.cards;
|
||
}
|
||
//闲家当前的捡分分数
|
||
deskinfo.PushCards.grade = jian_grade.grade;
|
||
//当前的出牌情况
|
||
deskinfo.PushCards.playproc = paiju.playproc;
|
||
//座位列表(报副统计)与亮牌:仅可查牌模式下展示(§9/§8.2)
|
||
if (!cls_youle_erqiwang_config.parse(o_room.roomtype).nocheck){
|
||
deskinfo.PushCards.seatlist = paiju.seatlist;
|
||
if (seat != paiju.banker){
|
||
var _lp = paiju.method.get_liangpai();
|
||
if (_lp){
|
||
deskinfo.PushCards.liangpai = _lp;
|
||
}
|
||
}
|
||
}
|
||
//出牌历史
|
||
deskinfo.PushCards.pushlist = [];
|
||
for (var i = 0; i < paiju.cards.length; i++) {
|
||
var pai = paiju.cards[i];
|
||
if (pai.playround > 0){
|
||
if (deskinfo.PushCards.pushlist.length < pai.playround){
|
||
deskinfo.PushCards.pushlist.length = pai.playround;
|
||
}
|
||
if (!deskinfo.PushCards.pushlist[pai.playround - 1]){
|
||
deskinfo.PushCards.pushlist[pai.playround - 1] = [[], [], []];
|
||
}
|
||
|
||
var owner = pai.dealowner;
|
||
if (owner == 0){
|
||
owner = paiju.banker + 1;
|
||
}
|
||
deskinfo.PushCards.pushlist[pai.playround - 1][owner - 1].push(i);
|
||
}
|
||
}
|
||
//按大小排序
|
||
for (var i = 0; i < deskinfo.PushCards.pushlist.length; i++) {
|
||
for (var j = 0; j < deskinfo.PushCards.pushlist.length; j++) {
|
||
deskinfo.PushCards.pushlist[i][j] = cls_youle_erqiwang_arith.order_cards(pai.flower, deskinfo.PushCards.pushlist[i][j]);
|
||
}
|
||
}
|
||
break;
|
||
case 6: //结算
|
||
deskinfo.Balance = {};
|
||
//玩家的准备状态
|
||
deskinfo.Balance.readystate = o_room.o_desk.prepare;
|
||
if (o_room.o_desk.prepare[seat] == 0){
|
||
//结算情况
|
||
deskinfo.Balance.aset = paiju.tmp_jiesuan_aset;
|
||
}
|
||
break;
|
||
}
|
||
|
||
return deskinfo;
|
||
}
|
||
|
||
//解散房间
|
||
exp.get_disbandRoom = function(o_room){
|
||
var msg = {};
|
||
return o_room.o_desk.method.curr_paiju().method.get_paiju_account(2, msg);
|
||
}
|
||
|
||
return exp;
|
||
}
|
||
}
|
||
|
||
//对内输出接口
|
||
youle_erqiwang.export = cls_youle_erqiwang_export.new(); |