在另一个问题中,您帮助我建立了足球模拟算法。 I got some very good answers there.再次感谢!
现在,我已经对该算法进行了编码。我想对其进行改进,并发现可能存在的错误。我不想讨论如何解决它-就像我们在上一个问题中所做的那样。现在我只想改善它。你能再帮我一次吗?
应该影响随机性的战术设置:
注意:
策略0和策略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, $teamname_att, $strength_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, $teamname_def, $strength_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, $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
}
更新(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中,它将稍微快一些(通常少于12毫秒,但是由于您在递归函数内部调用了该函数六次,每次运行可能会节省十分之几秒的时间)。
我认为这样做会更好(无论是从读者的角度还是从
最后,在几次情况下,您将使用具有相同参数的相同函数的相同调用。提前致电:
$goalieStrength = strengths_weight($strength_def['goalkeeper']);
希望这可以帮助。