Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] pauzowanie i wznawianie wykonywania pętli
Forum PHP.pl > Forum > Przedszkole
Testosteron
Witajcie. Chciałbym napisać skrypt, który mógłbym używać podczas sędziowania pojedynków w armwrestlingu. Rozpisywanie wszystkiego na papierze jest męczące, a poza tym chciałbym poćwiczyć trochę PHP. Sam skrypt powinien losować pary do walki i uwzględniać możliwe błędy i zliczać punkty. Po kliknięciu przy nazwisku danego zawodnika skrypt powinien przyznać mu punkt i dokonać kolejnego losowania. Problem jest jednak zupełnie inny.

Chyba najbardziej oczywistym rozwiązaniem jest utowrzenie pętli, która będzie losowała pary, jednak nie chcę, żeby wylosowane pary pojawiły jako lista, a pojawiła się jedynie wylosowana para. Po walce klikałbym na przycink obok nazwiska zwycięscy. Skrypt dodałby punkt tej osobie a następnie dokonywałby ponownego losowania. Mógłby ktoś udzielić mi jakiś wskazówek, jak to zrobić?
mar1aczi
Jeśli mają być wylosowane pary spośród wszystkich zawodników przed rozpoczęciem rozgrywek, to wykonujesz takie losowanie raz na początku a następnie każde kolejne odświeżenie strony podaje Ci kolejna parę. W przypadku, gdy ma być wylosowana tylko jedna para to losowanie powtarzasz z każdym odświeżeniem strony.
Testosteron
A czy za każdym odświerzeniem strony nie będzie trzeba potwierdzać ponownego wysłania formularza? Wolałbym tego uniknąć. Poza tym jak w takim przypadku różnicować dane, wysyłane po naciśnięciu przycisku? Tzn. w zależności od tego kto wygrał walkę, klikam inny button i wysyłane są inne wartości. Myślałem, że można to zadanie rozwiązać ręcznie, tzn. zamiast submita dać jakąś grafikę i kolejna para byłaby losowana od razu po wyświetleniu pierwszej pary a skrypt modyfikowałby jedynie adres do którego odsyła strona, np. jeden adres mógłby wyglądać tak:
  1. http://www.strona.pl/skrypt.php?win=1&zawodnik1=3&zawodnik2=4

Drugi natomiast
  1. http://www.strona.pl/skrypt.php?win=2&zawodnik1=3&zawodnik2=4

Skrypt na samym początku sprawdzałby kto wygrał i zapisywał wyniki w pliku, a następnie losował kolejną parę. Wydaje mi się, że takie rozwiązanie mogłoby przejść, chociaż raczej nie jest optymalne i jednak wolałbym wysyłać dane metodą POST. Tym bardziej, że ze skryptu będą prawdopodobnie korzystać też inne osoby.
mar1aczi
Cytat(Testosteron @ 9.02.2014, 17:58:04 ) *
A czy za każdym odświeżeniem strony nie będzie trzeba potwierdzać ponownego wysłania formularza?

Wszystko zależy od tego jak to technicznie zrobisz (oprogramujesz), jak chcesz aby działało. Generalnie, nie jest to konieczne.
Cytat(Testosteron)
Poza tym jak w takim przypadku różnicować dane, wysyłane po naciśnięciu przycisku? Tzn. w zależności od tego kto wygrał walkę, klikam inny button i wysyłane są inne wartości.

Np.: korzystając z $_GET, w zależności kto wygrał link będzie miał inną zawartość. Używając $_POST z formularzem, możesz użyć radio button.
Cytat(Testosteron)
Myślałem, że można to zadanie rozwiązać ręcznie, tzn. zamiast submita dać jakąś grafikę i kolejna para byłaby losowana od razu po wyświetleniu pierwszej pary a skrypt modyfikowałby jedynie adres do którego odsyła strona...

AJAX, i będzie jak sobie życzysz smile.gif
Testosteron
Po co AJAX? Skleciłem prosty skrypt. Może zawierać błędy, ponieważ napisałem go na szybko, ale sam zamysł powinien być widoczny:
  1. <?php
  2. $zawodnicy = array('Michał', 'Kacper', 'Sylwek', 'Bonifacy', 'Rafał');
  3.  
  4. If (empty($_GET['win']) || empty($_GET['zawodnik_a']) || empty($_GET['zawodnik_b']) )
  5. {
  6. $wylosowany_a = rand(0, 4);
  7. $wylosowany_b = rand(0, 4);
  8. $zawodnik_a = rand(0, 4);
  9. $zawodnik_b = rand(0, 4);
  10.  
  11. echo $zawodnicy[$wylosowany_a];
  12. echo '<a href="testowy.php?win=' . $wylosowany_a . '&zawodnik_a=' . $zawodnik_a . '&zawodnik_b=' . $zawodnik_b . '"> [Głosuj]</a><br>';
  13. echo $zawodnicy[$wylosowany_b];
  14. echo '<a href="testowy.php?win=' . $wylosowany_b . '&zawodnik_a=' . $zawodnik_a . '&zawodnik_b=' . $zawodnik_b . '"> [Głosuj]</a>';
  15. } else {
  16. //jakiś tam skrypt na zapisywanie wyników
  17. $wylosowany_a = $_GET['zawodnik_a'];
  18. $wylosowany_b = $_GET['zawodnik_b'];
  19. $zawodnik_a = rand(0, 4);
  20. $zawodnik_b = rand(0, 4);
  21.  
  22. echo $zawodnicy[$wylosowany_a];
  23. echo '<a href="testowy.php?win=' . $wylosowany_a . '&zawodnik_a=' . $zawodnik_a . '&zawodnik_b=' . $zawodnik_b . '"> [Głosuj]</a><br>';
  24. echo $zawodnicy[$wylosowany_b];
  25. echo '<a href="testowy.php?win=' . $wylosowany_b . '&zawodnik_a=' . $zawodnik_a . '&zawodnik_b=' . $zawodnik_b . '"> [Głosuj]</a>';
  26. }
  27. ?>

Co myślisz o takim sposobie rozwiązania tego problemu? Zda egzamin w praktyce?

@Edit
Jednak coś nie gra. Dopisałem jedną linijkę, która wyświetla imię zwycięscy. Skrypt zachowuje się jak chce. Czasami wszystko jest ok, a za chwilę pomija linijkę dotyczącą wyświetlenia imienia zwycięscy. Wtedy też przy odświeżaniu strony, imiona zawodników zmieniają się. Nie powinno do tego dochodzić, jeśli adres jest ten sam. Wie ktoś jaka może być przyczyna?
Martin-ZG
To losowanie nie jest zbyt poprawne np. możesz wylosować kilka razy tego samego zawodnika. W najgorszym przypadku będziesz miał pary typu Sylwek z Sylwek i Sylwek z Sylwek. Ja bym ustalił na sztywno, że 0 gra z 1, 2 z 3 itpd. I mieszał tablicę. Że raz Sylwek jest jeden, a innym razem Kacper.

Kod
<?php

for( $i = 0; $i <rand(0, 5); $i++ )
{
    $wylosowanyindeks=rand(0,4)
    $wstawdo=rand(0,4)
    
    $bufor=$pary[$wstawdo];
    $pary[$wstawdo]=$pary[$wylosowanyindeks];
    $pary[$wylosowanyindeks]=$bufor
}
?>


System punktowania też można w formie tablicy.

Gracz | punkty | czy wygral?
------------------
Sylwek | 0 | tak (+1)
--------------------
Testosteron
Tak jak pisałem, to był jedynie szkielet skryptu. Problem był zupełnie inny - w momencie, kiedy został wylosowany zawodnik o indeksie 0, skrypt zaczynał się sypać, np. podczas odświeżania strony następowało ponowne losowanie zawodników co nie powinno mieć miejsca. Nie mam pojęcia dlaczego skrypt reagował w ten sposób, ale trochę go przebudowałem. Tylko, że podczas uruchamiania pliku walka.php pojawiało się ostrzeżenie, że zmienna $win nie ma przypisanej wartości. Dlatego stłumiłem to ostrzeżenie, chociaż nie wiem, czy nie będzie to miało wpływ na stabilność skryptu, kiedy zostanie udostępniony.
  1. <?php
  2. $zawodnicy = array('Michał', 'Kacper', 'Sylwek', 'Bonifacy', 'Rafał');
  3. If (empty($_GET['a'])|| empty($_GET['b']) ){
  4. $a = rand(1, 5);
  5. $b = rand(1,5);
  6. while($a==$b){
  7. $a = rand(1,5);
  8. $b = rand(1,5);
  9. }
  10. header('location: walka.php?a=' . $a . '&b=' . $b);
  11. } else {
  12. $zawodnik_a = $zawodnicy[$_GET['a']-1];
  13. $zawodnik_b = $zawodnicy[$_GET['b']-1];
  14. $win_a = $_GET['a']-1;
  15. $win_b = $_GET['b']-1;
  16. $a = rand(1, 5);
  17. $b = rand(1,5);
  18. while($a==$b){
  19. $a = rand(1,5);
  20. $b = rand(1,5);
  21. }
  22. @$zwyciezca = $zawodnicy[$_GET['win']];
  23. echo $zwyciezca . '<br />';
  24. echo $zawodnik_a . '<a href="walka.php?win=' . $win_a . '&a=' . $a . '&b=' . $b . '">[wygral]</a><br />';
  25. echo $zawodnik_b . '<a href="walka.php?win=' . $win_b . '&a=' . $a . '&b=' . $b . '">[wygral]</a><br />';
  26. }
  27. ?>
Martin-ZG
Przy odświeżaniu strony skrypt zaczyna się od nowa. Takie uroki php. Żeby zapamiętać stany zmiennych trzeba użyć cookies, albo sesji, no albo bazy danych. Jeżeli chodzi o to ostrzeżenie, to nie powinno być kłopotów, ale dobry zwyczajem jest ustalać wartości początkowe.
Testosteron
Jak mogę ustalić wartość początkową, skoro jeszcze nikt nie wygrał walki?
Martin-ZG
W uproszczeniu skrypt php przy wejściu na stronę uruchamia się i zaczyna wykonywać instrukcję i po ostatniej się kończy i przestaje działać. To nie jest program działający, aż do chwili zamknięcia go przez użytkownika.

Cytat(Testosteron @ 10.02.2014, 19:34:48 ) *
Jak mogę ustalić wartość początkową, skoro jeszcze nikt nie wygrał walki?

Jak rozumiem $win wskazuje kto wygrał. Na początku nikt nie wygrał, więc $win='', a później $win='a' albo $win='b'.

"Nikt " to też jest jakiś początkowy stan.
Testosteron
Cytat
W uproszczeniu skrypt php przy wejściu na stronę uruchamia się i zaczyna wykonywać instrukcję i po ostatniej się kończy i przestaje działać. To nie jest program działający, aż do chwili zamknięcia go przez użytkownika.

Nie za bardzo rozumiem Twoją wypowiedź. Na wejściu skrypt wyświetla zawodników i generuje odpowiedni odnośnik. Kiedy jeden z zawodników wygra, klikam na link i skrypt wykonywany jest ponownie, czyli w tym zakresie spełnia swoje zadanie.
Cytat
"Nikt " to też jest jakiś początkowy stan.

No w sumie tak, ale pierwsza instrukcja warunkowa rozwiązuje ten problem. Sprawdza, czy zmienna $a i $b są puste, czyli nie zostali jeszcze wylosowany zawodnicy (co ma miejsce jeśli żadne walki nie zostały jeszcze przeprowadzone). Jeżeli taka sytuacja ma miejsce, losuje się zawodników i rozpoczyna swoje właściwe działanie.
Martin-ZG
Cytat
Nie za bardzo rozumiem Twoją wypowiedź. Na wejściu skrypt wyświetla zawodników i generuje odpowiedni odnośnik. Kiedy jeden z zawodników wygra, klikam na link i skrypt wykonywany jest ponownie, czyli w tym zakresie spełnia swoje zadanie.



No w sumie tak, ale pierwsza instrukcja warunkowa rozwiązuje ten problem. Sprawdza, czy zmienna $a i $b są puste, czyli nie zostali jeszcze wylosowany zawodnicy (co ma miejsce jeśli żadne walki nie zostały jeszcze przeprowadzone). Jeżeli taka sytuacja ma miejsce, losuje się zawodników i rozpoczyna swoje właściwe działanie.

Po prostu pisałeś, że po odświeżeniu strony następowało losowanie zawodników. Dzieje się tak ponieważ skrypt rozpoczął się od nowa.


To jest dobry przykład dlaczego dobrym zwyczajem jest wpisywanie wartości początkowych. Mnie uczono, że nigdy nie ma pustych zmiennych. Zmienna bez wartości początkowej przechowuje nie wiadomo co. I jak to sprawdzasz np w if, to mogą dziać się dziwne rzeczy. Zadziała mimo, że nie powinien.
Testosteron
Tak, ale skrypt losuje jedynie zawodników do następnej rundy, a wyświetla tych z pasku adresu. Tak więc, jeśli adres jest ten sam to przy odświeżaniu nie powinno się nic dziać. Zresztą problem występował WYŁĄCZNIE, kiedy został wylosowany zawodnik o identyfikatorze 0. W innym przypadku wszystko działało w porządku. Przerobiłem skrypt (kod podawałem wyżej) tak, żeby zawodnicy mieli identyfikatory wyłącznie powyżej zera i wszystko śmiga oneeyedsmiley02.png . Z czego to może wynikać?
Martin-ZG
empty

Z tego wynika, że jeżeli zmienna ma 0 to empty jest true.
Testosteron
Faktycznie, dzięki
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.