php – 改进足球模拟算法

前端之家收集整理的这篇文章主要介绍了php – 改进足球模拟算法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在另一个问题中,你帮助我构建了一个足球模拟算法. I got some very good answers there.再次感谢!

现在我编写了这个算法.我想改进它,发现可能存在的一些小错误.我不想讨论如何解决它 – 正如我们在上一个问题中所做的那样.现在我只想改进它.你能再帮我一次吗?

>有什么错误吗?
>嵌套的if子句的结构是否正常?可以改进吗?
>根据我的描述,战术是否正确整合?

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

> $tactics [x] [0]调整(1 =防守,2 =中立,3 =进攻):价值越高,防守越弱,进攻越强
> $tacticsx游戏速度(1 =慢,2 =中等,3 =快):值越高,机会越大但获得快速反击的风险越高
> $tacticsx传球距离(1 =短,2 =中,3 =长):值越高越少但获得的机会越多,越位越远
> $tacticsx创建变化(1 =安全,3 =有风险):价值越高,您的机会越多,但获得快速反击的风险越高
> $tactics [x] [4]防御压力(1 =低,3 =高):值越大,你将有越快的反击
> $tactics [x] [5]攻击性(1 =低,3 =高):值越高,你将被犯规所阻止的攻击越多

注意:
Tactic 0和tactic 4部分集成在发动机的其余部分,此功能不需要.

目前的算法:

<?PHP
function tactics_weight($wert) {
    $neuerWert = $wert*0.1+0.8;
    return $neuerWert;
}
function strengths_weight($wert) {
    $neuerWert = log10($wert+1)+0.35;
    return $neuerWert;
}
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,$shots,$tactics;
    // 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
    $matchReport .= '<p>'.$minute.'\': '.comment_action($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*tactics_weight($tactics[$teamname_att][1])/tactics_weight($tactics[$teamname_att][2]))) {
        // attacking team passes 1st third of opponent's field side
        $matchReport .= ' '.comment_action($teamname_def,'advance');
        if (Chance_Percent(25*tactics_weight($tactics[$teamname_def][5]))) {
            // the defending team fouls the attacking team
            $fouls[$teamname_def]++;
            $matchReport .= ' '.comment_action($teamname_def,'foul');
            if (Chance_Percent(43)) {
                // yellow card for the defending team
                $yellowCards[$teamname_def]++;
                $matchReport .= ' '.comment_action($teamname_def,'yellow');
            }
            elseif (Chance_Percent(3)) {
                // red card for the defending team
                $redCards[$teamname_def]++;
                $matchReport .= ' '.comment_action($teamname_def,'red');
            }
            // indirect free kick
            $matchReport .= ' '.comment_action($teamname_att,'iFreeKick');
            if (Chance_Percent(25*strengths_weight($strength_att['forwards']))) {
                // shot at the goal
                $shots[$teamname_att]++;
                $matchReport .= ' '.comment_action($teamname_att,'iFreeKick_shot');
                if (Chance_Percent(25/strengths_weight($strength_def['goalkeeper']))) {
                    // attacking team scores
                    $goals[$teamname_att]++;
                    $matchReport .= ' '.comment_action($teamname_att,'shot_score');
                }
                else {
                    // defending goalkeeper saves
                    $matchReport .= ' '.comment_action($teamname_def,'iFreeKick_shot_save');
                }
            }
            else {
                // defending team cleares the ball
                $matchReport .= ' '.comment_action($teamname_def,'iFreeKick_clear');
            }
        }
        elseif (Chance_Percent(17)*tactics_weight($tactics[$teamname_att][2])) {
            // attacking team is caught offside
            $offsides[$teamname_att]++;
            $matchReport .= ' '.comment_action($teamname_def,'offside');
        }
        else {
            // attack isn't interrupted
            // attack passes the 2nd third of the opponent's field side - good chance
            $matchReport .= ' '.comment_action($teamname_def,'advance_further');
            if (Chance_Percent(25*tactics_weight($tactics[$teamname_def][5]))) {
                // the defending team fouls the attacking team
                $fouls[$teamname_def]++;
                $matchReport .= ' '.comment_action($teamname_def,'foul');
                if (Chance_Percent(43)) {
                    // yellow card for the defending team
                    $yellowCards[$teamname_def]++;
                    $matchReport .= ' '.comment_action($teamname_def,'yellow');
                }
                elseif (Chance_Percent(3)) {
                    // red card for the defending team
                    $redCards[$teamname_def]++;
                    $matchReport .= ' '.comment_action($teamname_def,'red');
                }
                if (Chance_Percent(19)) {
                    // penalty for the attacking team
                    $shots[$teamname_att]++;
                    $matchReport .= ' '.comment_action($teamname_att,'penalty');
                    if (Chance_Percent(77)) {
                        // attacking team scores
                        $goals[$teamname_att]++;
                        $matchReport .= ' '.comment_action($teamname_att,'shot_score');
                    }
                    elseif (Chance_Percent(50)) {
                        // shot misses the goal
                        $matchReport .= ' '.comment_action($teamname_att,'penalty_miss');
                    }
                    else {
                        // defending goalkeeper saves
                        $matchReport .= ' '.comment_action($teamname_def,'penalty_save');
                    }
                }
                else {
                    // direct free kick
                    $matchReport .= ' '.comment_action($teamname_att,'dFreeKick');
                    if (Chance_Percent(33*strengths_weight($strength_att['forwards']))) {
                        // shot at the goal
                        $shots[$teamname_att]++;
                        $matchReport .= ' '.comment_action($teamname_att,'dFreeKick_shot');
                        if (Chance_Percent(33/strengths_weight($strength_def['goalkeeper']))) {
                            // attacking team scores
                            $goals[$teamname_att]++;
                            $matchReport .= ' '.comment_action($teamname_att,'shot_score');
                        }
                        else {
                            // defending goalkeeper saves
                            $matchReport .= ' '.comment_action($teamname_def,'dFreeKick_shot_save');
                        }
                    }
                    else {
                        // defending team cleares the ball
                        $matchReport .= ' '.comment_action($teamname_def,'dFreeKick_clear');
                    }
                }
            }
            elseif (Chance_Percent(62*strengths_weight($strength_att['forwards'])*tactics_weight($tactics[$teamname_att][2])*tactics_weight($tactics[$teamname_att][3]))) {
                // shot at the goal
                $shots[$teamname_att]++;
                $matchReport .= ' '.comment_action($teamname_att,'shot');
                if (Chance_Percent(30/strengths_weight($strength_def['goalkeeper']))) {
                    // the attacking team scores
                    $goals[$teamname_att]++;
                    $matchReport .= ' '.comment_action($teamname_att,'shot_score');
                }
                else {
                    if (Chance_Percent(50)) {
                        // the defending defenders block the shot
                        $matchReport .= ' '.comment_action($teamname_def,'shot_block');
                    }
                    else {
                        // the defending goalkeeper saves
                        $matchReport .= ' '.comment_action($teamname_def,'shot_save');
                    }
                }
            }
            else {
                // attack is stopped
                $matchReport .= ' '.comment_action($teamname_def,'stopped');
                if (Chance_Percent(15*$defense_strength*tactics_weight($tactics[$teamname_att][1])*tactics_weight($tactics[$teamname_att][3])*tactics_weight($tactics[$teamname_def][4]))) {
                    // quick counter attack - playing on the break
                    $strength_att['defenders'] = $strength_att['defenders']*0.8; // weaken the current attacking team's defense
                    $matchReport .= ' '.comment_action($teamname_def,'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
                }
            }
        }
    }
    // attacking team doesn't pass 1st third of opponent's field side
    elseif (Chance_Percent(15*$defense_strength*tactics_weight($tactics[$teamname_att][1])*tactics_weight($tactics[$teamname_att][3])*tactics_weight($tactics[$teamname_def][4]))) {
        // attack is stopped
        // quick counter attack - playing on the break
        $matchReport .= ' '.comment_action($teamname_def,'stopped');
        $strength_att['defenders'] = $strength_att['defenders']*0.8; // weaken the current attacking team's defense
        $matchReport .= ' '.comment_action($teamname_def,'quickCounterAttack');
        $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
        return simulate_attack($teamname_def,$strength_att); // new attack - this one is finished
    }
    else {
        // ball goes into touch - out of the field
        $matchReport .= ' '.comment_action($teamname_def,'throwIn');
        if (Chance_Percent(33)) {
            // if a new chance is created
            if (Chance_Percent(50)) {
                // throw-in for the attacking team
                $matchReport .= ' '.comment_action($teamname_def,'throwIn_att');
                $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
                return simulate_attack($teamname_att,$strength_def); // new attack - this one is finished
            }
            else {
                // throw-in for the defending team
                $matchReport .= ' '.comment_action($teamname_def,'throwIn_def');
                $matchReport .= ' ['.$goals[$_POST['team1']].':'.$goals[$_POST['team2']].']</p>'; // close comment line
                return simulate_attack($teamname_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
}

更新(2014年):几年后,我现在已经发布了游戏的完整代码open-source on GitHub.如果有兴趣的话,你会发现这个模拟in this file的具体实现.

一般来说,看起来这是一个相当复杂的问题,我不确定你会得到它的效率.

也就是说,我已经看到了一些可以帮助你的东西.

首先,我将在参数中键入变量.这可能不一定会使您的代码更快,但它会使它更容易阅读和调试.接下来,我将删除$teamname_att,$teamname_def参数,并将这些参数作为关联$strength_att,$strength_def数组中的值.由于此数据始终配对,这将降低意外使用一个团队名称作为对另一个团队的参考的风险.

这将使您不必不断地在数组中查找值:

// replace all $tactics[$teamname_att] with $attackers
$attackers = $tactics[$teamname_att]; 
$defenders = $tactics[$teamname_def];
// Now do the same with arrays like $_POST[ "team1" ];

你有三个辅助函数都有这个模式:

function foo( $arg ){
    $bar = $arg * $value;
    return $bar;
}

因为这意味着每次运行函数时都必须创建一个额外的变量(可能代价很高),请使用以下变量:

function tactics_weight($wert) {
    return $wert*0.1+0.8;
}

function strengths_weight($wert) {
    return log10($wert+1)+0.35;
}

/*
 Perhaps I missed it,but I never saw Chance_Percent( $num1,$num2 )
 consider using this function instead: (one line instead of four,it also
 functions more intuitively,Chance_Percent is your chance out of 100 
 (or per cent)

 function Chance_Percent( $chance ) {
     return (mt_rand(1,100) <= $chance);
 }    

*/
function Chance_Percent($chance,$universe = 100) {
    $chance = abs(intval($chance)); // Will you always have a number as $chance?
                                    // consider using only abs( $chance ) here.
    $universe = abs(intval($universe));
    return (mt_rand(1,$universe) <= $chance);
}

我忍不住注意到这种模式一直出现:

$matchReport .= ' ' . comment_action($teamname_att,'attack');

我的一般经验是,如果你将$matchReport的连接移动到comment_action,那么它会稍微快一些(通常不到十几毫秒,但是因为你在递归函数调用了这个函数的六倍,这样每次跑步可以减少十分之几秒.

我认为这会更好(无论是从读者的角度来看,还是来自

最后,有几次您将使用相同参数对同一函数使用相同的调用.提前打电话:

$goalieStrength = strengths_weight($strength_def['goalkeeper']);

希望这可以帮助.

猜你在找的PHP相关文章