二七王服务端:按 design.md 整改结算/算奖/甩牌,roomtype 改位串
结算与算奖(§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>
This commit is contained in:
+109
-14
@@ -4,6 +4,8 @@
|
||||
|
||||
var youle_erqiwang = youle_erqiwang || cls_mod.new("youle_erqiwang", "erqiwang", youle_app);
|
||||
|
||||
//配置解析类(roomtype 位串解析,SSOT)
|
||||
min_loadJsFile("games/erqiwang/class.config.js", function(){
|
||||
//牌类
|
||||
min_loadJsFile("games/erqiwang/class.pai.js", function(){
|
||||
//牌局类
|
||||
@@ -23,6 +25,7 @@ min_loadJsFile("games/erqiwang/class.export.js", function(){
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//对内的输入接口类(需要的外部接口)
|
||||
youle_erqiwang.import = null;
|
||||
@@ -60,10 +63,10 @@ youle_erqiwang.jiaofen = function(pack){
|
||||
if (o_paiju.method.get_callgrade_seat() != seat){
|
||||
return;
|
||||
}
|
||||
//检查当前的叫分分值必须大于0,且是5的整数倍
|
||||
if (call < 0 || call % 5 != 0){
|
||||
//检查叫分:0(不叫)或 5~70 且为 5 的整数倍(design §4)
|
||||
if (call < 0 || call > 70 || call % 5 != 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
var curr_call = o_paiju.method.get_callgrade_value();
|
||||
//第一家不能不叫分
|
||||
if (curr_call == 0 && call == 0){
|
||||
@@ -106,21 +109,33 @@ youle_erqiwang.jiaofen = function(pack){
|
||||
msg.data.banker = o_paiju.banker;
|
||||
msg.data.grade = o_paiju.call;
|
||||
msg.data.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(msg.data.grade);
|
||||
msg.data.bottomcards = o_paiju.method.get_bottomcards();
|
||||
msg.data.countdown = o_desk.method.get_countdown_xuanzhu();
|
||||
if (o_paiju.call < 65){
|
||||
if (o_paiju.call != 70){
|
||||
msg.data.touxiang = 0;
|
||||
} else {
|
||||
msg.data.touxiang = 1;
|
||||
}
|
||||
|
||||
//70分坐庄:庄家摸暗牌前,8张暗牌向所有玩家亮3秒(design §4/§7.1)
|
||||
if (o_paiju.call == 70){
|
||||
msg.data.ancard3s = 1;
|
||||
}
|
||||
var _bottomcards = o_paiju.method.get_bottomcards();
|
||||
|
||||
for (var i = 0; i < o_room.seatlist.length; i++) {
|
||||
msg.conmode = o_room.seatlist[i].conmode;
|
||||
msg.fromid = o_room.seatlist[i].fromid;
|
||||
if (i == o_paiju.banker){
|
||||
//庄家:手牌(含摸起的暗牌)与暗牌本身都可见
|
||||
msg.data.cards = o_paiju.method.get_seat_cards(i);
|
||||
msg.data.bottomcards = _bottomcards;
|
||||
} else {
|
||||
delete msg.data.cards;
|
||||
//闲家:仅70分坐庄时才下发暗牌(供亮3秒),否则暗牌只有庄家可见
|
||||
if (o_paiju.call == 70){
|
||||
msg.data.bottomcards = _bottomcards;
|
||||
} else {
|
||||
delete msg.data.bottomcards;
|
||||
}
|
||||
}
|
||||
youle_erqiwang.app.SendPack(msg);
|
||||
}
|
||||
@@ -227,6 +242,13 @@ youle_erqiwang.maipai = function(pack){
|
||||
//埋牌成功
|
||||
o_paiju.method.do_burycard(cards);
|
||||
|
||||
//亮牌(design §8.2):可查牌模式下,出牌开始向两个闲家亮出庄家手牌统计
|
||||
var _cfg = cls_youle_erqiwang_config.parse(o_room.roomtype);
|
||||
var _liangpai = null;
|
||||
if (!_cfg.nocheck){
|
||||
_liangpai = o_paiju.method.get_liangpai();
|
||||
}
|
||||
|
||||
//返回前端
|
||||
var msg = {};
|
||||
msg.app = "youle";
|
||||
@@ -241,9 +263,16 @@ youle_erqiwang.maipai = function(pack){
|
||||
if (i == o_paiju.banker){
|
||||
msg.data.cards = o_paiju.method.get_seat_cards(i);
|
||||
msg.data.bottomcards = cards;
|
||||
delete msg.data.liangpai;
|
||||
} else {
|
||||
delete msg.data.cards;
|
||||
delete msg.data.bottomcards;
|
||||
//闲家:可查牌且庄家达标时亮牌
|
||||
if (_liangpai){
|
||||
msg.data.liangpai = _liangpai;
|
||||
} else {
|
||||
delete msg.data.liangpai;
|
||||
}
|
||||
}
|
||||
youle_erqiwang.app.SendPack(msg);
|
||||
}
|
||||
@@ -271,16 +300,16 @@ youle_erqiwang.touxiang = function(pack){
|
||||
if (!o_paiju){
|
||||
return;
|
||||
}
|
||||
//检查当前的游戏阶段是否是叫分、埋牌、投降阶段
|
||||
if (o_paiju.step != 2 && o_paiju.step != 3 && o_paiju.step != 4){
|
||||
//投降是选主阶段(step 2)与选主互斥的选择:点投降直接结算,不选主、不埋牌(design §4)
|
||||
if (o_paiju.step != 2){
|
||||
return;
|
||||
}
|
||||
//检查庄家位置
|
||||
if (o_paiju.banker != seat){
|
||||
return;
|
||||
}
|
||||
//检查是否允许投降
|
||||
if (o_paiju.call < 65){
|
||||
//仅 70 分坐庄可投降(design §4 / §7.1)
|
||||
if (o_paiju.call != 70){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -319,7 +348,7 @@ youle_erqiwang.chupai = function(pack){
|
||||
return;
|
||||
}
|
||||
//检查当前的游戏阶段是否是出牌阶段
|
||||
if (o_paiju.step != 4 && o_paiju.step != 5){
|
||||
if (o_paiju.step != 5){
|
||||
return;
|
||||
}
|
||||
//检查出牌位置
|
||||
@@ -341,17 +370,26 @@ youle_erqiwang.chupai = function(pack){
|
||||
return;
|
||||
}
|
||||
|
||||
//查牌模式(design §9):不查牌时不下发任何主牌统计(info/报无主)
|
||||
var _cfg = cls_youle_erqiwang_config.parse(o_room.roomtype);
|
||||
|
||||
//返回前端
|
||||
var msg = {};
|
||||
msg.app = "youle";
|
||||
msg.route = "erqiwang";
|
||||
msg.data = {};
|
||||
msg.data.seat = seat;
|
||||
msg.data.cards = cards;
|
||||
msg.data.info = o_paiju.seatlist[seat];
|
||||
msg.data.cards = re.cards ? re.cards : cards; //实际打出的牌(甩错时为单张)
|
||||
if (!_cfg.nocheck){
|
||||
msg.data.info = o_paiju.seatlist[seat]; //座位牌况(报副统计),仅可查牌下发
|
||||
}
|
||||
msg.data.nextseat = o_paiju.playproc.currseat;
|
||||
msg.data.countdown = o_desk.method.get_countdown_chupai();
|
||||
if (o_paiju.method.have_baofu()){
|
||||
if (re.shuaicuo){
|
||||
msg.data.shuaicuo = 1; //甩错:本次甩牌被收回,只打出了最小一张(§5.4.5)
|
||||
}
|
||||
//报无主:仅可查牌模式下才据此展示他家主牌数量/对子(§9)
|
||||
if (!_cfg.nocheck && o_paiju.method.have_baofu()){
|
||||
msg.data.baozhu = 1;
|
||||
} else {
|
||||
msg.data.baozhu = 0;
|
||||
@@ -421,6 +459,63 @@ youle_erqiwang.chupai = function(pack){
|
||||
}
|
||||
}
|
||||
|
||||
//明牌:查看另外两家手中全部主牌的具体牌面(design §9,仅可查牌模式且已有人报无主)
|
||||
youle_erqiwang.mingpai = function(pack){
|
||||
var agentid = pack.data.agentid;
|
||||
var playerid = parseInt(pack.data.playerid);
|
||||
var gameid = pack.data.gameid;
|
||||
var roomcode = parseInt(pack.data.roomcode);
|
||||
var seat = parseInt(pack.data.seat);
|
||||
//检查玩家的位置是否正确
|
||||
var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid);
|
||||
if (!o_room){
|
||||
return;
|
||||
}
|
||||
//牌桌
|
||||
var o_desk = o_room.o_desk;
|
||||
if (!o_desk){
|
||||
return;
|
||||
}
|
||||
//牌局
|
||||
var o_paiju = o_desk.method.curr_paiju();
|
||||
if (!o_paiju){
|
||||
return;
|
||||
}
|
||||
//只在出牌阶段
|
||||
if (o_paiju.step != 5){
|
||||
return;
|
||||
}
|
||||
//不查牌模式禁止明牌
|
||||
var cfg = cls_youle_erqiwang_config.parse(o_room.roomtype);
|
||||
if (cfg.nocheck){
|
||||
return;
|
||||
}
|
||||
//必须已有玩家报无主才允许明牌
|
||||
if (!o_paiju.method.have_baofu()){
|
||||
return;
|
||||
}
|
||||
|
||||
//另外两家未出的全部主牌,只回发给请求者
|
||||
var msg = {};
|
||||
msg.app = "youle";
|
||||
msg.route = "erqiwang";
|
||||
msg.rpc = "mingpai";
|
||||
msg.data = {};
|
||||
msg.data.seat = seat;
|
||||
msg.data.others = [];
|
||||
for (var i = 0; i < 3; i++){
|
||||
if (i != seat){
|
||||
var one = {};
|
||||
one.seat = i;
|
||||
one.zhucards = cls_youle_erqiwang_paiju.get_seat_zhucards(o_paiju, i);
|
||||
msg.data.others.push(one);
|
||||
}
|
||||
}
|
||||
msg.conmode = pack.conmode;
|
||||
msg.fromid = pack.fromid;
|
||||
youle_erqiwang.app.SendPack(msg);
|
||||
}
|
||||
|
||||
//准备
|
||||
youle_erqiwang.zhunbei = function(pack){
|
||||
var agentid = pack.data.agentid;
|
||||
|
||||
Reference in New Issue
Block a user