【问题标题】:Soccer simulation for a game足球模拟游戏
【发布时间】:2010-11-28 11:05:27
【问题描述】:

我想构建一个可以模拟足球(足球)比赛的模拟引擎。如果你能帮助我,那就太好了。对我来说重要的是决定发生哪些动作。每个动作的事件监听器可以在以后轻松实现。该函数应该只模拟游戏结果和 cmet 发生的动作。不需要 2D/3D 图形。我们说的是Hattrick之类的游戏。


我建议您首先有一系列的行动分钟。

$minutes = 数组(1, 3, 4, 7, 11, 13, ..., 90, 92);

然后,您可以在每一分钟内模拟一次攻击。

攻击队伍由之前的骰子决定:$attacking = mt_rand(1, 2);

所以对我来说最重要的部分是攻击功能。

请编辑我的方法或将其用作示例。你能帮我改进一下吗?该函数应该是复杂的,以便结果尽可能真实。但是您需要在高可预测性和过于随机的结果之间找到一些东西。我只想改进这个功能。

我的方法:

<?php
function Chance_Percent($chance, $universe = 100) {
    $chance = abs(intval($chance));
    $universe = abs(intval($universe));
    if (mt_rand(1, $universe) <= $chance) {
        return true;
    }
    return false;
}
function simulate_attack($teamname_att, $teamname_def, $strength_att, $strength_def) {
    global $minute, $goals, $_POST, $matchReport, $fouls, $yellowCards, $redCards, $offsides, $schuesse, $taktiken;
    // input values: attacker's name, defender's name, attacker's strength array, defender's strength array
    // players' strength values vary from 0.1 to 9.9
    // ADJUSTMENT START
    switch ($taktiken[$teamname_att][0]) {
        case 1: $strength_att['defenders'] *= 1.1; $strength_att['forwards'] *= 0.9; break;
        case 3: $strength_att['defenders'] *= 0.9; $strength_att['forwards'] *= 1.1; break;
    }
    switch ($taktiken[$teamname_def][0]) {
        case 1: $strength_def['defenders'] *= 1.1; $strength_def['forwards'] *= 0.9; break;
        case 3: $strength_def['defenders'] *= 0.9; $strength_def['forwards'] *= 1.1; break;
    }
    // ADJUSTMENT END
    $matchReport .= '<p>'.$minute.'\': '.comment($teamname_att, 'attack');
    $offense_strength = $strength_att['forwards']/$strength_def['defenders'];
    $defense_strength = $strength_def['defenders']/$strength_att['forwards'];
    if (Chance_Percent(50*$offense_strength*($taktiken[$teamname_att][2]/2)*($taktiken[$teamname_att][3]/2))) {
        // attacking team passes 1st third of opponent's field side
        $matchReport .= ' '.comment($teamname_def, 'attack_advance');
        if (Chance_Percent(25*($taktiken[$teamname_def][4]/2))) {
            // the defending team fouls the attacking team
            $fouls[$teamname_def]++;
            $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul');
            if (Chance_Percent(43)) {
                // yellow card for the defending team
                // chance is correct for my purpose
                $yellowCards[$teamname_def]++;
                $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_yellow');
            }
            elseif (Chance_Percent(3)) {
                // red card for the defending team
                // chance is correct for my purpose (only 1.43% because it's an alternative way)
                $redCards[$teamname_def]++;
                $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_red');
            }
            // indirect free kick
            // only 58.23% because it's an alternative way
            $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick');
            if (Chance_Percent(25)) {
                // shot at the goal
                $schuesse[$teamname_att]++;
                $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot');
                if (Chance_Percent(25)) {
                    // attacking team scores (6.25% chance)
                    $goals[$teamname_att]++;
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot_score');
                }
                else {
                    // defending goalkeeper saves
                    // only 18.75% because it's an alternative way
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot_save');
                }
            }
            else {
                // defending team cleares the ball
                // only 75% because it's an alternative way
                $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_clear');
            }
        }
        elseif (Chance_Percent(17)) {
            // attacking team is caught offside
            // only 4.25% because it's an alternative way
            $offsides[$teamname_att]++;
            $matchReport .= ' '.comment($teamname_def, 'attack_advance_offside');
        }
        else {
            if (Chance_Percent(25*($taktiken[$teamname_def][5]/2))) {
                // the defending team fouls the attacking team
                $fouls[$teamname_def]++;
                $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul');
                if (Chance_Percent(43)) {
                    // yellow card for the defending team
                    // chance is correct for my purpose
                    $yellowCards[$teamname_def]++;
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_yellow');
                }
                elseif (Chance_Percent(3)) {
                    // red card for the defending team
                    // chance is correct for my purpose (only 1.43% because it's an alternative way)
                    $redCards[$teamname_def]++;
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_red');
                }
                if (Chance_Percent(19)) {
                    // penalty for the attacking team
                    $schuesse[$teamname_att]++;
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_penalty');
                    if (Chance_Percent(77)) {
                        // attacking team scores (77% chance according to Wikipedia)
                        $goals[$teamname_att]++;
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_penalty_score');
                    }
                    elseif (Chance_Percent(50)) {
                        // shot misses the goal
                        // only 11.5% because it's an alternative way
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_penalty_miss');
                    }
                    else {
                        // defending goalkeeper saves
                        // only 11.5% because it's an alternative way
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_penalty_save');
                    }
                }
                elseif (Chance_Percent(28)) {
                    // direct free kick
                    // only 22.68% because it's an alternative way
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_dFreeKick');
                    if (Chance_Percent(33)) {
                        // shot at the goal
                        $schuesse[$teamname_att]++;
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_dFreeKick_shot');
                        if (Chance_Percent(33)) {
                            // attacking team scores (10.89% chance)
                            $goals[$teamname_att]++;
                            $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_dFreeKick_shot_score');
                        }
                        else {
                            // defending goalkeeper saves
                            $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_dFreeKick_shot_save');
                        }
                    }
                    else {
                        // defending team cleares the ball
                        // only 77% because it's an alternative way
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_dFreeKick_clear');
                    }
                }
                else {
                    // indirect free kick
                    // only 58.23% because it's an alternative way
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick');
                    if (Chance_Percent(25)) {
                        // shot at the goal
                        $schuesse[$teamname_att]++;
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot');
                        if (Chance_Percent(25)) {
                            // attacking team scores (6.25% chance)
                            $goals[$teamname_att]++;
                            $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot_score');
                        }
                        else {
                            // defending goalkeeper saves
                            // only 18.75% because it's an alternative way
                            $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot_save');
                        }
                    }
                    else {
                        // defending team cleares the ball
                        // only 75% because it's an alternative way
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_clear');
                    }
                }
            }
            else {
                // attack passes the 2nd third of the opponent's field side - good chance
                $matchReport .= ' '.comment($teamname_def, 'attack_advance_advance');
                if (Chance_Percent(62*($taktiken[$teamname_att][6]/2)*($taktiken[$teamname_att][7]/2)/($taktiken[$teamname_att][8]/2)*($taktiken[$teamname_att][9]/2)/($taktiken[$teamname_def][10]/2))) {
                    // shot at the goal
                    $schuesse[$teamname_att]++;
                    $matchReport .= ' '.comment($teamname_def, 'attack_advance_advance_shot');
                    if (Chance_Percent(30*$strength_def['goalkeeper']/7/($taktiken[$teamname_att][11]/2))) {
                        // the attacking team scores
                        // only 8.78% because it's an alternative way
                        // if goalkeeper has strenth 7 then chance is 8.78% otherwise lower/higher
                        $goals[$teamname_att]++;
                        $matchReport .= ' '.comment($teamname_def, 'attack_advance_advance_shot_score');
                    }
                    else {
                        if (Chance_Percent(50)) {
                            // the defending defenders block the shot
                            $matchReport .= ' '.comment($teamname_def, 'attack_advance_advance_shot_block');
                        }
                        else {
                            // the defending goalkeeper saves
                            $matchReport .= ' '.comment($teamname_def, 'attack_advance_advance_shot_save');
                        }
                    }
                }
            }
        }
    }
    // attacking team doesn't pass 1st third of opponent's field side
    elseif (Chance_Percent(15*$defense_strength*($taktiken[$teamname_att][12]/2)*($taktiken[$teamname_att][13]/2))) {
        // quick counter attack - playing on the break
        // only 7.5% because it's an alternative way
        // if defense has strength 7 then chance is 7.5% otherwise lower/higher
        $strength_att['defenders'] = $strength_att['defenders']*0.8; // weaken the current attacking team's defense
        $matchReport .= ' '.comment($teamname_def, 'attack_quickCounterAttack');
        $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
        return simulate_attack($teamname_def, $teamname_att, $strength_def, $strength_att); // new attack - this one is finished
    }
    else {
        // ball goes into touch - out of the field
        $matchReport .= ' '.comment($teamname_def, 'attack_throwIn');
        if (Chance_Percent(33)) {
            // if a new chance is created
            if (Chance_Percent(50)) {
                // throw-in for the attacking team
                $matchReport .= ' '.comment($teamname_def, 'attack_throwIn_att');
                $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
                return simulate_attack($teamname_att, $teamname_def, $strength_att, $strength_def); // new attack - this one is finished
            }
            else {
                // throw-in for the defending team
                $matchReport .= ' '.comment($teamname_def, 'attack_throwIn_def');
                $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
                return simulate_attack($teamname_def, $teamname_att, $strength_def, $strength_att); // new attack - this one is finished
            }
        }
    }
    $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
    return TRUE; // finish the attack
}
?>

应该影响随机性的战术设置:

  • 调整(1=防守,2=中立,3=进攻):数值越高,防守越弱,进攻越强
  • 游戏速度(1=慢,2=中,3=快):数值越高,机会越大,但快速反击的风险越高
  • 传球距离(1=短,2=中,3=长):值越高,获得的机会越少,但越位的机会越多
  • 创造变化(1=安全,2=中等,3=有风险):值越高,您的机会就越大,但获得快速反击的风险越高
  • 防守压力(1=低,2=中,3=高):数值越高,反击越快
  • 攻击性(1=低,2=中,3=高):数值越高,你会被犯规阻止的攻击越多

战术设置的整合:

所有战术设置都有一个值,可以是“1”、“2”或“3”。 “2”总是中性/中等。所以我将这些值除以 2。我得到的比率是 0.5 或 1 或 1.5。我想我可以很容易地乘以这个机会,以整合战术影响力。但是出现了一个问题:如果我将一个机会乘以 2 个或更多战术值,它可能会高于 100%(例如 60 x 1.5 x 1.5)。所以我不能这样整合战术。我还能做什么?


非常感谢!

更新(2014 年): 几年后,我现在以开源 on GitHub 的形式发布了游戏的完整代码库。这个模拟的具体实现in this file,有兴趣的可以去看看。

【问题讨论】:

  • 你不应该在函数调用中使用exit,而是使用return simulation_attack()。
  • 这真的有效吗?那个时候给出的值是什么? Return 通常会返回一个值,对吗?但是这个值只有在之前有退出的情况下才会设置。所以很多情况下是没有返回的,那么返回什么值呢?
  • 我不能再次调用simulate_attack() 并在下一行返回TRUE 吗?这应该有同样的效果!?
  • 如果没有返回值 void 也就是没有返回任何值,返回键结束函数的生命周期,所以它是比退出更好的做法。
  • 另外你必须只用英文写你的代码,这让其他人更容易理解。

标签: php simulation


【解决方案1】:

这会很复杂,但如果你想真实地模拟一场足球比赛,你需要投入更多的变量。并不是你的所有球队都会进攻,你会有防守者,而这些防守者会减轻对方球队的进攻强度。

我会推荐一个更像这样的流程:

1) A 队在他们的场边控球。它会尝试得分。从 1-100 (0-99) 生成一个表格,并用以下因素填充它:A 队球员的技能、对方球员的防守能力、与球门的距离、疲劳程度(比赛持续时间)。这个表格看起来像这样(想象 +1 使它更简单,所以 1-100 而不是 0-99):

  1. 1-50 : 球员成功推进球
  2. 51-60 : 球员未能推进球但保持控球权
  3. 61-73 : 球员未能推进球并失去控球权
  4. 74-82 : 球员将球传给另一名进攻球员
  5. 83-95 : 球员失去控球权,敌人试图得分
  6. 95-100 : 严重失误 : 球员失去控球权并立即让对方进球

2) 如果是 1,请再次掷骰,但现在有一组不同的选择来站在对方一边。在 2 的偶数中,再次在桌子上滚动相同的卷。如果是三人,则为对方球队进行相同的掷骰,但使用不同的桌子,因为他们更接近球门。如果是 4,则再次进行掷骰,但将球员的统计数据更改为 A 队的球员 2,并假设数字更接近目标。在 5 的情况下,根据随机玩家的技能滚动对手队伍成功或失败的桌子。如果是六,立即给对方一个进球(在足球比赛中,这种情况发生的几率不到 5%,更像是 0.01%,但你也可以在另一张桌子上滚动包括受伤或看起来很愚蠢十秒钟的严重故障)。

3) 根据结果重复该过程。

我可以给你代码示例,但我认为你有基本的想法。

更新:我认为其他人已经回答了如何使用您的方法计算权重。我的方法实际上会有所不同,我将在这里解释差异......

1) 您的计算基本上假设每隔这么多分钟就有一次进球尝试,此时有一组复杂的计算试图模拟球员得分或不得分的机会。我的计算会假设球一直在比赛中,并根据一系列统计数据从一组可能的结果移动到下一个可能的结果,而不是被认为是在球门上的一系列来回射门。这在概念上会有所不同,因为它是跟随球而不是球员,并且球将被分配给由上述因素加权的一定数量的可能性。

2) 您对事物加权的方法涉及多个权重,正如其他人所描述的那样,这会增加您在一定数量上的百分比变化。在我的场景中,您将机会分解为一个表格,以便绝对最多只有 100 个可能的结果,然后您使用 mt_rand 在这组结果中命中一个数字,这通常称为命中表或彩票。

为了做到这一点,您将获得基本机会,然后对其进行加权,从而为您提供成长空间。例如,假设一个球得分的基本机会是 10/100。如果某人是 1,则变为 5。2,保持 10。3,变为 15。所以现在,滚动 0-14 被灵活地分配给这些值,而命中表中的其他值则移动以适应。这会在稍后带来概率问题,因为您也应该假设您也应该扩大牌桌,但这会被动地降低您从 10/100 到 15/105 (考虑到所有其他可能的结果)中击中的机会。

如果你想沿着你已经开始的道路继续前进,我认为我在这里所说的大部分内容都行不通,除非你简单地将这些值放入一个表中,并在每次攻击时计算它们已经做了。

如果您想坚持使用当前的嵌套随机语句,我会说选择其他人提供的解决方案之一。祝你好运!

【讨论】:

  • 非常感谢,很好的详细解释。这就是我已经在做的,不是吗?我只是不使用表,而是使用 mt_rand 嵌套条件!?
  • 现在我在问题中添加了“整合战术设置”。你能看看这个吗?你对我的问题有解决方案吗?
  • 谢谢!编辑使一些事情变得更加清晰。但是:第 1 点的区别(球总是在比赛中)很明显。但我看不出第 2+3 点有什么不同。你用一张桌子掷骰子,得到一个数字。我在 if 子句中使用机会。这几乎是一样的,不是吗?您将如何对这些表进行编码?使用 switch 语句?
  • [注意:哎呀,评论了错误的答案,移到这里] 将值分配给表格的重点是因为有多种结果,而不仅仅是两个具有加权可能性的结果.我会这样做的方法是将这些值写入一些数据结构(如数组),并通过循环加载它......例如for循环,将迭代器加载到索引中,如 $results[$i] = "miss" for $i 0-4 等。然后您可以执行 $results[rand(0,99)] 来提取结果,并在需要时针对该情况重用该结果表。有意义吗?
  • 谢谢你,现在我已经完全理解你的方法了。
【解决方案2】:

构建一个基于“权重”的模拟(是的,我刚刚发明了这个术语)。每个变量(无论其类型如何)都有一个“权重”。例如,球员有重量。一个好的球员有额外的重量。受伤的球员体重较轻,甚至根本不需要等待(或者可能是负重?)。

您将所有重量加在一起(两支球队的重量,因为这是一场足球比赛)。该权重类似于获胜机会百分比。例如;

A队体重=56B队体重=120

重量已经表明,一支球队比另一支球队要好得多(不管重量是如何确定的......也许他们的球很圆,谁在乎)。

根据重量,您可以计算中奖机会; A队获胜机率=32%B队获胜机率=68%

现在您可以编写一个算法来模拟比赛,受胜率的影响。我曾经写过一个这样的算法来绘制广告。就我而言,广告的点击次数就是权重。权重越大,广告被我的算法选中的机会就越大。

我通过取一个大数字(例如 1000)来编写算法,然后根据权重百分比为每个广告分配该数字的范围。在这种情况下,团队 A 获得 1000 的 32%0 - 320,团队 B 获得 68% 的范围,即 321 - 1000。然后我的算法会(随机)抽取一个介于 0 和 1000 之间的数字。范围最大(因此获胜机会最大)的广告(或您的团队)最有可能被算法选中,尽管结果可能不同.

这种算法对于平衡结果(如果用户可以创建自己的团队、购买更好的球员等)来说非常棒(尽管并不完美)。您还可以通过该算法在游戏中绘制任何事件,只需为事件添加权重即可。..

您可以根据球队内的其他权重因素(连续进行多少场比赛、比赛表现如何(或权重)为每支球队增加重量(例如队友受伤)他们的医务人员等)。如果你做对了重量,你可以获得一个非常平衡(并且易于扩展)的模拟算法,它既可以预测(就像现实生活中的一些比赛一样),也可以完全令人惊讶(再次,就像现实生活中的比赛一样)。

更新: 战术影响 你添加了战术影响,加上“你会怎么做?”的问题,所以我会详细说明。您目前正在做的(据我所知)是取一个百分比(发生某事的机会)并将其乘以一个比率,这样它就会发生更多/更少。

但是,因为您可以有多个比率,所以您最终的机会超过 100%。

首先,对于一支球队的每一个战术优势,对另一支球队来说(可能)都有一个反制优势。例如,如果 A 队在进球方面具有权重,B 队在制止进球方面具有反制权。这个总和就是宇宙(100%)。现在,这两种战术优势的重要性构成了整个宇宙的一部分,或者说总重量(正如我在上面解释的那样)。

假设 A 队有 80% 确定在某分钟内进球,B 队有 20% 确定阻止它(基于体重系统)。但是,因为B队刚刚获得了一名非常优秀的门将,所以B队的战术影响很大。这种影响应该改变事件的机会,而不是宇宙本身!换句话说,你最终的总机会不应该超过 100%(尽管在某些情况下,这不一定是坏事)

因此,您应该根据战术影响为 B 队增加权重,然后根据新的权重重新计算机会。

分配权重

现在,就像您评论的那样,分配权重并不容易。如果你必须“衡量”球员的素质,那当然不会。称重不仅仅是说一个球员是“坏”或“好”,你必须对他们进行实际评分(就像在高中时一样!)。最高等级越大,权重系统越准确。

现在,为战术影响分配权重要容易一些。假设你有以下影响;

  • 停止目标
  • 进球数
  • 防御
  • 攻击

现在,创建一个总重量池(比如 1000,我喜欢这个数字)。这些是您可以分配的“战术点”。这四个影响构成了匹配,因此您可以为每个影响分配 250 分。这个数字 (250) 是每个影响的范围。

这些分数的分配,每支球队,取决于球队的权重因素(比如,他们有一个好的门将吗?)

例如,一名守门员与对手守门员(也许还有介于守门员和对手之间的人,但让我们保持简单)称重。假设A队门将占总重量的80%B队门将占20%。这可以评估他们的好坏程度,这与他们获得的战术点数直接相关。因此,A 队获得 250 个停球得分中的 80%B 队获得其中的 20%

其余的点可以平均分配。在我的示例中,我只选择了两个守门员,因为无论目标是否停止。实际上,可能有更多的权重因子(供您计算)。

一旦将它们全部分开,您就可以使用战术点来确定比赛。每分钟您都可以重新计算获胜的机会。每分钟,您还可以重新计算战术影响(比如另一名球员上场,或一名球员受伤)。

是的,你会得到很多变量。但是你得到的越多,比赛就越好。变量(或重量/配重)越多,感觉就越真实。

【讨论】:

  • 很好的答案,谢谢。这就是我现在的做法。但困难的是找到合适的权重:)
  • 现在我在问题中添加了“整合战术设置”。你能看看这个吗?你对我的问题有解决方案吗?
  • @MiRAGe:非常感谢这次详细的更新! :) 我已经构建了应该模拟比赛的基本结构。你可以在我的问题中看到它。在很多情况下都有机会。战术价值应该只影响/改变这些机会。你也可以在我的问题中看到我的战术价值观。我不想分配战术点左右。
  • 你的机会计算的问题是你试图将苹果乘以香蕉,这会产生意想不到的结果。您应该将您的比率转换为百分比以便使用它们。
  • 为什么是苹果和香蕉?为什么我不应该将它们相乘?对我来说这是合乎逻辑的:如果战术值为 3,则机会增加,如果为 1,则机会减少,如果为 2,则没有任何改变。或者: (x*0.1+0.8) 会给出一个介于 0.9 和 1.1 之间的值,我可以将其用作百分比,对吧?所以不要乘以 (tacticalValue/2) 而是乘以 (tacticalValue*0.1+0.8)。这样更好吗?
【解决方案3】:

我建议您将所有概率转换为百分比:

function Chance($chance, $universe = 100)
{
    $chance = abs(intval($chance));
    $universe = abs(intval($universe));

    if (mt_rand(1, $universe) <= $chance)
    {
        return true;
    }

    return false;
}

Chance(25); // 25%
Chance(5, 1000); // 0.5%

另外我只会用其他人的条件来实例化一些概率,例如:

if ($attack === true)
{
    if (Chance(15 * $aggressivity) === true)
    {
        if (Chance(10 * $aggressivity) === true)
        {
            // red card
        }

        else
        {
            // yellow card
        }
    }
}

编辑:我刚回家,我真的需要睡觉了,但在快速浏览了您的编辑后,我想到了一个您可能会感兴趣的想法。如果不使用 1、2 或 3 的调整值,而不使用球队的战术位置,那会怎样?例如,与 3-3-4 球队相比,一支 4-4-2 阵型的球队在对阵 5-3-2 球队时进球的机会更少。假设位置总是三连冠 (X-Y-Z),那么比较哪支球队在防守、传球和得分方面表现最好是很容易的。

一个简单的公式可能是这样的:

A: 4-4-2 (Defending Team)
B: 3-2-5 (Attacking Team)

B 进球的几率是 (4 / 5) ^ -1 = 0.2 = 20%,反之(A 队进球)是 (3 / 2) ^ -1 = 0.5 = 50%。 PS:这个现在好像没什么意义了,不过我早上再试试看。

还有一件事:在一张红牌之后,为什么犯错的球队保持不变?它应该会变得更弱(少一个玩家)IMO。

【讨论】:

  • 非常感谢! :) Chance() 函数很棒,它比我的带有 运算符的 mt_rand() 解决方案要好得多。您建议在没有其他条件的情况下实例化大多数概率,因为它会改变百分比值,对吗?但我必须将所有可能性与不能同时发生的其他条件相加,不是吗?
  • 现在我在问题中添加了“整合战术设置”。你能看看这个吗?你对我的问题有解决方案吗?
  • 非常感谢您的编辑!我没有不同的阵型(4-4-2等),所以我不能在战术中使用它们。红牌的影响是在函数之外完成的。
【解决方案4】:

这才是真正的把戏不是吗?也许开始思考球员和球队有哪些变量会影响行动的成功和概率。

程序流程可能如下所示: 1.根据变量计算发生了哪个事件,并让那里也有一些随机性 2.计算事件的成功率。

恐怕你必须自己做这个和编程;)

【讨论】:

  • 很可惜:(这是我卡了几个月的点。我的用户抱怨模拟中的随机性太多。我已经添加了有影响的因素现在讨论随机性。
  • 现在我在问题中添加了“整合战术设置”。你能看看这个吗?你对我的问题有解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 2020-02-27
  • 2015-03-18
  • 2019-05-09
  • 2018-01-18
  • 2015-08-23
  • 1970-01-01
相关资源
最近更新 更多