You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现老虎机支付线面板遇异常/显示问题求助

老虎机支付线面板实现修复方案

核心问题诊断

你的代码存在以下关键问题:

  • 随机数重复生成:每次调用GetRandomFloat都新建Random实例,短时间内会生成相同随机值,导致目标结果重复。
  • 浮点数精度误差:float类型的精度限制会导致递归匹配时出现计算偏差,频繁触发"无组合找到"的结果。
  • 逻辑偏离真实老虎机规则:原代码通过累加不同符号的 payout 凑目标值,这和老虎机"生成符号面板→检查支付线连续匹配→计算奖金"的实际逻辑完全不符。
  • 递归效率低下:背包式组合查找不仅不符合需求,还容易因深度限制或精度问题导致匹配失败。

重构后的完整实现

以下是符合真实老虎机逻辑的C#代码,包含符号面板生成、支付线定义、匹配计算奖金的完整流程:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SlotMachine
{
    internal class Program
    {
        // 静态随机数实例,避免重复生成相同种子
        private static readonly Random _random = new Random();

        // 符号 payout 配置:key=符号,value=不同匹配长度对应的奖金
        private static readonly Dictionary<string, Dictionary<int, decimal>> _symbolPayouts = new Dictionary<string, Dictionary<int, decimal>>
        {
            {"J", new Dictionary<int, decimal> {{3, 0.1m}, {4, 0.3m}, {5, 0.6m}}},
            {"Q", new Dictionary<int, decimal> {{3, 0.7m}, {4, 1.5m}, {5, 3.0m}}},
            {"K", new Dictionary<int, decimal> {{3, 1.5m}, {4, 5.0m}, {5, 10.0m}}},
            {"A", new Dictionary<int, decimal> {{3, 3.0m}, {4, 10.0m}, {5, 20.0m}}}
        };

        // 支付线定义:每条线是面板上的坐标(行索引,列索引),示例为9条常见支付线
        private static readonly List<List<(int Row, int Col)>> _paylines = new List<List<(int, int)>>
        {
            // 水平直线
            new List<(int, int)> {(0,0), (1,0), (2,0)}, // 左竖线
            new List<(int, int)> {(0,1), (1,1), (2,1)}, // 中竖线
            new List<(int, int)> {(0,2), (1,2), (2,2)}, // 右竖线
            new List<(int, int)> {(0,0), (1,1), (2,2)}, // 左上到右下斜线
            new List<(int, int)> {(0,2), (1,1), (2,0)}, // 右上到左下斜线
            // 其他常见支付线
            new List<(int, int)> {(0,0), (1,0), (2,1)},
            new List<(int, int)> {(0,1), (1,0), (2,0)},
            new List<(int, int)> {(0,2), (1,2), (2,1)},
            new List<(int, int)> {(0,1), (1,2), (2,2)}
        };

        // 符号池:控制各符号出现概率,重复次数越多概率越高
        private static readonly List<string> _symbolPool = new List<string>
        {
            "J", "J", "J", "J", "Q", "Q", "Q", "K", "K", "A"
        };

        static void Main(string[] args)
        {
            while (true)
            {
                // 生成老虎机面板:3行5列
                var panel = GenerateSlotPanel();
                Console.WriteLine("老虎机面板:");
                PrintPanel(panel);

                // 计算所有支付线的中奖情况
                var winnings = CalculateTotalWinnings(panel);
                Console.WriteLine($"\n总奖金:{winnings:C}");

                // 列出每条支付线的结果
                Console.WriteLine("\n支付线详情:");
                foreach (var (lineIndex, symbol, matchLength, payout) in GetPaylineResults(panel))
                {
                    if (payout > 0)
                    {
                        Console.WriteLine($"支付线 {lineIndex+1}: {symbol} 连续匹配 {matchLength} 个,奖金 {payout:C}");
                    }
                    else
                    {
                        Console.WriteLine($"支付线 {lineIndex+1}: 未中奖");
                    }
                }

                Console.WriteLine("\n按任意键继续...");
                Console.ReadKey(true);
                Console.Clear();
            }
        }

        // 生成3行5列的老虎机面板
        private static string[,] GenerateSlotPanel()
        {
            var panel = new string[3,5];
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 5; col++)
                {
                    panel[row, col] = _symbolPool[_random.Next(_symbolPool.Count)];
                }
            }
            return panel;
        }

        // 打印面板
        private static void PrintPanel(string[,] panel)
        {
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 5; col++)
                {
                    Console.Write($"[{panel[row, col]}] ");
                }
                Console.WriteLine();
            }
        }

        // 计算所有支付线的总奖金
        private static decimal CalculateTotalWinnings(string[,] panel)
        {
            return GetPaylineResults(panel).Sum(r => r.payout);
        }

        // 获取每条支付线的匹配结果
        private static IEnumerable<(int LineIndex, string Symbol, int MatchLength, decimal Payout)> GetPaylineResults(string[,] panel)
        {
            for (int lineIndex = 0; lineIndex < _paylines.Count; lineIndex++)
            {
                var payline = _paylines[lineIndex];
                if (payline.Count == 0) yield return (lineIndex, "", 0, 0);

                // 获取支付线上的所有符号
                var symbolsOnLine = payline.Select(pos => panel[pos.Row, pos.Col]).ToList();
                // 计算连续匹配的长度
                string targetSymbol = symbolsOnLine[0];
                int matchLength = 1;
                for (int i = 1; i < symbolsOnLine.Count; i++)
                {
                    if (symbolsOnLine[i] == targetSymbol)
                    {
                        matchLength++;
                    }
                    else
                    {
                        break; // 一旦出现不同符号,停止计数
                    }
                }

                // 计算奖金
                decimal payout = 0;
                if (_symbolPayouts.TryGetValue(targetSymbol, out var payouts) && payouts.TryGetValue(matchLength, out decimal amount))
                {
                    payout = amount;
                }

                yield return (lineIndex, targetSymbol, matchLength, payout);
            }
        }
    }
}

关键改动说明

  1. 随机数优化:使用静态Random实例,确保每次生成的随机值不重复。
  2. 精度问题解决:改用decimal类型处理所有奖金计算,完全避免浮点数精度误差。
  3. 符合老虎机逻辑:
    • 生成3行5列的符号面板,模拟真实老虎机的滚动结果。
    • 定义了9条常见支付线,每条线对应面板上的坐标位置。
    • 对每条支付线检查连续相同符号的长度,根据匹配长度和符号的 payout 表计算奖金。
  4. 概率控制:通过_symbolPool控制各符号的出现概率,重复次数越多的符号出现概率越高。

内容的提问来源于stack exchange,提问作者Theis Jensen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:53:16