Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Shuffle-peli

Tzama [12.05.2006 22:29:05]

#

Miten saisin shuffle -pelin toimimaan kunnolla?
Minulla tulee nimittäin tällainen teksti:
"Warning: fread(): Length parameter must be greater than 0. in /mbnet/m/mansku91/salahakemisto/shuffle/shuffle.php on line 38".

Voitte katsoa sitä sivua ---> http://koti.mbnet.fi/mansku91/salahakemisto/shuffle/shuffle.php?nayta=voitto

Laittamani koodi on tällainen:

<?php
session_start();
$conf['sdir'] = "start/"; // Taustakuva tänne
$conf['udir'] = "use/"; // Tänne tulee kaikki resurssitiedostot
$conf['jarjestys'] = "use/jarjestys.txt"; // Järjestys sullotaan tänne
$conf['ennatys'] = "use/ennatys.txt"; // Ennätykset tänne

$blokki['width'] = 100;
$blokki['height'] = 100;

$sdir_sis = glob($conf['sdir'].'*.jpg');
$spic = $sdir_sis[0];

$buffer = "";
$error = false;

function randomname() {
    return md5(microtime().str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ1234567890abcdefghijklmnopqrstuvwxyzåäö'));
}
function kirjoita($s,$file) {
    $s = implode("\n",$s);
    $kahva = fopen($file,'w'); // Tiedoston avaus kirjoitusmoodiin & tyhjennys
    flock($kahva,LOCK_EX); // EXCLUSIVE-lukko. (Yksinoikeus)
    fwrite($kahva,$s); // Kirjoitetaan
    flock($kahva,LOCK_UN); // Poistetaan luko
    fclose($kahva); // Suljetaan tiedosto
}
function tyhjenna_ennatys($ents) {
    $kahva = fopen($ents,'w');
    flock($kahva,LOCK_EX);
    ftruncate($kahva,0);
    flock($kahva,LOCK_UN);
    fclose($kahva);
}
function lue($file) {
    $kahva = fopen($file,'r');
    flock($kahva,LOCK_SH);
    $raakadata = fread($kahva,filesize($file));
    flock($kahva,LOCK_UN);
    fclose($kahva);
    $raakadata = explode("\n",$raakadata);
    return $raakadata;
}
function etsi_mahd_siirrot() {
    $mahdsiirrot = array();
    $vasenreuna = floor($_SESSION['tyhjaruutu']/$_SESSION['sarakkeita'])*$_SESSION['sarakkeita'];
    $oikeareuna = floor($_SESSION['tyhjaruutu']/$_SESSION['sarakkeita'])*$_SESSION['sarakkeita']+$_SESSION['sarakkeita']-1;

    if($_SESSION['tyhjaruutu']-1 >= 0  && $_SESSION['tyhjaruutu'] != $vasenreuna)
        $mahdsiirrot[] = ($_SESSION['tyhjaruutu']-1);
    if($_SESSION['tyhjaruutu']+1 < $_SESSION['riveja']*$_SESSION['sarakkeita'] && $_SESSION['tyhjaruutu'] != $oikeareuna)
        $mahdsiirrot[] = ($_SESSION['tyhjaruutu']+1);
    if($_SESSION['tyhjaruutu']-$_SESSION['sarakkeita'] >= 0)
        $mahdsiirrot[] = ($_SESSION['tyhjaruutu']-$_SESSION['sarakkeita']);
    if($_SESSION['tyhjaruutu']+$_SESSION['sarakkeita'] < $_SESSION['sarakkeita']*$_SESSION['riveja'])
        $mahdsiirrot[] = ($_SESSION['tyhjaruutu']+$_SESSION['sarakkeita']);
    return $mahdsiirrot;
}

// Tässä toiminteet, joita voidaan suorittaa...
if(!empty($_GET['uusipeli']) && isset($_GET['uusipeli'])) {
    session_destroy(); // Poistetaan session tiedot
    header('Location: '.$_SERVER['PHP_SELF']);
}
elseif(!empty($_POST['nimimerkki']) && strlen($_POST['nimimerkki']) > 0 && $_SESSION['voitto'] == true) {
    $topdata = lue($conf['ennatys']);    // Luetaan ensin top10-tiedosto
    $kahva = fopen($conf['ennatys'],'w'); // Avataan, lukitetaan & tyhjennetään kirjoitusta varten.
    flock($kahva,LOCK_EX);

    // Poistetaan nimimerkistä html yms.
    $pelaaja = stripslashes(htmlspecialchars(str_replace(array("\n","\r","\t","|"),'',$_POST['nimimerkki'])));
    $raakalista = array();
    $filuun = array();
    $paikkaloydetty = false;

    // Sullotaan top-lista oikeassa järjestyksessä arrayyn
    foreach($topdata as $rivi) {
        $pilkottu = explode("|",$rivi);
        if(intval($pilkottu[0]) > $_SESSION['siirtoja'] && !$paikkaloydetty) {
            $raakalista[] = array($_SESSION['siirtoja'],$pelaaja);
            $paikkaloydetty = true;
        }
        $raakalista[] = $pilkottu;
    }

    // Pistetään array tekstikasaksi, erotellaan sarakkeet. Kirjoitetaan vain 10 ensimmäistä tulosta.
    for($i=0;$i<10;$i++) {
        if(isset($raakalista[$i])) {
            $filuun[] = implode("|",$raakalista[$i]);
        }
    }
    // Kirjoitetaan array tiedostoon
    $filuun = implode("\n",$filuun);
    fwrite($kahva,$filuun);

    flock($kahva,LOCK_UN);
    fclose($kahva);

    session_destroy(); // Tuhotaan session tiedot, nollataan peli

    header('Location: '.$_SERVER['PHP_SELF'].'?nayta=Top10'); // Refresh, jotta selain ei valita... Jos selain ei tue headeria, mennään kuitenkin etiäpäim.
}

if(!empty($spic)) {    // Jos skriptalle annetaan uusi kuva taustaksi, luodaan pikkukuvat uudestaan
    $ainfo = getimagesize($spic);
    $sarakkeet = floor($ainfo[0]/$blokki['width']);    // Montako saraketta luodaan
    $rivit = floor($ainfo[1]/$blokki['height']); // Montako riviä luodaan

    if($ainfo['mime'] == 'image/jpeg') { // Varmistetaan, että kuva on varmasti Jpeg
        foreach(glob($conf['udir']."*.jpg") as $poista)    // Poistetaan vanhat tiedostot alta turhaa tilaa viemästä
            unlink($poista);

        $akuva = imagecreatefromjpeg($spic);

        $jarjestys = array();

        $uusinimi = 'valkoinen.jpg';
        $uusi = imagecreate($blokki['width'],$blokki['height']); // Luodaan uusi kuvapohja
        $white = imagecolorallocate($uusi, 255, 255, 255); // Taustaväriksi valkoinen
        imagejpeg($uusi,$conf['udir'].$uusinimi,100); // tallennetaan valkoinen kuva nimellä valkoinen.jpg
        imagedestroy($uusi); // Tuhotaan muistista
        $jarjestys[] = '0|'.$uusinimi; // Laitetaan

        for($a=0; $a < $rivit; $a++) {
            for($b=0; $b < $sarakkeet; $b++) {
                if($a==0 && $b==0) continue;
                $uusinimi = randomname().'.jpg';
                $uusi = imagecreatetruecolor($blokki['width'],$blokki['height']);

                // Kopioidaan oikean kokoinen pala alkuperäisestä kuvasta, ja tallennetaan se satunnaisella nimellä hakemistoon talteen
                imagecopy($uusi, $akuva, 0, 0, intval($b*$blokki['width']), intval($a*$blokki['height']), $blokki['width'], $blokki['height']);
                imagejpeg($uusi,$conf['udir'].$uusinimi,100);
                imagedestroy($uusi);
                $jarjestys[] = $a.'|'.$uusinimi;
            }
        }
        imagejpeg($akuva,$conf['udir'].'alkup.jpg',100); // Tallennetaan alkuperäinen kuva parhaalla laadulla uuteen paikkaan
        imagedestroy($akuva); // Tuhotaan kuva muistia varaamasta
        kirjoita($jarjestys,$conf['jarjestys']); // Kirjoitetaan kuvien oikea järjestys tiedostoon
        tyhjenna_ennatys($conf['ennatys']);
        unlink($spic) or $error = 'POISTA KUVATIEDOSTO KANSIOSTA START! MUUTEN PELI STRESSAA PALVELINTA JOKA LATAUSKERRALLA TEKEMÄLLÄ PIKKUKUVAT UUDELLEEN!!!';
    } else {
        die('Taustakuva ei ole JPEG.');
    }
}

switch($_GET['nayta']) {
    case 'Top10':
        $buffer .= '
        <form method="get" action="'.$_SERVER['PHP_SELF'].'">
        <input type="submit" value="Takaisin peliin" name="nayta" />
        </form>
        <table cellspacing="4" cellpadding="1" class="toptable">
            <tr>
                <td align="left"> Pelaaja </td><td align="right"> Siirtoja </td>
            </tr>';

        // Tarkistetaan pääsikö pelaaja toplistaan
        $toplista = lue($conf['ennatys']);
        foreach($toplista as $pelaaja) {
            $buffer .= "
            <tr>";

            $pelaaja = explode("|",rtrim($pelaaja));
            $buffer .= '
                <td align="left">'.$pelaaja[1].'</td><td align="right">'.$pelaaja[0].'</td>';

            $buffer .= "
            </tr>";
        }

        $buffer .= '
        </table>';
    break;
    case 'voitto';
        if($_SESSION['voitto'] == true) {
            $buffer .= '<h2> Onneksi Olkoon! </h2>
            <p>Ratkaisit pelin '.$_SESSION['siirtoja'].' siirrolla';

            // Tarkistetaan pääsikö pelaaja top10-listaan
            $topkymppiin = false;
            $topdata = lue($conf['ennatys']);
            if(count($topdata) == 10) {
                foreach($topdata as $rivi) {
                    $rivi = explode("|",$rivi);
                    if($rivi[0] > $_SESSION['siirtoja']) {
                        $topkymppiin = true;
                        break;
                    }
                }
            } else {
                $topkymppiin = true;
            }

            if($topkymppiin) {
                $buffer .= ' ja pääsit top-10 listaan.</p>
                <p> Kirjoita alle nimesi ja paina Lisää-nappia.
                <form action="'.$_SERVER['PHP_SELF'].'?nayta=Top10" method="post">
                    <input type="text" name="nimimerkki" size="30" maxlength="30" />
                    <input type="submit" value="Lisää" />
                </form>
                ';
            } else {
                $buffer .= ' mutta et kuitenkaan päässyt top-10 listaan.</p>
                <p> Jatka top-10-listaan painamalla nappia.
                <form action="'.$_SERVER['PHP_SELF'].'" method="get">
                    <input type="submit" value="Top10" name="nayta" />
                </form>
                ';
                session_destroy(); // Koska sessiotietoja ei tarvita enää top10-listaan lisäämisessä, poistetaan ne. Peli nollaantuu.
            }
            $buffer .= '</p>
            ';
        }
        else {
            $buffer .= 'Jahas, sitä yritetään uunottaa??';
        }
    break;
    default:
        // Nyt päästään itse peliosioon. Ensin luodaan sessiomuuttujaan "kuva" pelialueesta, jos sitä ei ole

        if(!isset($_SESSION['alue'])) {
            $jarjestys = lue($conf['jarjestys']); // Luetaan järjestystiedosto
            $rivimaara = count($jarjestys);
            $rivi = explode('|',$jarjestys[$rivimaara-1]);

            $_SESSION['riveja'] = $rivi[0]+1;
            $_SESSION['sarakkeita'] = $rivimaara / ($_SESSION['riveja']);
            $_SESSION['ruutuja'] = $_SESSION['riveja']*$_SESSION['sarakkeita'];
            $_SESSION['siirtoja'] = 0; // Tänne tallennetaan siitojen määrä vahdollista top-10 varten
            $_SESSION['voitto'] = false; // Tällä tarkistetaan, että pelaaja on oikeasti voittanut...
            $_SESSION['alue'] = array(); // Tähän taulukkoon sotkettu pelialue
            $_SESSION['jarjestys'] = array(); // Tähän taulukkoon oikea järjestys
            $_SESSION['tyhjaruutu'] = 0;

            // Puhdistetaan törky pois, pistetään kamaa taulukkoihin
            for($i=0; $i<count($jarjestys); $i++) {
                $rivi = explode('|',rtrim($jarjestys[$i]));
                $_SESSION['jarjestys'][] = $rivi[1];
                $_SESSION['alue'][] = $rivi[1];
            }

            // Järjestellään palaset sekalaiseen järjestykseen
            for($i=0;$i<($_SESSION['ruutuja']*2);$i++) {
                $vaihtoehdot = array_flip(etsi_mahd_siirrot());
                unset($vaihtoehdot[$edellinen]); // Poistetaan edellisen siirron lähtöruutu, ettei jäädä kieppumaan...
                $edellinen = $_SESSION['tyhjaruutu']; // Määritetään $edellinen uudestaan
                $siirrakohtaan = array_rand($vaihtoehdot); // Valitaan satunnaunen siirto
                $temp = $_SESSION['alue'][$siirrakohtaan];
                $_SESSION['alue'][$siirrakohtaan] = 'valkoinen.jpg'; // Siirretään valkoista blokkia
                $_SESSION['alue'][$_SESSION['tyhjaruutu']] = $temp; // Siirretään klikattua blokkia
                $_SESSION['tyhjaruutu'] = $siirrakohtaan; // Muutetaan valkoisen blokin senhetkinen paikkatieto
            }

            header('Location: '.$_SERVER['PHP_SELF']); // Päivitetään sivu, ettei selaimet valita ...
        }

        // Etsitään kaikki mahdolliset siirrot
        $mahdsiirrot = etsi_mahd_siirrot($_SESSION['tyhjaruutu']);

        // Mikäli palasta halutaan siirtää, tarkistetaan että siirto on mahdollinen ja suoritetaan se
        if(isset($_GET['siirra']) && intval($_GET['siirra']) < $_SESSION['riveja']*$_SESSION['sarakkeita'] && intval($_GET['siirra']) >= 0) {
            if(!in_array(intval($_GET['siirra']),$mahdsiirrot)) {
                $error = "Et voi liikuttaa tähän ruutuun";
            } else {
                $siirrakohtaan = intval($_GET['siirra']);
                $temp = $_SESSION['alue'][$siirrakohtaan];
                $_SESSION['alue'][$siirrakohtaan] = 'valkoinen.jpg'; // Siirretään valkoista blokkia
                $_SESSION['alue'][$_SESSION['tyhjaruutu']] = $temp; // Siirretään klikattua blokkia
                $_SESSION['siirtoja']++; // Lisätään yksi siirto siirtoklopaaliin
                $_SESSION['tyhjaruutu'] = $siirrakohtaan; // Muutetaan valkoisen blokin senhetkinen paikkatieto
                header('Location: '.$_SERVER['PHP_SELF']); // Refresh
            }
        }

        // Tarkistetaan onko kuvio valmis
        $tarkistusarvot = array();
        for($x=0; $x<count($_SESSION['alue']); $x++) {
            if($_SESSION['alue'][$x] == $_SESSION['jarjestys'][$x]) $tarkistusarvot[] = true;
            else $tarkistusarvot[] = false;
        }
        // Jos pelialue ja alkup. alue täsmäävät, voitto...
        if(!in_array(false,$tarkistusarvot)) {
            $_SESSION['voitto'] = true;
            $error = "Voitit!!! <br /> <a href=\"".$_SERVER['PHP_SELF']."?nayta=voitto\">Eteenpäin</a>";
            header("Location: ".$_SERVER['PHP_SELF']."?nayta=voitto");
        }

        $buffer .= '
        <form method="get" action="'.$_SERVER['PHP_SELF'].'">
            <input type="submit" value="Uusi peli!" name="uusipeli" />
            <input type="submit" value="Top10" name="nayta" />
        </form>

        <p> Valkoinen ruutu kuuluu aina vasempaan yläreunaan. </p>

        <table cellspacing="10" cellpadding="0">
            <tr>
                <td>
        ';

        $i=0;
        for($a=0; $a < $_SESSION['riveja']; $a++) { // Luodaan rivit
            for($b=0; $b < $_SESSION['sarakkeita']; $b++) { // Luodaan sarakkeet
                $fkuva = $conf['udir'].$_SESSION['alue'][$i];

                // Mikäli ruutuun voi siirtää, luodaan linkki kuvan ympärille
                if(in_array($i,$mahdsiirrot)) $buffer .= '<a href="'.$_SERVER['PHP_SELF'].'?siirra='.$i.'">';
                $buffer .= '<img src="'.$fkuva.'" class="img" alt="palanen" width="'.$blokki['25'].'" height="'.$blokki['25'].'" />';
                if(in_array($i,$mahdsiirrot)) $buffer .= '</a>';
                $buffer .= "\n";
                $i++;
            }
            $buffer .= "<br />\n";
        }
        $buffer .= '
                </td>
                <td>
                    <img src="'.$conf['udir'].'alkup.jpg" alt="Alkup. kuvio">
                </td>
            </tr>
        </table>
        <p>Siirtoja: '.$_SESSION['siirtoja'].'</p>

        </body>
        </html>';
    break;
}
print '<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi" lang="fi">
<head>
    <title>Shuffle v1.0 by Turatzuro</title>
    <style type="text/css">
    .toptable {
        border: 1px solid black;
    }
    a:hover {
        background-color: white;
        -moz-opacity: 0.3;
        opacity: 0.3;
    }
    .img {
        padding-right: 1px;
        border: 0px;
        margin-bottom: 0px;
        padding-bottom: 0px;
    }
</style>
</head>
<body>
';
print $buffer;
if($error !== false) print '<p style="color:red; font-weight: bold;">'.$error.'</p>'."\n"; // Mikäli virhe, tulostetaan
print '
</body>
</html>';
?>

Mikä tässä on mennyt väärin? Voitteko auttaa korjaamaan?

Antti Laaksonen [13.05.2006 14:06:29]

#

Suomennettuna ilmoitus on:
"Varoitus: fread(): Parametrin 'length' arvon täytyy olla suurempi kuin 0. - -"

Moinen viittaa siihen, että tiedosto on olemassa, mutta siinä ei ole yhtään tekstiä.

Jos peli toimii muuten oikein, varoituksen saa pois esim. kirjoittamalla funktion eteen merkin @.

Metabolix [13.05.2006 14:25:57]

#

Lukufunktioon (siis siihen omaasi, johon tuokin rivi kuuluu) kannattaisi laittaa tarkistus siitä, onko tiedosto olemassa, ja jos sen koko on nolla, sitä ei tietenkään kannata lukea. Eli tällainen funktion alkuun:

/* Jos ei ole olemassa tai koko on nolla */
if (!file_exists($file) || (filesize($file) == 0)) {
  /* Palautetaan tyhjä teksti */
  return '';
}
/* Muuten funktio jatkuu ja tiedosto luetaan */

Tietenkin PHP-tapaisempaa olisi palauttaa ensimmäisen ehdon tapauksessa false.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta