Olen tekemässä PHP:llä 100x100 kokoista ristinollapeliä. Miten ristinollaan voitontarkistus kannattaisi toteuttaa?
Kannattaako tehdä taulukko $siirrot[x][y] johon merkitsen molempien pelaajien siirrot pelilaudalla vai miten? Tein jonkinlaisen koodinpätkän joka osaa tarkistaa 5 peräkkäin olevaa merkkiä, mutta oma toteutus oli erittäin huono. Pientä vinkkiä haluaisin hyvään toteutukseen :)
Tee siitä oma luokka, jokaisen siirron jälkeen kutsut vaikka tarkastaVoitto(); metodia joka voisi vaikka lähteä jokaisesta "siirrosta" kaikkiin suuntiin ja tarkastaa että onko niitä vaadittu määrä peräkkäin. Toki tuon tarkistuksenkin voi ja varmaankin kannattaakin jakaa vielä eri metodeihin.
Tuon pelialueen voit tosiaan säilöä vaikka taulukkoon, $siirrot[n] = array(x, y)... Tosin ehkä siihen kannattaisi säilöä myös aktori, eli vaikka $siirrot[n] = array(x, y, pelaaja).. Toki siirrosta voisi myös tehdä oman luokan, jolloin ne olisivat helpommin laajennettavissa ja ylläpidettävissä.
Näin itse ehkä lähtisin tuota viemään eteenpäin.
Mureakuhassa oli sama kysymys huhtikuussa. Kopioin vastaukseni sieltä:
Järkevin tapa lienee se, että aina kun ruudukkoon lisätään merkki, tarkistetaan synnyttikö kyseinen merkki valmiin suoran. Eli edetään vastakkaisiin (mm. ylös-alas) suuntiin etsien riittävää määrää peräkkäisiä samoja merkkejä.
Koko ruudukon tutkiminen on tarpeellista vain silloin, kun saadaan tutkittavaksi keskeneräinen pelitilanne ilman tietoa viimeisimmästä siirrosta.
Mennään abstraktiotasolla jo aika pitkälle, jos jokaiselle siirrolle tehdään oma luokka. Pelialueen voi laittaa kaksiulotteiseen taulukkoon, kuten kysyjä ehdottikin, arvoina ykköstä ja nollaa merkkeinä pelaajien 1 ja 2 siirroille.
Ps. Väärä alue?
tsuriga kirjoitti:
Pelialueen voi laittaa kaksiulotteiseen taulukkoon, kuten kysyjä ehdottikin, arvoina ykköstä ja nollaa merkkeinä pelaajien 1 ja 2 siirroille.
Itse pitäisin loogisena käyttää 0:aa tyhjille ruuduille ja sitten 1:stä ylöspäin pelaajien merkeille. Mutta toki pelaajille voi laittaa ehdottamasi 0 ja 1 ja sitten tyhjät vaikka 7:na jos haluaa. Nämähän on jossain määrin makuasioita.
tsuriga kirjoitti:
Ps. Väärä alue?
Mikäs olisi oikea alue PHP-aiheisille kysymyksille?
Yksi tapa on tehdä erillinen funktio, joka saa syötteenä pelaajan id:n ja ruudun, johon pelaaja klikkasi. Funktio käy siirretystä ruudusta jokaiseen kahdeksaan suuntaan korkeintaan 5 ruutua läpi. Palautteena tulee joko true / false riippuen miten kävi.
Pelaajalla 1 voisi olla -1 ja pelaajalla 2 1 arvona. Tyhjä ruutu voisi olla 0. Tällöin viiden suora pelaajalle 1 olisi -5 ja pelaajalle 2 +5. Pelialueeksi kaksiulotteinen taulu ei ole suinkaan tarpeellista, vaan yksiulotteiselle pärjää jo aika hyvin.
<?php /* Siirtotaulu (kieltämättä huono nimi) */ $suunnat = array(); $suunnat[] = 1; /* vasemmalle */ $suunnat[] = $leveys + 1; /* Alaviistoon vasemmalle */ $suunnat[] = $leveys; /* Alas */ $suunnat[] = $leveys - 1; /* Alaviistoon oikealle */ $suunnat[] = -1; /* Oikealle */ $suunnat[] = -$leveys - 1; /* Yläviistoon oikealle */ $suunnat[] = -$leveys; /* Ylös */ $suunnat[] = -$leveys + 1; /* Yläviistoon vasemmalle */; /* Käydään läpi kaikki suunnat */ function tarkista($ruutu, $pelaaja){ for($a = ; $a < 8; $a++){ /* Käydään läpi yksi suora */ for($b = 0; $b < 5; $b++){ $indeksi = $ruutu + $b + $suunnat[$a]; /** * Pitäisi varmistaa ettei mene rajoista yli! * Onko helppoa tapaa tähän? */ $summa += $peliAlue[$indeksi]; } if($summa == 5 || $summa == -5){ return true; } $summa = 0; } return false; } ?>
Grez kirjoitti:
tsuriga kirjoitti:
Ps. Väärä alue?
Mikäs olisi oikea alue PHP-aiheisille kysymyksille?
Oisko muut kielet? Ei tästä käy mistään ilmi, että tämä nettisivuihin liittyis.
Tässä on hahmotelma koodista, jolla voi tarkistaa pelaajan merkinnän jälkeen, tuottiko merkintä voittosuoran. Funktiolle voitto annetaan parametriksi, mihin ruudukon kohtaan pelaaja laittoi merkin.
<?php // kuinka monta merkkiä tietyllä suoralla on? function maara($x, $y, $xs, $ys) { global $t; // $t[$x][$y] on merkki kohdassa ($x, $y) $ux = $x; $uy = $y; while ($t[$ux][$uy] == $t[$x][$y]) { $maara++; $ux += $xs; $uy += $ys; } return $maara; } // tuottiko merkintä kohtaan ($x, $y) voittosuoran? function voitto($x, $y) { // vaakasuunnan tarkistus if (maara($x, $y, 1, 0) + maara($x, $y, -1, 0) - 1 >= 5) return true; // pystysuunnan tarkistus if (maara($x, $y, 0, 1) + maara($x, $y, 0, -1) - 1 >= 5) return true; // 1. vinosuunnan tarkistus if (maara($x, $y, 1, 1) + maara($x, $y, -1, -1) - 1 >= 5) return true; // 2. vinosuunnan tarkistus if (maara($x, $y, 1, -1) + maara($x, $y, -1, 1) - 1 >= 5) return true; // ei voittoa return false; } ?>
Muoks. Muutin vähän koodin rakennetta.
tsuriga kirjoitti:
Grez kirjoitti:
tsuriga kirjoitti:
Ps. Väärä alue?
Mikäs olisi oikea alue PHP-aiheisille kysymyksille?
Oisko muut kielet? Ei tästä käy mistään ilmi, että tämä nettisivuihin liittyis.
Nettisivuille teen tätä juuri. Kiitos jo tulleista vastauksista, yritän kasata omaa toteutusta niin että ohjelma tarkistaa aina vain uusimman siirron.
tsuriga kirjoitti:
Ei tästä käy mistään ilmi, että tämä nettisivuihin liittyis.
Toisaalta mistään ei käynyt myöskään ilmi että liittyisi nimenomaan johonkin muuhun. Kyllä PHP:n käytöstä voi aika pitkälti olettaa, että kyseessä on weppisovellus, vaikka sillä periatteessa pystyy tekemään muutakin.
tsuriga kirjoitti:
Mennään abstraktiotasolla jo aika pitkälle, jos jokaiselle siirrolle tehdään oma luokka.
<pilknus>
Tarkoitat varmaan että jokaiselle siirrolle oma olio :)
</pilknus>
Oma ehdotukseni oli tosiaan kyllä ehkä vähän överi, nyt kun luen kysymyksen uusiksi. Kerta jotain toteutusta on jo tehty (ja nähtävästi ilman oliopohjaista suunnittelua/toteutusta) niin eipä siihen ihan olioiden ilosta kannata siirtyä.
Grez kirjoitti:
tsuriga kirjoitti:
Ei tästä käy mistään ilmi, että tämä nettisivuihin liittyis.
Toisaalta mistään ei käynyt myöskään ilmi että liittyisi nimenomaan johonkin muuhun.
Eikö se nyt jo määritelmän pohjalta liity johonkin muuhun jos ei liity asiaan X?
JTS kirjoitti:
Tarkoitat varmaan että jokaiselle siirrolle oma olio :)
Kyllä, aivan, hyvä korjaus :).
Aihe on jo aika vanha, joten et voi enää vastata siihen.