Thursday, February 4, 2016

Limbajul PHP. Sesiuni. "Guess my number" game (link aplicatie)

Enuntul urmator este dat ca tema facultativa in cadrul unui curs PHP procedural iar rezolvarea sa implica realizarea unei aplicatii tipice pentru lucrul cu sesiuni si persistenta informatiei intre apelurile unui script PHP.

" Sa se implementeze urmatorul joc folosind sesiuni: computerul alege un numar pe care utilizatorul incearca sa il ghiceasca prin incercari repetate, folosind un formular. De fiecare data cand nu a ghicit, va fi ghidat afisandu-i-se "mai aproape" sau "mai departe". Cand numarul a fost ghicit, utilizatorul este felicitat, indicandu-i-se si numarul de incercari ce au condus la reusita, iar jocul va fi resetat."

Mai intai, linkul catre aplicatie si apoi rezolvarea comentataJ

Sunt trei aspecte care trebuie solutionate:

1) valoarea curenta introdusa si valoarea anterior introdusa trebuie comparate, fiecare, cu numarul ales de calculator. Daca valoarea anterior introdusa este 'mai aproape' de numarul ales (in sensul valorii absolute a diferentei celor doua numere) decat valoarea curenta, se va afisa mesajul "mai departe". In cazul contrar, daca la initializarea curenta se introduce o valoare mai apropiata de numar decat cea anterioara, se va afisa 'mai aproape'.

Transmiterea valorii curente si a valorii anterior introduse la o aceeasi accesare a scriptului se poate face cu un element "hidden" inclus in formular.  Valoarea curenta poate fi stocata in tabloul $_SESSION in vederea afisarii numarului de incercari.

Ramane de rezolvat problema indexarii lui $_SESSION, care este un tablou asociativ ce nu suporta chei strict numerice.

O idee ar fi indexarea cu un string ce reprezinta timpul Unix pe masina locala intr-un format oarecare. Functia date() intoarce un astfel de string dupa un format specificat de utilizator. 

Dupa fiecare incercare nereusita (== accesare a scriptului) se poate genera aceasta valoare in vederea stocarii intr-o variabila, s-o notam $current, pe care o vom putea folosi drept index:

$current = date('Y-m-d, h:i:s A'); unde 'Y-m-d, h:i:s A' este stringul de formatare a valorii numerice reprezentand tipul Unix.

2) generarea numarului aleator intre anumite limite (de ex, 1, 100) si persistenta acestei valori la multiplele apeluri ale scriptului.

Sa ne imaginam ca suntem la prima accesare a scriptului: cookie-ul de sesiune a fost transmis de functia session_start() iar tabloul asociativ $_SESSION este momentan gol.

Definim si initializam cu sirul vid " variabila ce va stoca numarul generat de computer:

$number = "";

Mai departe rationam in felul urmator:

daca este definita variabila $_SESSION['number'] (stim ca momentan nu este definita, scriptul fiind la prima apelare) atunci $number = $_SESSION['number']; altfel, vom adauga in $_SESSION o valoare numerica aleatoare indexata cu cheia 'number' si vom atribui acest rezultat lui $number, $number = $_SESSION['number'] = rand(1, 100);

La urmatoarele apeluri ale scriptului se va executa prima ramura a clauzei if/else, pentru ca $_SESSION['number']  a fost deja initializata cu ocazia primei accesari.

In felul acesta, informatia din $number se prezerva pana se iese din program (pana cand utilizatorul ghiceste numarul $number).

3) resetarea scriptului. La ghicirea valorii $number, codul afiseaza un mesaj de succes si itereaza prin tabloul $_SESSION afisand valorile corespunzatoare tuturor indecsilor cu exceptia indexului 'number'. Aceste valori reprezinta tentativele nereusite de a ghici valoarea lui $number iar numarul lor se poate deterima usor cu ocazia iterarii prin tablou cu foreach(…)

Resetarea tabloului $_SESSION (= array()) si apelul functiei session_destroy() asigura conditiile de resetare a jocului. Trebuie mentionat insa ca daca vrem sa facem "curatentie completa" dupa un joc si sa distrugem si cookie-ul de sesiune PHPSESSID va trebui sa folosim urmatoarea sintaxa:

setcookie(session_name(), "", time() - 86400, '/', "");

Aceasta, intrucat cookie-ul trimis pe browserul client de catre functia session_start() are by default domeniul "" (orice domeniu) si calea "/";

Codul si printscreen-ul:

<!DOCTYPE HTML>
<head>
            <title>Guess the number v2</title>
            <style>
            #header1{
            width:99%;
            padding:6px;
            background-color: lightblue;
            text-align: center;
            }
            #rsector{
            width:70%;
            height:600px;
            float:right;
            background-color: lightgrey;
            padding:10px;
            text-align: center;
            }
            table, td, tr{
            border:2px solid black;
            border-collapse:collapse;
            width:70%;
            margin-left:15%;
            margin-right:15%;
            }
            </style>
</head>
<body style = "background-color: AntiqueWhite">
<div id = "header1">
<h3>I've picked a number between 1 and 100 and I dare you to guess it!</h3>
</div>
<?php
session_start();

$hid = "";

$number = "";

if(isset($_SESSION['number'])) $number = $_SESSION['number'];
else
{
            $_SESSION['number'] = rand(1,100);
            $number = $_SESSION['number'];
}

$res =<<<TR
<form method = "POST" action = "$_SERVER[PHP_SELF]">
<input type = 'submit' name = 'destruct' value = "Reset">
</form>
TR;

if(in_array("Ok", $_POST))
{
            if(is_numeric($_POST['guess']))
            {
                        if(!abs($_POST['guess'] - $number))
                        {
                                    setcookie(session_name(), "", time() - 86400, '/', '');
                                    // '' is the domain made available for PHPSESSID by function session_start();
                                    //  '/' is the path set by default
                                    //   futile line; $_SESSION will be unset and the session file will be destroyed
                                    
                                   $count = 0;
                                    echo "<div id = \"rsector\">";
                                    echo "<br />Lucky guess!The hidden number is:";
                                    echo "<h3 style = \"color:red;text-shadow:2px 1px DarkOrchid\">$number</h3>";
                                    echo "You can find your unlucky guesses in the next table:<br />";
                                    echo "<br><table><tr><td> Value </td><td>At the moment</td></tr>";
                                    
                                    foreach($_SESSION as $k=>$v)
                                    {
                                                if($k != 'number')
                                                {
                                                            echo "<tr><td>$v</td><td>$k</td></tr>";
                                                            $count++;
                                                }
                                    }
                                    echo "</table>", "<br />", "You've guessed it after you tried ".($count + 1)." time(s)!";
                                    $_SESSION = array();
                                    session_destroy();
                                    echo $res, "</div></body></html>";
                                    exit;
                        }
                        else
                        {
                                    $current = date('Y-m-d, h:i:s A');
                                    $_SESSION[$current] = $_POST['guess'];
                                    if($_POST['hyde'] == "")
                                    {
                                                echo "<br />Your didn't guess it at your first try!<br />";
                                                echo "Actually, we didn't expect you to do so:-P";
                                    }
                                    else
                                    {
                                                $delta = abs($_SESSION[$current] - $number);
                                                $delta1 = abs($_POST['hyde'] - $number);
                                                if($delta < $delta1) echo "<br />Closer.";
                                                else echo "<br/>You are not getting close!";
                                    }
                                    $hid = $_POST['guess'];
                        }
            }
            else echo "<br />Don't trick me, gimme some numbers!";
}

$formular2 =<<<TD
<form method = "POST" action = "$_SERVER[PHP_SELF]">
<br />Make a guess: <br />
<input type = "text" name = "guess">
<input type = "submit" name = "send" value = "Ok">
<input type = "hidden" name = 'hyde' value = $hid>
</form>
TD;

echo "<br />", $formular2;
?>
</body>

</html>


No comments:

Post a Comment