二七王:拖拉机极大连续段扫描与牌编码区间常量收敛进 shared
前后端此前各写了一遍「分对子 → is_continuous 扫极大连续段 → ≥2 对算拖拉机」: 服务端 class.arith.js decompose_trump 与前端 core/CardMark.js。规则内容(什么算连续、 几对起算拖拉机)散在两处,正是 shared/ 要消除的重复。 - shared/cards.js 新增 group_tractor_runs(mainflower, pairlist):返回极大连续段数组, 孤立对子作为长度 1 的段返回,拼接后恰好还原入参;阈值导出为 TRACTOR_MIN_PAIRS。 - shared/cards.js 导出牌编码区间边界具名常量(CODE_ZHU_MIN / CODE_ZHENG2_* / CODE_FU2_* / CODE_ZHENG7_* / CODE_FU7_* / CODE_XIAOWANG / CODE_DAWANG / CODE_A_IN_ZHU),并在 id_to_code / is_continuous / trump_rank 内部改用它们。 - decompose_trump 改调共享扫描,对外行为完全不变(分量类型、顺序、cards 归属不变)。 - CardMark 删掉本地扫描改调共享版本,区间判定与标记值改引用常量,去掉 1000/3000/ 4000/8000/9000 裸字面量。 - 前端副本经 sync_shared.cmd 同步;服务端单测 624→645 checks 全绿,前端 8 个测试全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,31 +64,32 @@ var cls_youle_erqiwang_arith = cls_youle_erqiwang_arith || {
|
||||
return 40;
|
||||
},
|
||||
|
||||
//以下 8 项为前后端共享算法,权威实现在 shared/cards.js(经 sync_shared.cmd 同步到前端)。
|
||||
//以下 9 项为前后端共享算法,权威实现在 shared/cards.js(经 sync_shared.cmd 同步到前端)。
|
||||
//此处只挂引用:对外方法名与签名不变,全部既有调用点无需改动。
|
||||
id_to_flower: youle_erqiwang_shared_cards.id_to_flower,
|
||||
id_to_number: youle_erqiwang_shared_cards.id_to_number,
|
||||
id_to_code: youle_erqiwang_shared_cards.id_to_code,
|
||||
order_cards: youle_erqiwang_shared_cards.order_cards,
|
||||
is_continuous: youle_erqiwang_shared_cards.is_continuous,
|
||||
get_pairlist: youle_erqiwang_shared_cards.get_pairlist,
|
||||
get_tuolaji_list: youle_erqiwang_shared_cards.get_tuolaji_list,
|
||||
trump_rank: youle_erqiwang_shared_cards.trump_rank,
|
||||
id_to_flower: youle_erqiwang_shared_cards.id_to_flower,
|
||||
id_to_number: youle_erqiwang_shared_cards.id_to_number,
|
||||
id_to_code: youle_erqiwang_shared_cards.id_to_code,
|
||||
order_cards: youle_erqiwang_shared_cards.order_cards,
|
||||
is_continuous: youle_erqiwang_shared_cards.is_continuous,
|
||||
get_pairlist: youle_erqiwang_shared_cards.get_pairlist,
|
||||
group_tractor_runs: youle_erqiwang_shared_cards.group_tractor_runs,
|
||||
get_tuolaji_list: youle_erqiwang_shared_cards.get_tuolaji_list,
|
||||
trump_rank: youle_erqiwang_shared_cards.trump_rank,
|
||||
|
||||
//把一组主牌分解为分量列表(design §5.4.3/§5.4.4)
|
||||
//返回 [{type:'single'|'pair'|'tractor', len, value, cards:[]}...],value 为该分量最大牌的归一化 rank
|
||||
decompose_trump: function(mainflower, cards){
|
||||
var ordered = cls_youle_erqiwang_arith.order_cards(mainflower, cards.concat());
|
||||
//先分出对子与单张
|
||||
var pairs = []; //{code, cards:[id,id]}
|
||||
var singles = []; //{card}
|
||||
//先分出对子与单张(对子形状与 shared get_pairlist 一致:[id, id])
|
||||
var pairs = []; //[[id,id], ...]
|
||||
var singles = []; //[id, ...]
|
||||
var i = 0;
|
||||
while (i < ordered.length){
|
||||
var code_i = cls_youle_erqiwang_arith.id_to_code(mainflower, ordered[i]);
|
||||
if (i + 1 < ordered.length){
|
||||
var code_n = cls_youle_erqiwang_arith.id_to_code(mainflower, ordered[i + 1]);
|
||||
if (code_i == code_n){
|
||||
pairs.push({code: code_i, cards: [ordered[i], ordered[i + 1]]});
|
||||
pairs.push([ordered[i], ordered[i + 1]]);
|
||||
i = i + 2;
|
||||
continue;
|
||||
}
|
||||
@@ -96,26 +97,21 @@ var cls_youle_erqiwang_arith = cls_youle_erqiwang_arith || {
|
||||
singles.push(ordered[i]);
|
||||
i++;
|
||||
}
|
||||
//连续对子组成拖拉机,其余为单独对子
|
||||
//连续对子组成拖拉机,其余为单独对子。极大连续段的扫描是前后端共享算法(shared/cards.js),
|
||||
//此处只负责把段翻译成分量,不再自己实现「什么算连续、几对起算拖拉机」
|
||||
var runs = youle_erqiwang_shared_cards.group_tractor_runs(mainflower, pairs);
|
||||
var comps = [];
|
||||
var j = 0;
|
||||
while (j < pairs.length){
|
||||
var run = [pairs[j]];
|
||||
var k = j;
|
||||
while (k + 1 < pairs.length && cls_youle_erqiwang_arith.is_continuous(pairs[k].code, pairs[k + 1].code)){
|
||||
run.push(pairs[k + 1]);
|
||||
k++;
|
||||
for (var j = 0; j < runs.length; j++){
|
||||
var run = runs[j];
|
||||
var tcards = [];
|
||||
for (var r = 0; r < run.length; r++){
|
||||
tcards = tcards.concat(run[r]);
|
||||
}
|
||||
if (run.length >= 2){
|
||||
var tcards = [];
|
||||
for (var r = 0; r < run.length; r++){
|
||||
tcards = tcards.concat(run[r].cards);
|
||||
}
|
||||
comps.push({type: "tractor", len: run.length, value: cls_youle_erqiwang_arith.trump_rank(mainflower, run[0].cards[0]), cards: tcards});
|
||||
if (run.length >= youle_erqiwang_shared_cards.TRACTOR_MIN_PAIRS){
|
||||
comps.push({type: "tractor", len: run.length, value: cls_youle_erqiwang_arith.trump_rank(mainflower, run[0][0]), cards: tcards});
|
||||
} else {
|
||||
comps.push({type: "pair", len: 1, value: cls_youle_erqiwang_arith.trump_rank(mainflower, run[0].cards[0]), cards: run[0].cards});
|
||||
comps.push({type: "pair", len: 1, value: cls_youle_erqiwang_arith.trump_rank(mainflower, run[0][0]), cards: tcards});
|
||||
}
|
||||
j = k + 1;
|
||||
}
|
||||
for (var s = 0; s < singles.length; s++){
|
||||
comps.push({type: "single", len: 1, value: cls_youle_erqiwang_arith.trump_rank(mainflower, singles[s]), cards: [singles[s]]});
|
||||
|
||||
Reference in New Issue
Block a user