Jak zrobić rozbudowaną walkę pvp

Witam napisałem taki kod:

Drużyna "A"










Druzyna "B"
















<?PHP

$a1=$_POST['a1'];

$a2=$_POST['a2'];

$a3=$_POST['a3'];

$a4=$_POST['a4'];



$b1=$_POST['b1'];

$b2=$_POST['b2'];

$b3=$_POST['b3'];

$b4=$_POST['b4'];


if(isset($_POST['walcz']))

{

$ahp1=$ahp2=$ahp3=$ahp4=100;

$bhp1=$bhp2=$bhp3=$bhp4=100;


printf("


$a1->$ahp1
$a2->$ahp2
$a3->$ahp3
$a4->$ahp4



VS


$b1->$bhp1
$b2->$bhp2
$b3->$bhp3
$b4->$bhp4



");


$akogo=array($b1, $b2, $b3, $b4);

$bkogo=array($a1, $a2, $a3, $a4);


for($runda==0; $runda<=9; $runda++)

{

$r=$runda+1;


$alos1=rand(0, 3);

$alos2=rand(0, 3);

$alos3=rand(0, 3);

$alos4=rand(0, 3);




$blos1=rand(0, 3);

$blos2=rand(0, 3);

$blos3=rand(0, 3);

$blos4=rand(0, 3);



if($alos1==0 and $ahp1>0)

{

$bhp1=$bhp1-rand(10, 21);

}

elseif($alos1==1 and $ahp1>0)

{

$bhp2=$bhp2-rand(10, 21);

}

elseif($alos1==2 and $ahp1>0)

{

$bhp3=$bhp3-rand(10, 21);

}

elseif($alos1==3 and $ahp1>0)

{

$bhp4=$bhp4-rand(10, 21);

}

if($alos2==0 and $ahp2>0)

{

$bhp1=$bhp1-rand(10, 21);

}

elseif($alos2==1 and $ahp2>0)

{

$bhp2=$bhp2-rand(10, 21);

}

elseif($alos2==2 and $ahp2>0)

{

$bhp3=$bhp3-rand(10, 21);

}

elseif($alos2==3 and $ahp2>0)

{

$bhp4=$bhp4-rand(10, 21);

}

if($alos3==0 and $ahp3>0)

{

$bhp1=$bhp1-rand(10, 21);

}

elseif($alos3==1 and $ahp3>0)

{

$bhp2=$bhp2-rand(10, 21);

}

elseif($alos3==2 and $ahp3>0)

{

$bhp3=$bhp3-rand(10, 21);

}

elseif($alos3==3 and $ahp3>0)

{

$bhp4=$bhp4-rand(10, 21);

}

if($alos4==0 and $ahp4>0)

{

$bhp1=$bhp1-rand(10, 21);

}

elseif($alos4==1 and $ahp4>0)

{

$bhp2=$bhp2-rand(10, 21);

}

elseif($alos4==2 and $ahp4>0)

{

$bhp3=$bhp3-rand(10, 21);

}

elseif($alos4==3 and $ahp4>0)

{

$bhp4=$bhp4-rand(10, 21);

}

printf("




Runda $r


");

if($ahp1>0){printf("$a1 -> $ahp1 hp zaatakował $akogo[$alos1]
");}

if($ahp2>0){printf("$a2 -> $ahp2 hp zaatakował $akogo[$alos2]
");}

if($ahp3>0){printf("$a3 -> $ahp3 hp zaatakował $akogo[$alos3]
");}

if($ahp4>0){printf("$a4 -> $ahp4 hp zaatakował $akogo[$alos4]

");}


if($blos1==0 and $bhp1>0)

{

$ahp1=$ahp1-rand(10, 21);

}

elseif($blos1==1 and $bhp1>0)

{

$ahp2=$ahp2-rand(10, 21);

}

elseif($blos1==2 and $bhp1>0)

{

$ahp3=$ahp3-rand(10, 21);

}

elseif($blos1==3 and $bhp1>0)

{

$ahp4=$ahp4-rand(10, 21);

}

if($blos2==0 and $bhp2>0)

{

$ahp1=$ahp1-rand(10, 21);

}

elseif($blos2==1 and $bhp2>0)

{

$ahp2=$ahp2-rand(10, 21);

}

elseif($blos2==2 and $bhp2>0)

{

$ahp3=$ahp3-rand(10, 21);

}

elseif($blos2==3 and $bhp2>0)

{

$ahp4=$ahp4-rand(10, 21);

}

if(balos3==0 and $bhp3>0)

{

$ahp1=$ahp1-rand(10, 21);

}

elseif($blos3==1 and $bhp3>0)

{

$ahp2=$ahp2-rand(10, 21);

}

elseif($blos3==2 and $bhp3>0)

{

$ahp3=$ahp3-rand(10, 21);

}

elseif($blos3==3 and $bhp3>0)

{

$ahp4=$ahp4-rand(10, 21);

}

if($blos4==0 and $bhp4>0)

{

$ahp1=$ahp1-rand(10, 21);

}

elseif($blos4==1 and $bhp4>0)

{

$ahp2=$ahp2-rand(10, 21);

}

elseif($blos4==2 and $bhp4>0)

{

$ahp3=$ahp3-rand(10, 21);

}

elseif($blos4==3 and $bhp4>0)

{

$ahp4=$ahp4-rand(10, 21);

}



if($bhp1>0){printf("$b1 -> $bhp1 hp zaatakował $bkogo[$blos1]
");}

if($bhp2>0){printf("$b2 -> $bhp2 hp zaatakował $bkogo[$blos2]
");}

if($bhp3>0){printf("$b3 -> $bhp3 hp zaatakował $bkogo[$blos3]
");}

if($bhp4>0){printf("$b4 -> $bhp4 hp zaatakował $bkogo[$blos4]
");}

printf("




$a1->$ahp1
$a2->$ahp2
$a3->$ahp3
$a4->$ahp4



VS


$b1->$bhp1
$b2->$bhp2
$b3->$bhp3
$b4->$bhp4



");




if($ahp1<=0 and $ahp2<=0 and $ahp3<=0 and $ahp4<=0)

{

printf("Wygrali obrońcy!!!");

break;

}

elseif($bhp1<=0 and $bhp2<=0 and $bhp3<=0 and $bhp4<=0)

{

printf("Wygrali napastnicy.");

break;

}

elseif($runda==9)

{

printf("Remis Gracze z obu drużyn przetrwali.");

}





}





}



?>

działa tak jak chce tylko jak jakiś gracz straci całe hp to dalej można go atakować. jak zrobić żeby nie dało się atakować tych co stracili całe hp?

Wogule czy ten kod jest poprawny czy tak można robić czy trzeba jakoś inaczej? nigdy takiego czegoś nie pisałem i chce się nauczyć jak to powinno działać.

Nie mam zielonego pojęcia po co coś tak nieużytecznego pisać, ale 2 błędy w PHP mogę wytknąć:

  • w pętli for na początek musisz deklarować $runda z przypisaniem 0, a nie sprawdzeniem czy jest równe 0 - ale może to tylko ‘literówka’ w kodzie

  • stała ‘balos’ jednak chyba miała być zmienną ‘$blos’ (linijka 165)

Kwestia pomysłu na rozwiązanie tego problemu “atakowania nieżywych” wymaga tylko odrobiny wyoobraźni - pomoże np. sprawdzanie w stylu:

1.losujemy cel

2.sprawdzamy jego hp

3.jeśli hp celu <=0 idź do punktu 1.

Oczywiście takie coś tylko jeśli wiesz, że choć jeden ma hp > 0;

Dodatkowa kwestia, to przewaga drużyny atakującej jako pierwsza (mam nadzieję że wiesz dlaczego)- tutaj rozwiązaniem mogłoby być weryfikowanie ‘zdolności do walki’ na początku rundy, przed otrzymaniem ciosów.

PS Piszemy “w ogóle”.

A jak inaczej napisać taką walke?? Nie wiem ja sie tylko ucze. Dlaczego nieużyteczne??

Po prostu nie widzę, gdzie mógłbyś ten skrypt zamieścić/wykorzystać - ale do nauki - czemu nie.

Ważne, że próbujesz.

Trochę na razie pomyliłeś się z tytułem: pvp=“gracz kontra gracz”, a tutaj w zasadzie żadnego gracza nie ma :slight_smile:

Edit:

Trochę mi się nudziło, a jako że też uczę się PHP, uruchomiłem te walki według Twojego zamierzenia :smiley:

Przewaga napastników jest rzeczywiście wielka, a statystyki wyglądają mniej więcej tak (dla 10000 prób - skrypt wykonuje się ~4s ;p )

Podejście pierwsze: Obrońcy wygrali 2307 razy, napastnicy 7693 razy, a remis był 0 razy

Podejście drugie: Obrońcy wygrali 2309 razy, napastnicy 7691 razy, a remis był 0 razy

I trzecie: Obrońcy wygrali 2307 razy, napastnicy 7693 razy, a remis był 0 razy

W miarę zbliżone wyniki:

Obrońcy wygrali 4983 razy, napastnicy 4866 razy, a remis był 151 razy

Obrońcy wygrali 4977 razy, napastnicy 4874 razy, a remis był 149 razy

Obrońcy wygrali 4979 razy, napastnicy 4867 razy, a remis był 154 razy

otrzymamy przy zmianie hp obrońców na 110 w stosunku do 100 u atakujących. Zresztą, trzymaj wersję z moimi przeróbkami:

<?php 

$a=$b=array();

for($i=1;$i<=4;$i++)$a[$i-1] = (isset($_POST["a$i"])) ? $_POST["a$i"] : ''; // Dla wygody użycia przepisuję sobie

for($i=1;$i<=4;$i++)$b[$i-1] = (isset($_POST["b$i"])) ? $_POST["b$i"] : ''; // z $_POST na krótkie zmienne

?>




Drużyna "A"










Druzyna "B"














<?PHP

function atak($jakadruzynaatakuje, $ktoatakuje) { // atak wyrzucony do osobnej funkcji, żeby nie powtarzać kodu wiele razy

global $ahp, $bhp, $a, $b; // te zmienne spoza funkcji będą tutaj w środku potrzebne

	if($jakadruzynaatakuje=='a') { // jeśli atakują napastnicy, będziemy bić obrońców

	if($bhp[0]>0||$bhp[1]>0||$bhp[2]>0||$bhp[3]>0) //sprawdzamy, czy jest kogo bić

		while(1) { //jeśli tak, to szukamy celu "do skutku"

			$cel=rand(0,3);							

			if($bhp[$cel]>0) { //sprawdzamy, czy cel żyje

				$mocataku=rand(10, 21); //moc ataku zapisuję do raportu		

				$bhp[$cel]-=$mocataku; //odjęcie hp

				echo "$a[$ktoatakuje] atakuje $b[$cel] i zadaje $mocataku obrażeń!
"; //wyplucie raportu uderzenia

				return; //koniec funkcji

			}

		}

	}

	elseif ($jakadruzynaatakuje=='b') { // atakują obrońcy -> celu szukamy wśród napastników

	if($ahp[0]>0||$ahp[1]>0||$ahp[2]>0||$ahp[3]>0) //sprawdzamy, czy jest kogo bić

		while(1) { //jeśli tak, to szukamy celu "do skutku"

			$cel=rand(0,3);

			if($ahp[$cel]>0) { //sprawdzamy, czy cel żyje

				$mocataku=rand(10, 21); 	

				$ahp[$cel]-=$mocataku; //odjęcie hp

				echo "$b[$ktoatakuje] atakuje $a[$cel] i zadaje $mocataku obrażeń!
"; //wyplucie raportu uderzenia

			return; //koniec funkcji

			}

		}

	}

	return; //tu też koniec funkcji, ale tylko jeśli $jakadruzynaatakuje było nieprawidłowe

}


/* $obr=$nap=$rem=0;

for($licznik=0;$licznik<10000;$licznik++)

{

ob_start(); */


if(isset($_POST['walcz'])) {

$ahp = array(100,100,100,100); // przypisanie hp atakującym

$bhp = array(110,110,110,110); // przypisanie hp obrońcom


echo("

| $a[0]->$ahp[0] $a[1]->$ahp[1] $a[2]->$ahp[2] $a[3]->$ahp[3] | VS | $b[0]->$bhp[0] $b[1]->$bhp[1] $b[2]->$bhp[2] $b[3]->$bhp[3] |

“); for($runda=1; $runda<=10; $runda++) { echo(”

Runda $runda

"); for($j=0;$j<=3;$j++) if($ahp[$j]>0) atak(‘a’, $j); //grupa napastników atakuje echo " “; for($j=0;$j<=3;$j++) if($bhp[$j]>0) atak(‘b’, $j); //grupa obrońców atakuje echo(”

| $a[0]->$ahp[0] $a[1]->$ahp[1] $a[2]->$ahp[2] $a[3]->$ahp[3] | VS | $b[0]->$bhp[0] $b[1]->$bhp[1] $b[2]->$bhp[2] $b[3]->$bhp[3] |

"); if($ahp[0]<=0 and $ahp[1]<=0 and $ahp[2]<=0 and $ahp[3]<=0) { //$obr++; echo(“Wygrali obrońcy!!!”); break; } elseif($bhp[0]<=0 and $bhp[1]<=0 and $bhp[2]<=0 and $bhp[3]<=0) { //$nap++; echo(“Wygrali napastnicy.”); break; } elseif($runda==10) { //$rem++; echo(“Remis Gracze z obu drużyn przetrwali.”); } } } /* ob_end_clean(); } echo “Obrońcy wygrali $obr razy, napastnicy $nap razy, a remis był $rem razy”; */ ?>[/code]

Zakomentowane fragmenty kodu były od powyższych “statystyk”

while(1) { //jeśli tak, to szukamy celu "do skutku"

         $cel=rand(0,3);                     

         if($bhp[$cel]>0) { //sprawdzamy, czy cel żyje

            $mocataku=rand(10, 21); //moc ataku zapisuję do raportu      

            $bhp[$cel]-=$mocataku; //odjęcie hp

            echo "$a[$ktoatakuje] atakuje $b[$cel] i zadaje $mocataku obrażeń!
"; //wyplucie raportu uderzenia

            return; //koniec funkcji

         }

      }

wut? Przecież to nie jest całkowicie poprawnym algorytmem, z technicznego punktu widzenia, nie można udowodnić własności stopu…

Skoro linijkę wyżej sprawdzasz, czy jest ktoś do bicia, to możesz go przekazać, unikniesz wtedy tego nie-determinizmu.

Wiem, że można to rozpisać o parę linijek dla usprawnienia procesu wyszukiwania, ale stop w tej pętli wykonał się dla każdego jej uruchomienia (co najmniej milion razy) i wykona się na pewno, więc nie ma co dramatyzować :wink:

Nie rozumiem za bardzo tego “przekazywania” celu - sprawdziłem przecież tylko, czy istnieje jeszcze drużyna, wcześniej cel nie był wybrany…

Chociaż fakt faktem, moje rozwiązanie jest o tyle błędne, że nie jestem w stanie oszacować liczby przebiegów - w teorii nieskończona - ale na to nieskończenie małe prawdopodobieństwo.