Futbol simülasyon algoritması geliştirilmesi

4 Cevap php

Başka bir soruda, size futbol için bir simülasyon algoritma oluşturmak için bana yardımcı oldu. I got some very good answers there. Tekrar teşekkürler!

Şimdi bu algoritmayı kodlu ettik. Ben onu geliştirmek ve bunun içinde olabilir küçük hataları bulmak istiyorum. Ben bunu çözmek için nasıl tartışmak istemiyorum - biz son soru olduğu gibi. Şimdi sadece bunu geliştirmek istiyorum. Beni tekrar yardım edebilir miyim?

  1. Herhangi bir hata var mı?
  2. Iç içe geçmiş yapısı if-cümlecikleri Tamam mı? Geliştirilmiş olabilir mi?
  3. Taktik benim açıklama göre doğru entegre edilmiştir?

Tactical settings which should have an influence on the rveomness:

  • $ Taktikleri [x] [0] ayarı (1 = savunma, 2 = nötr, 3 = saldırgan): yüksek değeri zayıf olan savunma ve güçlü suçtur
  • $ Taktikleri oyun x hızı (1 = Yavaş, 2 = orta, 3 = hızlı): yüksek değerini daha iyi fırsatlar vardır ama daha yüksek bir hızlı karşı atak yakalanma riski olduğunu
  • Paso $ taktikleri [x] [2] mesafe (1 = kısa, 2 = orta, 3 = uzun): daha yüksek değer elde daha az ama daha iyi fırsatlar ve daha sık ofsayt vardır
  • Değişikliklerin $ taktikleri [x] [3] oluşturma (1 = 2 = orta, 3 = riskli güvenli): yüksek değeri daha iyi fırsatlar vardır ama daha yüksek bir hızlı karşı atak yakalanma riski
  • Savunma $ taktikleri [x] [4] basıncı (1 = düşük, 2 = orta, 3 = yüksek): yüksek değer olacak daha hızlı karşı saldırıları
  • $ Taktikleri [x] [5] agresivitesinin (1 = düşük, 2 = orta, 3 = yüksek): yüksek değer faulü ile duracaktır daha saldırıları

Note: Tactic 0 ve tactic 4 vardır partly integrated in the rest of the engine, not needed in this function.

The current algorithm:

<?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_rve(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 clevardırs 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 clevardırs 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
}

4 Cevap

Bu oldukça karmaşık bir sorundur, ve ben onu alırsınız nasıl verimli emin değilim gibi genel olarak görünüyor.

O dedi, ben kesinlikle size yardımcı olacak bazı şeyler gördük.

Önce parametreleri değişkenleri yazarsınız. Bu mutlaka kodun daha hızlı yapmak değil, ama daha kolay okumak ve hata ayıklama yapmak istiyorum. Sonra, ben, $ teamname_def parametreleri $ teamname_att kaldırmak ve sadece ilişkisel $ strength_att, $ strength_def dizilerde değerler olarak bu var. Bu veriler her zaman zaten eşleştirilmiş olduğundan, bu yanlışlıkla diğer takım için referans olarak bir takımın adını kullanarak riskini azaltacaktır.

Bu yüzden sürekli dizide değerleri aramak zorunda kalmazsınız yapacaktır:

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

Tüm desen var, üç yardımcı fonksiyonları vardır:

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

Bu yerine bu kullandığınızda, işlevi çalıştırmak her zaman ekstra bir değişken (pahalıya mal olabilir bir şey) oluşturmak zorunda anlamına gelir beri:

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);
}

Ben yardım edemem ama sürekli geliyor bu model fark olamazdı:

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

Benim genel deneyim comment_action içine $ matchReport arasında birleştirme taşırsanız, o zaman bir düzine milisaniye daha Genellikle az (sadece slightly daha hızlı olacak ama yani bu işlevini yarım düzine kere diyorlar beri özyinelemeli işlev içinde, bu) çalışan başına bir saniyenin birkaç onda tıraş olabilir.

Bu bir okuyucu açısından ve hem de (çok daha iyi akış olacağını düşünüyorum

Son olarak, aynı parametresi ile aynı işlevi aynı çağrı kullanacak birkaç kez vardır. Ön bu çağrı yapmak:

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

Umarım bu yardımcı olur.

I (hızlı) bunun üzerinden okumak ve ben bir kaç şey fark ettim:

  • Kırmızı / sarı kart dağıtıldı yüzde alanın tüm ünde aynı, bu kasıtlı olduğunu? Ben bir futbol adam değilim, ama ben suçlar ilk ziyade, alanın son üçte gerçekleşmesi daha olası olduğunu söyleyebilirim. (Eğer ilk üzerinde iseniz, büyük olasılıkla savunma Çünkü)

  • Bir penaltı attı olduğunu belirlemek için yüzde her takım için, ancak bazı takımlar, doğrusu oyuncular, diğerlerine göre bir ceza puanı daha muhtemel aynıdır.

  • Eğer dikkate korner vuruşu, bir faul sonrası olası yaralanmaları veya hedefleri almıyorsun (raporda kayda değer olabilir) kafasını kullanarak attı.

Bunun dışında, sadece lot kez bu simülasyonu çalıştırmak ve seçtiğiniz değerleri doğru olup olmadığını görmek gerekir; algoritması çimdik. Yapılacak en iyi şey, el çimdik o (örneğin bir dosyadan tüm sabitleri okumak ve farklı değerler ve farklı ekipleri ile bir kaç yüz simülasyonlar), yapılacak en kolay şey denemek için bir Genetik Algoritma uygulamak ve bulmak için muhtemelen daha iyi değerler.

Temelde burada ne var gerçek oynanış / ai kodu, yani kod bu tür yönetmek için oyun stüdyoları tarafından kullanılan teknikler üzerinde okumak isteyebilirsiniz. (Bir şey örneğin, daha sonra share / daha kolay çimdik bir google elektronik tablodaki değişkenleri koymaktır).

Eğer gerçek bir futbol maçı var bazı şeyleri kaçırıyoruz olsa da, genellikle bu durumlarda bunun doğru bir simülasyon sağlamak için daha güzel bir oyun sağlamak için daha önemlidir, çünkü mümkün olduğunca gerçekçi olmaya çalışıyorum hiçbir nokta yoktur.

Yous eksik gibi görünüyor: -

#include oscar.h;
void function dive (int ball_location, int[] opposition, int[] opposition_loc) {
    if (this.location != PenaltyBox || ball_location != PenatlyBox)
       return;
    } else {
       for (x = 0; x < 11; x++) {
           if ( opposition_loc[x] = PenaltyBox ) {
               scream(loudly);
               falldown();
               roll_around();
               cry();
               roll_around();
               scream(patheticaly);
               plead_with_ref();
               return;
            }
     }
     return;
}

Ne kadar sıklıkla bu değerler kontrol olacak? O bir sürü insan tarafından kullanılıyor olacak ve sürekli bu aşkın recursing eğer / else ifadeleri, ben bellek bir sürü yeme ve oldukça yavaş çalışıyor görebilirsiniz.

Belki ama orada bir kaç anahtarları eğer kimi en yerini olabilir?

Ben hız iyileştirilmesi için görebilirsiniz hepsi. Algoritması kendisi için olduğu gibi, ben biraz sonra başka kimse yok eğer üzerinde incelemek gerekir.