Я хотел бы создать механизм моделирования, который может имитировать соответствие футбольного матча. Было бы здорово, если бы вы могли мне помочь. Для меня важно решить, какие действия происходят. Слушатели событий для каждого действия могут быть реализованы позже легко. Функция должна только имитировать результаты игры и комментарии к происходящим действиям. Нет необходимости в 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 name, defender name, attacker strength array, defender 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 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 an alternative way)
$redCards[$teamname_def]++;
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_red');
}
// indirect free kick
// only 58.23% because it 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 an alternative way
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot_save');
}
}
else {
// defending team cleares the ball
// only 75% because it 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 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 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 an alternative way
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_penalty_miss');
}
else {
// defending goalkeeper saves
// only 11.5% because it an alternative way
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_penalty_save');
}
}
elseif (Chance_Percent(28)) {
// direct free kick
// only 22.68% because it 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 an alternative way
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_dFreeKick_clear');
}
}
else {
// indirect free kick
// only 58.23% because it 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 an alternative way
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_shot_save');
}
}
else {
// defending team cleares the ball
// only 75% because it an alternative way
$matchReport .= ' '.comment($teamname_def, 'attack_advance_foul_iFreeKick_clear');
}
}
}
else {
// attack passes the 2nd third of the opponent 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 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 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 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 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 х 1,5 х 1,5). Поэтому я не могу интегрировать тактику таким образом. Что еще я могу сделать?
Большое спасибо!
Обновление (2014): Несколько лет спустя я выпустил полную базу кода игры как открытый на GitHub. Вы найдете конкретную реализацию этого моделирования в этом файле, если кому-то это интересно.