我想建立一个可以模拟足球(足球)比赛的模拟引擎。如果你能帮助我,那就太好了。对我来说重要的是决定发生哪些动作。每个动作的事件监听器可以在以后轻松实现。该功能应该只模拟游戏结果和对发生动作的评论。不需要 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=进攻):数值越高,防守越弱,进攻越强
- speed of play (1=slow, 2=medium, 3=fast):数值越高,机会越大,但获得快速反击的风险越高
- 传球距离(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 年):几年后,我现在在 GitHub 上以开源形式发布了游戏的完整代码库。如果有人感兴趣,您将在此文件中找到此模拟的具体实现。