优化彩金池杀分逻辑-根据彩金池玩家盈利判断而非玩家个人盈利判断

This commit is contained in:
2026-03-20 15:25:45 +08:00
parent ca620eb536
commit 8702cb0571
2 changed files with 21 additions and 30 deletions

View File

@@ -77,23 +77,14 @@ class PlayStartLogic
throw new ApiException('Lottery pool config not found (name=default required)');
}
// 玩家累计盈利:仅统计 lottery_config_id=default 的成功对局。
// 付费券:盈利按 win_coin - 100/局计算;免费券:不扣除 100/局,只计入 win_coin。
$playerQuery = DicePlayRecord::where('player_id', $playerId)
->where('lottery_config_id', $configType0->id)
->where('status', self::RECORD_STATUS_SUCCESS);
$playerWinSum = (float) $playerQuery->sum('win_coin');
$paidPlayCount = (int) DicePlayRecord::where('player_id', $playerId)
->where('lottery_config_id', $configType0->id)
->where('lottery_type', self::LOTTERY_TYPE_PAID)
->where('status', self::RECORD_STATUS_SUCCESS)
->count();
$playerProfitTotal = $playerWinSum - 100.0 * $paidPlayCount;
// 彩金池累计盈利:用于判断是否触发杀分(不再依赖单个玩家累计盈利)
// 该值来自 dice_lottery_pool_config.profit_amount
$poolProfitTotal = $configType0->profit_amount ?? 0;
$safetyLine = (int) ($configType0->safety_line ?? 0);
$killEnabled = ((int) ($configType0->kill_enabled ?? 1)) === 1;
// 盈利>=安全线且开启杀分:付费/免费都用 killScore盈利<安全线:付费用玩家权重,免费用 killScore无则用 default
// 记录 lottery_config_id用池权重时记对应池付费用玩家权重时记 default
$usePoolWeights = ($ticketType === self::LOTTERY_TYPE_PAID && $killEnabled && $playerProfitTotal >= $safetyLine && $configType1 !== null)
$usePoolWeights = ($ticketType === self::LOTTERY_TYPE_PAID && $killEnabled && $poolProfitTotal >= $safetyLine && $configType1 !== null)
|| ($ticketType === self::LOTTERY_TYPE_FREE);
$config = $usePoolWeights
? (($ticketType === self::LOTTERY_TYPE_FREE && $configType1 === null) ? $configType0 : $configType1)
@@ -274,8 +265,10 @@ class PlayStartLogic
$p->save();
// 玩家累计盈利累加在 type=0 彩金池上:每局按“当前中奖金额(含 BIGWIN - 抽奖券费用 100”
$perPlayProfit = $winCoin - 100.0;
// 彩金池累计盈利累加在 name=default 彩金池上:
// 付费券:每局按“当前中奖金额(含 BIGWIN - 抽奖券费用 100”
// 免费券:取消票价成本 100只计入中奖金额
$perPlayProfit = ($ticketType === self::LOTTERY_TYPE_PAID) ? ($winCoin - 100.0) : $winCoin;
$addProfit = $perPlayProfit;
try {
DiceLotteryPoolConfig::where('id', $type0ConfigId)->update([

View File

@@ -80,9 +80,8 @@ class WeightTestRunner
DiceRewardConfig::clearRequestInstance();
DiceReward::clearRequestInstance();
//“玩家”盈利:仅统计 lottery_config_id=default 的成功对局。
// 付费券:盈利 = win_coin - 100/局;免费券:盈利 = win_coin不扣除 100/局)
$playerProfitTotal = 0.0;
// 彩金池累计盈利:用于判断是否触发杀分(不再依赖单个玩家累计盈利)
$poolProfitTotal = $configType0->profit_amount ?? 0;
$playLogic = new PlayStartLogic();
$resultCounts = [];
@@ -92,22 +91,22 @@ class WeightTestRunner
try {
for ($i = 0; $i < $paidS; $i++) {
$usePoolWeights = $killEnabled && $playerProfitTotal >= $safetyLine && $configType1 !== null;
$usePoolWeights = $killEnabled && $poolProfitTotal >= $safetyLine && $configType1 !== null;
$paidConfig = $usePoolWeights ? $configType1 : $configType0;
$customWeights = $usePoolWeights ? null : $paidTierWeights;
$row = $playLogic->simulateOnePlay($paidConfig, 0, 0, $customWeights);
$this->accumulateProfitForDefault($row, 0, $paidConfig, $configType0, $playerProfitTotal);
$this->accumulateProfitForDefault($row, 0, $paidConfig, $configType0, $poolProfitTotal);
$this->aggregate($row, $resultCounts, $tierCounts);
$buffer[] = $this->rowForInsert($row, $recordId);
$done++;
$this->flushIfNeeded($buffer, $recordId, $done, $total, $resultCounts, $tierCounts);
}
for ($i = 0; $i < $paidN; $i++) {
$usePoolWeights = $killEnabled && $playerProfitTotal >= $safetyLine && $configType1 !== null;
$usePoolWeights = $killEnabled && $poolProfitTotal >= $safetyLine && $configType1 !== null;
$paidConfig = $usePoolWeights ? $configType1 : $configType0;
$customWeights = $usePoolWeights ? null : $paidTierWeights;
$row = $playLogic->simulateOnePlay($paidConfig, 1, 0, $customWeights);
$this->accumulateProfitForDefault($row, 0, $paidConfig, $configType0, $playerProfitTotal);
$this->accumulateProfitForDefault($row, 0, $paidConfig, $configType0, $poolProfitTotal);
$this->aggregate($row, $resultCounts, $tierCounts);
$buffer[] = $this->rowForInsert($row, $recordId);
$done++;
@@ -115,7 +114,7 @@ class WeightTestRunner
}
for ($i = 0; $i < $freeS; $i++) {
$row = $playLogic->simulateOnePlay($freeConfig, 0, 1, null);
$this->accumulateProfitForDefault($row, 1, $freeConfig, $configType0, $playerProfitTotal);
$this->accumulateProfitForDefault($row, 1, $freeConfig, $configType0, $poolProfitTotal);
$this->aggregate($row, $resultCounts, $tierCounts);
$buffer[] = $this->rowForInsert($row, $recordId);
$done++;
@@ -123,7 +122,7 @@ class WeightTestRunner
}
for ($i = 0; $i < $freeN; $i++) {
$row = $playLogic->simulateOnePlay($freeConfig, 1, 1, null);
$this->accumulateProfitForDefault($row, 1, $freeConfig, $configType0, $playerProfitTotal);
$this->accumulateProfitForDefault($row, 1, $freeConfig, $configType0, $poolProfitTotal);
$this->aggregate($row, $resultCounts, $tierCounts);
$buffer[] = $this->rowForInsert($row, $recordId);
$done++;
@@ -142,20 +141,19 @@ class WeightTestRunner
}
/**
* 仅当使用 default 池lottery_config_id=default时累加玩家盈利,与 PlayStartLogic 一致
* 累加彩金池累计盈利,用于触发杀分,与 PlayStartLogic 一致
* @param int $lotteryType 0=付费券1=免费券
* @param object $usedConfig 本次使用的奖池配置
* @param object $usedConfig 本次使用的奖池配置(仅用于校验非空)
* @param object $configType0 name=default 的彩金池
* @param float $playerProfitTotal 实际为“彩金池累计盈利”滚动值
*/
private function accumulateProfitForDefault(array $row, int $lotteryType, $usedConfig, $configType0, float &$playerProfitTotal): void
{
if (($lotteryType !== 0 && $lotteryType !== 1) || $usedConfig === null || $configType0 === null || !isset($row['win_coin'])) {
return;
}
if ((int) $usedConfig->id === (int) $configType0->id) {
$winCoin = (float) $row['win_coin'];
$playerProfitTotal += $lotteryType === 0 ? ($winCoin - 100.0) : $winCoin;
}
$winCoin = (float) $row['win_coin'];
$playerProfitTotal += $lotteryType === 0 ? ($winCoin - 100.0) : $winCoin;
}
private function aggregate(array $row, array &$resultCounts, array &$tierCounts): void