Initial commit: 投注游戏平台初始化
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
namespace App\Core;
|
||||
|
||||
class PK10Algorithm implements GameAlgorithmInterface {
|
||||
|
||||
/**
|
||||
* 生成随机开奖结果 (1-10的排列)
|
||||
*/
|
||||
public static function generateResult(): array {
|
||||
$cars = range(1, 10);
|
||||
shuffle($cars);
|
||||
return $cars; // index 0=冠军, 1=亚军, ..., 9=第十名
|
||||
}
|
||||
|
||||
/**
|
||||
* 带放水机制的开奖结果生成
|
||||
* @param array $bets 当期所有投注 [{bet_type, bet_target, amount, odds}, ...]
|
||||
* @param array $waterConfig [{bet_type => win_rate_pct}, ...]
|
||||
* @param int $attempts 最大尝试次数
|
||||
*/
|
||||
public static function generateControlledResult(array $bets, array $waterConfig, int $attempts = 100): array {
|
||||
if (empty($bets) || empty($waterConfig)) {
|
||||
return self::generateResult();
|
||||
}
|
||||
|
||||
$bestResult = null;
|
||||
$bestProfit = PHP_INT_MIN;
|
||||
|
||||
for ($i = 0; $i < $attempts; $i++) {
|
||||
$result = self::generateResult();
|
||||
$profit = self::calculatePlatformProfit($result, $bets);
|
||||
|
||||
// 选择平台利润最高的结果
|
||||
if ($profit > $bestProfit) {
|
||||
$bestProfit = $profit;
|
||||
$bestResult = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $bestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算某个开奖结果下平台的利润
|
||||
*/
|
||||
public static function calculatePlatformProfit(array $result, array $bets): float {
|
||||
$totalBet = 0;
|
||||
$totalPayout = 0;
|
||||
foreach ($bets as $bet) {
|
||||
$amount = (float)$bet['amount'];
|
||||
$totalBet += $amount;
|
||||
if (self::checkWin($result, $bet['bet_type'], $bet['bet_target'])) {
|
||||
$totalPayout += $amount + $amount * (float)$bet['odds'];
|
||||
}
|
||||
}
|
||||
return $totalBet - $totalPayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心中奖判定
|
||||
* @param array $result 开奖排名 [冠军车号, 亚军车号, ..., 第十名车号]
|
||||
* @param string $betType 投注类型: rank/bs/oe/dt/sum/sum_bs
|
||||
* @param string $betTarget 投注目标: rank1_5/rank1_big/dt1_dragon/sum_11/sum_big...
|
||||
*/
|
||||
public static function checkWin(array $result, string $betType, string $betTarget): bool {
|
||||
switch ($betType) {
|
||||
case 'rank': return self::checkRank($result, $betTarget);
|
||||
case 'bs': return self::checkBigSmall($result, $betTarget);
|
||||
case 'oe': return self::checkOddEven($result, $betTarget);
|
||||
case 'dt': return self::checkDragonTiger($result, $betTarget);
|
||||
case 'sum': return self::checkSum($result, $betTarget);
|
||||
case 'sum_bs': return self::checkSumBigSmall($result, $betTarget);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 名次投注: rank{N}_{carNo} 如 rank1_5 = 冠军是5号车
|
||||
private static function checkRank(array $r, string $target): bool {
|
||||
if (!preg_match('/^rank(\d+)_(\d+)$/', $target, $m)) return false;
|
||||
$pos = (int)$m[1] - 1; // 0-indexed
|
||||
$car = (int)$m[2];
|
||||
return isset($r[$pos]) && $r[$pos] === $car;
|
||||
}
|
||||
|
||||
// 大小: rank{N}_big/small, 车号>=6为大, <=5为小
|
||||
private static function checkBigSmall(array $r, string $target): bool {
|
||||
if (!preg_match('/^rank(\d+)_(big|small)$/', $target, $m)) return false;
|
||||
$pos = (int)$m[1] - 1;
|
||||
if (!isset($r[$pos])) return false;
|
||||
$car = $r[$pos];
|
||||
return $m[2] === 'big' ? $car >= 6 : $car <= 5;
|
||||
}
|
||||
|
||||
// 单双: rank{N}_odd/even
|
||||
private static function checkOddEven(array $r, string $target): bool {
|
||||
if (!preg_match('/^rank(\d+)_(odd|even)$/', $target, $m)) return false;
|
||||
$pos = (int)$m[1] - 1;
|
||||
if (!isset($r[$pos])) return false;
|
||||
$car = $r[$pos];
|
||||
return $m[2] === 'odd' ? ($car % 2 === 1) : ($car % 2 === 0);
|
||||
}
|
||||
|
||||
// 龙虎: dt{N}_dragon/tiger, N=1-5, 对应 1vs10, 2vs9, 3vs8, 4vs7, 5vs6
|
||||
private static function checkDragonTiger(array $r, string $target): bool {
|
||||
if (!preg_match('/^dt(\d)_(dragon|tiger)$/', $target, $m)) return false;
|
||||
$pair = (int)$m[1]; // 1-5
|
||||
$frontPos = $pair - 1; // 0,1,2,3,4
|
||||
$backPos = 10 - $pair; // 9,8,7,6,5
|
||||
if (!isset($r[$frontPos], $r[$backPos])) return false;
|
||||
$front = $r[$frontPos];
|
||||
$back = $r[$backPos];
|
||||
if ($front === $back) return false; // 和局(PK10不会出现)
|
||||
return $m[2] === 'dragon' ? $front > $back : $front < $back;
|
||||
}
|
||||
|
||||
// 冠亚和值: sum_{3-19}
|
||||
private static function checkSum(array $r, string $target): bool {
|
||||
if (!preg_match('/^sum_(\d+)$/', $target, $m)) return false;
|
||||
$sumVal = $r[0] + $r[1]; // 冠军+亚军
|
||||
return $sumVal === (int)$m[1];
|
||||
}
|
||||
|
||||
// 冠亚和大小单双: sum_big/small/odd/even, 和>=12为大, <=11为小
|
||||
private static function checkSumBigSmall(array $r, string $target): bool {
|
||||
$sumVal = $r[0] + $r[1];
|
||||
switch ($target) {
|
||||
case 'sum_big': return $sumVal >= 12;
|
||||
case 'sum_small': return $sumVal <= 11;
|
||||
case 'sum_odd': return $sumVal % 2 === 1;
|
||||
case 'sum_even': return $sumVal % 2 === 0;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名次中文/英文名称
|
||||
*/
|
||||
public static function getRankName(int $pos): string {
|
||||
$names = [1=>'champion',2=>'runner_up',3=>'rank_n',4=>'rank_n',5=>'rank_n',
|
||||
6=>'rank_n',7=>'rank_n',8=>'rank_n',9=>'rank_n',10=>'rank_n'];
|
||||
return $names[$pos] ?? 'rank_n';
|
||||
}
|
||||
|
||||
/**
|
||||
* 龙虎对应关系
|
||||
*/
|
||||
public static function getDragonTigerPairs(): array {
|
||||
return [
|
||||
1 => [1, 10], // 第1名 vs 第10名
|
||||
2 => [2, 9],
|
||||
3 => [3, 8],
|
||||
4 => [4, 7],
|
||||
5 => [5, 6],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 期号生成
|
||||
*/
|
||||
public static function generatePeriodNumber(int $gameId): string {
|
||||
return 'PK' . $gameId . date('Ymd') . str_pad(mt_rand(1, 9999), 4, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
public static function getResultTable(): ?string { return 'pk10_results'; }
|
||||
|
||||
public static function formatResultForStorage(array $result, int $periodId): array {
|
||||
return [
|
||||
'period_id' => $periodId,
|
||||
'rank_1' => $result[0], 'rank_2' => $result[1], 'rank_3' => $result[2],
|
||||
'rank_4' => $result[3], 'rank_5' => $result[4], 'rank_6' => $result[5],
|
||||
'rank_7' => $result[6], 'rank_8' => $result[7], 'rank_9' => $result[8],
|
||||
'rank_10' => $result[9], 'champion_sum' => $result[0] + $result[1],
|
||||
];
|
||||
}
|
||||
|
||||
public static function parseResultFromDb(array $row): array {
|
||||
$r = [];
|
||||
for ($i = 1; $i <= 10; $i++) $r[] = (int)($row['rank_' . $i] ?? 0);
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user