游戏足球模拟 - php

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

我建议您先花几分钟时间进行操作。

$ minutes = array(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。

参考方案

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

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

A组的权重= 56,B组的权重= 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%。

其余的点可以平均分配。在我的示例中,我只选择了两名守门员,无论是否停止进球。实际上,可能会有更多的权重因子(供您找出)。

将它们全部分割后,您可以使用战术要点进行比赛。对于每一分钟,您可以重新计算获胜的机会。每分钟,您还可以重新计算战术影响力(例如,其他玩家进入该领域,或者某个玩家受伤)。

是的,您将获得很多变量。但是得到的越多,一场比赛就越好。变量(或权重/配重)越多,则感觉越像真实生活。

PHP:不推荐使用password_hash的'salt'选项 - php

我正在使用密码哈希进行注册。我需要手动创建Salt,以下是我使用的代码:$options = [ 'cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM) ]; $password = password_hash( $this->…

PHP-全局变量的性能和内存问题 - php

假设情况:我在php中运行一个复杂的站点,并且我使用了很多全局变量。我可以将变量存储在现有的全局范围内,例如$_REQUEST['userInfo'],$_REQUEST['foo']和$_REQUEST['bar']等,然后将许多不同的内容放入请求范围内(这将是适当的用法,因为这些数据指的是要求自…

PHP strtotime困境 - php

有人可以解释为什么这在我的服务器上输出为true吗?date_default_timezone_set('Europe/Bucharest'); var_dump( strtotime('29.03.2015 03:00', time()) === strtotime('29.03.2015 04:00�…

php-casperjs获取内部文本 - php

我正在为casperjs使用php包装器-https://github.com/alwex/php-casperjs我正在网上自动化一些重复的工作,我需要访问一个项目的innerText,但是我尚不清楚如何从casperjs浏览器访问dom。我认为在js中我会var arr = document.querySelector('label.input…

PHP Laravel从另一个驱动器读取文件 - php

我目前正在学习Laravel。我想知道是否有一种方法可以在Laravel中使用Storage::从另一个硬盘访问文件(使用Windows)。例如,我在驱动器C:上安装了带有Laravel的Xampp,但是我想访问网站目录之外的E:上的文件。我试过使用Storage::files('E:')和File::files('E:…