【发布时间】: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