130 lines
3.4 KiB
PHP
130 lines
3.4 KiB
PHP
|
|
<?php
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 文件功能:老虎机游戏记录模型
|
|||
|
|
*
|
|||
|
|
* 记录每次转动的三列图案、结果类型和赔付情况。
|
|||
|
|
*
|
|||
|
|
* @author ChatRoom Laravel
|
|||
|
|
*
|
|||
|
|
* @version 1.0.0
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
namespace App\Models;
|
|||
|
|
|
|||
|
|
use Illuminate\Database\Eloquent\Model;
|
|||
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||
|
|
|
|||
|
|
class SlotMachineLog extends Model
|
|||
|
|
{
|
|||
|
|
protected $fillable = [
|
|||
|
|
'user_id', 'reel1', 'reel2', 'reel3',
|
|||
|
|
'result_type', 'cost', 'payout',
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 属性类型转换。
|
|||
|
|
*/
|
|||
|
|
protected function casts(): array
|
|||
|
|
{
|
|||
|
|
return [
|
|||
|
|
'cost' => 'integer',
|
|||
|
|
'payout' => 'integer',
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关联玩家。
|
|||
|
|
*/
|
|||
|
|
public function user(): BelongsTo
|
|||
|
|
{
|
|||
|
|
return $this->belongsTo(User::class);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 全部图案符号定义(key => emoji)。
|
|||
|
|
* 顺序影响权重:越靠前出现概率越高(摇奖时按权重随机)。
|
|||
|
|
*
|
|||
|
|
* @return array<string, array{emoji: string, weight: int}>
|
|||
|
|
*/
|
|||
|
|
public static function symbols(): array
|
|||
|
|
{
|
|||
|
|
return [
|
|||
|
|
'cherry' => ['emoji' => '🍒', 'weight' => 30],
|
|||
|
|
'lemon' => ['emoji' => '🍋', 'weight' => 25],
|
|||
|
|
'orange' => ['emoji' => '🍊', 'weight' => 20],
|
|||
|
|
'grape' => ['emoji' => '🍇', 'weight' => 15],
|
|||
|
|
'bell' => ['emoji' => '🔔', 'weight' => 8],
|
|||
|
|
'gem' => ['emoji' => '💎', 'weight' => 4],
|
|||
|
|
'skull' => ['emoji' => '💀', 'weight' => 3],
|
|||
|
|
'seven' => ['emoji' => '7️⃣', 'weight' => 1],
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 按权重随机抽取一个图案 key。
|
|||
|
|
*/
|
|||
|
|
public static function randomSymbol(): string
|
|||
|
|
{
|
|||
|
|
$symbols = static::symbols();
|
|||
|
|
$totalWeight = array_sum(array_column($symbols, 'weight'));
|
|||
|
|
$rand = random_int(1, $totalWeight);
|
|||
|
|
$cumulative = 0;
|
|||
|
|
|
|||
|
|
foreach ($symbols as $key => $item) {
|
|||
|
|
$cumulative += $item['weight'];
|
|||
|
|
if ($rand <= $cumulative) {
|
|||
|
|
return $key;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 'cherry'; // fallback
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 根据三列图案判断结果类型。
|
|||
|
|
*
|
|||
|
|
* @return string 'jackpot' | 'triple_gem' | 'triple' | 'pair' | 'curse' | 'miss'
|
|||
|
|
*/
|
|||
|
|
public static function judgeResult(string $r1, string $r2, string $r3): string
|
|||
|
|
{
|
|||
|
|
// 三个7 → 大奖
|
|||
|
|
if ($r1 === 'seven' && $r2 === 'seven' && $r3 === 'seven') {
|
|||
|
|
return 'jackpot';
|
|||
|
|
}
|
|||
|
|
// 三个💎 → 豪华奖
|
|||
|
|
if ($r1 === 'gem' && $r2 === 'gem' && $r3 === 'gem') {
|
|||
|
|
return 'triple_gem';
|
|||
|
|
}
|
|||
|
|
// 三个💀 → 诅咒(亏双倍)
|
|||
|
|
if ($r1 === 'skull' && $r2 === 'skull' && $r3 === 'skull') {
|
|||
|
|
return 'curse';
|
|||
|
|
}
|
|||
|
|
// 三同(其他)
|
|||
|
|
if ($r1 === $r2 && $r2 === $r3) {
|
|||
|
|
return 'triple';
|
|||
|
|
}
|
|||
|
|
// 两同
|
|||
|
|
if ($r1 === $r2 || $r2 === $r3 || $r1 === $r3) {
|
|||
|
|
return 'pair';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 'miss';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 结果类型中文标签。
|
|||
|
|
*/
|
|||
|
|
public static function resultLabel(string $type): string
|
|||
|
|
{
|
|||
|
|
return match ($type) {
|
|||
|
|
'jackpot' => '🎉 三个7大奖!',
|
|||
|
|
'triple_gem' => '💎 三钻豪华奖',
|
|||
|
|
'triple' => '✨ 三同奖',
|
|||
|
|
'pair' => '🎁 两同小奖',
|
|||
|
|
'curse' => '☠️ 三骷髅诅咒',
|
|||
|
|
'miss' => '😔 未中奖',
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|