优化中奖权重计算方式

This commit is contained in:
2026-03-12 17:17:00 +08:00
parent 064ce06393
commit 7e4ba86afa
25 changed files with 2344 additions and 403 deletions

View File

@@ -12,7 +12,7 @@ use app\api\util\ReturnCode;
use app\dice\model\config\DiceConfig;
use app\dice\model\play_record\DicePlayRecord;
use app\dice\model\player\DicePlayer;
use app\dice\model\reward_config\DiceRewardConfig;
use app\dice\model\reward\DiceRewardConfig;
use app\api\controller\BaseController;
use app\api\util\ApiLang;
use plugin\saiadmin\exception\ApiException;

View File

@@ -10,7 +10,8 @@ use app\dice\model\play_record\DicePlayRecord;
use app\dice\model\player\DicePlayer;
use app\dice\model\player_ticket_record\DicePlayerTicketRecord;
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
use app\dice\model\reward_config\DiceRewardConfig;
use app\dice\model\reward\DiceReward;
use app\dice\model\reward\DiceRewardConfig;
use plugin\saiadmin\exception\ApiException;
use support\Log;
use support\think\Cache;
@@ -85,7 +86,9 @@ class PlayStartLogic
$safetyLine = (int) ($config->safety_line ?? 0);
$usePoolWeights = $poolProfit >= $safetyLine;
// 按档位 T1-T5 抽取后,直接按该档位内 weight 抽取一条 DiceRewardConfig得到 grid_number
// 按档位 T1-T5 抽取后,从 DiceReward 表按当前方向取该档位数据,再按 weight 抽取一条得到 grid_number
$rewardInstance = DiceReward::getCachedInstance();
$byTierDirection = $rewardInstance['by_tier_direction'] ?? [];
$maxTierRetry = 10;
$chosen = null;
$tier = null;
@@ -93,9 +96,9 @@ class PlayStartLogic
$tier = $usePoolWeights
? LotteryService::drawTierByWeights($config)
: LotteryService::drawTierByPlayerWeights($player);
$tierRewards = DiceRewardConfig::getCachedByTier($tier);
$tierRewards = $byTierDirection[$tier][$direction] ?? [];
if (empty($tierRewards)) {
Log::warning("档位 {$tier} 无任何奖励配置,重新摇取档位");
Log::warning("档位 {$tier} 方向 {$direction} 无任何 DiceReward,重新摇取档位");
continue;
}
try {
@@ -110,23 +113,18 @@ class PlayStartLogic
break;
}
if ($chosen === null) {
Log::error("多次摇取档位后仍无有效权重配置");
Log::error("多次摇取档位后仍无有效 DiceReward");
throw new ApiException('暂无可用奖励配置');
}
$chosenId = (int) ($chosen['id'] ?? 0);
// 起始索引:根据 direction 取 s_start_index(顺时针)或 n_start_index逆时针结束索引当前中奖配置 id
$startIndex = $direction === 0
? (int) ($chosen['s_start_index'] ?? 0)
: (int) ($chosen['n_start_index'] ?? 0);
$targetIndex = $chosenId;
$startIndex = (int) ($chosen['start_index'] ?? 0);
$targetIndex = (int) ($chosen['end_index'] ?? 0);
$rollNumber = (int) ($chosen['grid_number'] ?? 0);
$realEv = (float) ($chosen['real_ev'] ?? 0);
$isTierT5 = (string) ($chosen['tier'] ?? '') === 'T5';
// T5再来一次摇色子中奖平台币 = 配置的 real_ev其他档位 = 100 + real_ev
$rewardWinCoin = $isTierT5 ? $realEv : (100 + $realEv);
// 流程:先抽档位 T1-T5再按档位内权重抽色子点数5 和 30 抽到即豹子10/15/20/25 按 BIGWIN weight 判定是否中大奖(豹子如 [4,4,4,4,4]
// 豹子判定5/30 必豹子10/15/20/25 按 DiceRewardConfig 中 BIGWIN 该点数的 weight 判定0-1000010000=100%
$superWinCoin = 0;
$isWin = 0;
$bigWinRealEv = 0.0;
@@ -135,21 +133,26 @@ class PlayStartLogic
$alwaysSuperWin = in_array($rollNumber, self::SUPER_WIN_ALWAYS_GRID_NUMBERS, true);
$doSuperWin = $alwaysSuperWin;
if (!$doSuperWin) {
$weight = $bigWinConfig !== null
? max(1, min(10000, (int) ($bigWinConfig['weight'] ?? 1)))
: 10000;
$bigWinWeight = 10000;
if ($bigWinConfig !== null && isset($bigWinConfig['weight'])) {
$bigWinWeight = min(10000, max(0, (int) $bigWinConfig['weight']));
$bigWinRealEv = (float) ($bigWinConfig['real_ev'] ?? 0);
}
$roll = (random_int(0, PHP_INT_MAX - 1) / (float) PHP_INT_MAX);
$doSuperWin = $roll < ($weight / 10000.0);
$doSuperWin = $bigWinWeight > 0 && $roll < ($bigWinWeight / 10000.0);
} else {
if ($bigWinConfig !== null) {
$bigWinRealEv = (float) ($bigWinConfig['real_ev'] ?? 0);
}
}
if ($doSuperWin) {
$rollArray = $this->getSuperWinRollArray($rollNumber);
$isWin = 1;
if ($bigWinConfig !== null) {
$bigWinRealEv = (float) ($bigWinConfig['real_ev'] ?? 0);
$superWinCoin = $bigWinRealEv;
} else {
$superWinCoin = self::SUPER_WIN_BONUS;
}
$superWinCoin = $bigWinRealEv > 0 ? $bigWinRealEv : self::SUPER_WIN_BONUS;
// 中 BIGWIN 豹子:不走原奖励流程,不记录原奖励,不触发 T5 再来一次,仅发放豹子奖金
$rewardWinCoin = 0;
$realEv = 0;
$isTierT5 = false;
} else {
$rollArray = $this->generateNonSuperWinRollArrayWithSum($rollNumber);
}
@@ -164,11 +167,11 @@ class PlayStartLogic
$startIndex,
$targetIndex
));
$winCoin = $superWinCoin + $rewardWinCoin; // 赢取平台币 = 中大奖 + 摇色子中奖
$winCoin = $superWinCoin + $rewardWinCoin; // 赢取平台币 = 中大奖 + 摇色子中奖(豹子时 rewardWinCoin 已为 0
$record = null;
$configId = (int) $config->id;
$rewardId = $chosenId;
$rewardId = ($isWin === 1 && $superWinCoin > 0) ? 0 : $targetIndex; // 中豹子不记录原奖励配置 id
$configName = (string) ($config->name ?? '');
$adminId = ($player->admin_id ?? null) ? (int) $player->admin_id : null;
try {