Forum » Programiranje » [PHP/JavaScript] tic tac toe
[PHP/JavaScript] tic tac toe
šrawfncigr ::
Pozdravljeni!
Lotil sem se delati tic tac toe (križci-krožci), najprej sem enostavno v javascript naredil scripto ki ti zaznava kdo je na potezi ter če je igra že končana kjer lahko igrata dva igralca na istem računalniku. Zdaj sem pa dobil željo da bi izdelal še igranje prek spleta znam nekaj php-ja ter javascript, nevem pa kako bi naredil da bi prepoznalo kdo je na potezi in katero polje je nasportinik kliknil.
Prosim če mi lahko pomogate oz. razložite na kakšen način naj se lotim problema.
Lep pozdrav!
Lotil sem se delati tic tac toe (križci-krožci), najprej sem enostavno v javascript naredil scripto ki ti zaznava kdo je na potezi ter če je igra že končana kjer lahko igrata dva igralca na istem računalniku. Zdaj sem pa dobil željo da bi izdelal še igranje prek spleta znam nekaj php-ja ter javascript, nevem pa kako bi naredil da bi prepoznalo kdo je na potezi in katero polje je nasportinik kliknil.
Prosim če mi lahko pomogate oz. razložite na kakšen način naj se lotim problema.
Lep pozdrav!
t3hn0 ::
PHP niti ne boš potreboval, razen če bi rad beležil kakšne rezultate.
Vse rešiš z JS, najbolše z jQuery.
V vizualnem delu si sestavi tabelo (al bo tabela, al bodo div-i,...) v katere vstavis prazne slike z nekim classom in idjem.
V JS lahko enostavno reces
$(".nekClass").click(function() {
var kliknjenId = $(this).attr('id');
});
in tako dobis id polja za nadaljne operacije, ki bi šle tako nekako:
- veljavna poteza - da/ne
- menjaj slikco z 0 ali X
- zmaga - da/ne
- menjaj igralca
...čakaj na nov klik
Vse rešiš z JS, najbolše z jQuery.
V vizualnem delu si sestavi tabelo (al bo tabela, al bodo div-i,...) v katere vstavis prazne slike z nekim classom in idjem.
V JS lahko enostavno reces
$(".nekClass").click(function() {
var kliknjenId = $(this).attr('id');
});
in tako dobis id polja za nadaljne operacije, ki bi šle tako nekako:
- veljavna poteza - da/ne
- menjaj slikco z 0 ali X
- zmaga - da/ne
- menjaj igralca
...čakaj na nov klik
^.^
šrawfncigr ::
Hmm, vrjetno smo se narobe razumeli.
Jaz imam že vse narejeno v javascript manka mi samo igranje dveh igralcev po spletu katerega nevem kako bi se lotil :s
Vseeno hvala za trud.
Jaz imam že vse narejeno v javascript manka mi samo igranje dveh igralcev po spletu katerega nevem kako bi se lotil :s
Vseeno hvala za trud.
vorantz ::
sej piše po spletu se pravi na različnih računalnikih
recimo z ajaxom bi lahko vmes javljal strežniku trenutno stanje, da si zapomni
recimo z ajaxom bi lahko vmes javljal strežniku trenutno stanje, da si zapomni
šrawfncigr ::
Se res ne da rešiti drugače kakor z AJAX-om? Namreč se trenutno res nimam volje učiti :s
technolog ::
šrawfncigr je izjavil:
Se res ne da rešiti drugače kakor z AJAX-om? Namreč se trenutno res nimam volje učiti :s
To je več ali manj enina pametna opcija. Poleg seveda COMET-a, long pollinga in ostalih hackov.
Izjemoma lahko narediš tako, da stran vsako sekundo refresha, vendar bo zoprno.
Zgodovina sprememb…
- spremenil: technolog ()
Arto ::
šrawfncigr je izjavil:
Se res ne da rešiti drugače kakor z AJAX-om? Namreč se trenutno res nimam volje učiti :s
Sej AJAX ni težak, se nimaš prav dosti za doučit, če že znaš php in javascript. Najbolje da si pogledaš tole: http://www.w3schools.com/ajax/ajax_exam...
EDIT: V bistvu je precej lažje, če vse skupaj delaš z JQuery.
Zgodovina sprememb…
- spremenil: Arto ()
šrawfncigr ::
Dobro bom uporabil pač ajax, malo sem si ogledoval vodiče pa recimo da nekaj vem na približno . Zanima pa me na kakšen način bi poslal informacjo o kliknjenemu polju in kam jo bi shranilo.
Hvala za vso pomoč.
Hvala za vso pomoč.
Spura ::
Vsako polje ima onclick event z requestom kjer je kliknjeno polje parameter v URL.
Ce bos hotel da se pokaze ko drugi igralec klikne, bos rabil AJAX pushback, COMET al kakorkoli temu ze hoces rect.
Ce bos hotel da se pokaze ko drugi igralec klikne, bos rabil AJAX pushback, COMET al kakorkoli temu ze hoces rect.
technolog ::
Ne ga matrat s pull metodami. :)
Enostavno naj ima navaden polling. Sepravi OP, na vsake tri sekunde pošlji AJAX request na server v stilu:
"Je kaka nova poteza?"
in potem server odgovori recimo:
je. Na polju 2,1.
Enostavno naj ima navaden polling. Sepravi OP, na vsake tri sekunde pošlji AJAX request na server v stilu:
"Je kaka nova poteza?"
in potem server odgovori recimo:
je. Na polju 2,1.
technolog ::
Ja, torej, ti rabiš na strežniku en programček, ki bo imel shranjeno pozicijo igre (torej vse poteze do sedaj).
Ko narediš potezo, se temu strežniku pošlje katero polje si kliknil. Strežnik preveri, če je polje še prosto ali če je konec igre in sporoči odgovor. Seveda si shrani novo stanje.
Seveda to ni dovolj. Rabiš še eno stvar - nek ponavljajoč cikel, ki vsake tri sekunde preveri, če je slučajno nasprotnik odigral kako novo potezo in ti jo sporoči.
Sem ti rekel, da ne bo tole tako trivialno. Programček na strežniku lahko napišeš v poljubnem jeziku, recimo PHP, C++, Python, Ruby. Lahko pa izbereš kar node.js, ker javascript že znaš.
Ko narediš potezo, se temu strežniku pošlje katero polje si kliknil. Strežnik preveri, če je polje še prosto ali če je konec igre in sporoči odgovor. Seveda si shrani novo stanje.
Seveda to ni dovolj. Rabiš še eno stvar - nek ponavljajoč cikel, ki vsake tri sekunde preveri, če je slučajno nasprotnik odigral kako novo potezo in ti jo sporoči.
Sem ti rekel, da ne bo tole tako trivialno. Programček na strežniku lahko napišeš v poljubnem jeziku, recimo PHP, C++, Python, Ruby. Lahko pa izbereš kar node.js, ker javascript že znaš.
šrawfncigr ::
Obistvu programček ki ti zazna potezo preveri če je veljavna itd. že imam le malo preurediti jo moram. Zanima kam bi shranjevalo poteze običajno polje array() katerega po koncu igre izbriše? Ter kaj bi se zgodilo če bi prišla tretja oseba na stran na kateri že igrata dva igralca?
Za lažjo predstavo:
HTML:
javascrip:
Za lažjo predstavo:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>križci-krožci</title> <link rel="stylesheet" type="text/css" href="css.css" /> <script language="javascript" src="igra.js"></script> </head> <body> <div class="glavni" align="center"> <input type="button" id="0.0" value="" class="tipke" onclick="klik(this);zmaga();"/> <input type="button" id="0.1" value="" class="tipke" onclick="klik(this);zmaga();"/> <input type="button" id="0.2" value="" class="tipke" onclick="klik(this);zmaga();"/> <BR> <input type="button" id="1.0" value="" class="tipke" onclick="klik(this);zmaga();"/> <input type="button" id="1.1" value="" class="tipke" onclick="klik(this);zmaga();"/> <input type="button" id="1.2" value="" class="tipke" onclick="klik(this);zmaga();"/> <BR> <input type="button" id="2.0" value="" class="tipke" onclick="klik(this);zmaga();"/> <input type="button" id="2.1" value="" class="tipke" onclick="klik(this);zmaga();"/> <input type="button" id="2.2" value="" class="tipke" onclick="klik(this);zmaga();"/> <BR> <input type="button" id="začni" value="začni znova" onclick="začni()"/> <P ID="status">Na vrsti je: X</P> </div> </body> </html>
javascrip:
var x = true; var konec = 1; var poteze = 0; function klik(square) { var status = document.getElementById('status'); var value = square.value; if (konec == 1){ if(value != 'X' && value != 'O') { if(x) { poteze++; square.value = 'X'; x = false; status.innerHTML = 'Na vrsti je: O'; } else { poteze++; square.value = 'O'; x = true; status.innerHTML = 'Na vrsti je: X'; } } else alert('Pritisnil si Ĺže polno polje.'); } else{ alert('Igra je konÄana.') } } function zaÄni() { var status = document.getElementById('status'); x = true; poteze = 0; konec = 1; status.innerHTML = 'Na vrsti je: X'; for(var a = 0; a < 3; a++) { for(var b = 0; b < 3; b++) { document.getElementById(a + '.' + b).value = ' '; } } } function zmaga() { var status = document.getElementById('status'); var val0; var val1; var val2; for(var b = 0; b < 3; b++) { val0 = document.getElementById('0.'+b).value; val1 = document.getElementById('1.'+b).value; val2 = document.getElementById('2.'+b).value; if(val0 == 'X' && val1 == 'X' && val2 == 'X') { status.innerHTML = "X je zmagal!"; konec = 0; return true; } else if(val0 == 'O' && val1 == 'O' && val2 == 'O') { status.innerHTML = "O je zmagal!"; konec = 0; return true; } } for(var a = 0; a < 3; a++) { val0 = document.getElementById(a + '.0').value; val1 = document.getElementById(a + '.1').value; val2 = document.getElementById(a + '.2').value; if(val0 == 'X' && val1 == 'X' && val2 == 'X') { status.innerHTML = "X je zmagal!"; konec = 0; return true; } else if(val0 == 'O' && val1 == 'O' && val2 == 'O') { status.innerHTML = "O je zmagal!"; konec = 0; return true; } } val0 = document.getElementById('0.0').value; val1 = document.getElementById('1.1').value; val2 = document.getElementById('2.2').value; if(val0 == 'X' && val1 == 'X' && val2 == 'X') { status.innerHTML = "X je zmagal!"; konec = 0; return true; } else if(val0 == 'O' && val1 == 'O' && val2 == 'O') { status.innerHTML = "O je zmagal!"; konec = 0; return true; } val0 = document.getElementById('2.0').value; val1 = document.getElementById('1.1').value; val2 = document.getElementById('0.2').value; if(val0 == 'X' && val1 == 'X' && val2 == 'X') { status.innerHTML = "X je zmagal!"; konec = 0; return true; } else if(val0 == 'O' && val1 == 'O' && val2 == 'O') { status.innerHTML = "O je zmagal!"; konec = 0; return true; } if(poteze == 9) { status.innerHTML = "Ni zmagovalca!"; konec = 0; } }
technolog ::
To moreš prevert vse na serverju. preverjanje lokalno ni dovolj.
Glede več igralcev se stvar še bolj zakomplicira... Moraš naredit nek lobby, če hočeš, da bo vse propper.
V praksi pa gre, da ko klikneš nova igra ti da nek game ID, ki ga potem preko gtalka sporočiš soigralcu. On ga vpiše in igra med vama se vzpostavi.
Ravno v tem je problem, ker boš moral skoraj vso kodo prepisat na server. Predlagam ti, da s tako igro prek interneta še kako leto počakaš, ali pa se jo lotiš spisat v C++ in narediš pravi server / client, se pravi p2p, brez vmesnega strežnika.
Glede več igralcev se stvar še bolj zakomplicira... Moraš naredit nek lobby, če hočeš, da bo vse propper.
V praksi pa gre, da ko klikneš nova igra ti da nek game ID, ki ga potem preko gtalka sporočiš soigralcu. On ga vpiše in igra med vama se vzpostavi.
Ravno v tem je problem, ker boš moral skoraj vso kodo prepisat na server. Predlagam ti, da s tako igro prek interneta še kako leto počakaš, ali pa se jo lotiš spisat v C++ in narediš pravi server / client, se pravi p2p, brez vmesnega strežnika.
Zgodovina sprememb…
- spremenil: technolog ()
illion ::
prvo si morš zamislt celotno logiko, pol boš komot sprogramiral. Problem php-ja je drugače v tem, da se zažene za vsak request posebaj, zato moraš razne podatke shranjevat (mysql/datoteka/..) in jih nato brat pri novem requestu, to boš pri tej igri rabil. Jz bi naredu neki v tem smislu:
server logika:
maš recimo 3 tabele s stolpci:
- igralec (session, nickname)
- igra (id_igre, session1, session2, status)
- poteze (id_igre, session, x_poteza, y_poteza)
session je phpjev session id (PHPSESSID), ki ga dobi vsak browser, ko se poveže s strežnikom in unikatno loči browserje, s tem ločiš uporabnike (neke vrste id). Session1 in session2 sta sessiona od obeh igralcev
1)
- igralec pride na tvoj sajt. PHP preveri, če v tabeli igralec že obstaja igralec s tem sessionom. Če ne obstaja, se mu naloži html, kjer je input za vpis nicknejma in gumbom "new game". Če session že obstaja, imaš nick že shranjen, tako da tistega inputa ni treba izrisovati.
- Ko igralec vpiše nicknejm (če je treba) in klikne na "new game", se z ajaxom pošlje na server request z akcijo "new_game"
- PHP preveri, če v tabeli igra obstaja igra z statusom "waiting". Ker ne obstaja, se vanjo zapiše igralčev session in status "waiting", odgovori z statusom "waiting"
2)
- drug igralec pride na tvoj sajt, zgodi se enako kot prej
- ko ta igralec klikne na "new game", PHP najde v tabeli igre eno igro z statusom "waiting". Status spremeni v "started", odgovori s statusom "started"
client & server logika:
- ko client od serverja po requestu za "new_game" dobi status "started", začne cikel (glej javascript setInterval), recimo na vsake 2 sekundi, kjer se pošilja na server request z akcijo "check_status"
- ko PHP dobi ta request, preveri v tabeli poteze zadnjo potezo za igro, kjer je en izmed session1 ali session2 pripada temu igralcu in vrne x in y, true/false, če je to njegova poteza (če ta session, ki je zabeležen v tej potezi, pripada njemu) ter status igre (recimo: 0 - igra teče naprej, 1 neodločen izid, 2 zmagal je ta igralec, 3 zmagal je nasprotnik - glej čisto zadnjo alinejo)
- client preveri, če je potezo, ki jo je dobil z requestom "check_status" že narisal, če je ni, nariše nov križec/krogec (glede na to, če je bila to igralčeva ali nasprotnikova poteza). Če je bila zadnja poteza od nasprotnika, tudi omogoči nadalnje klikanje po poljih (glej naslednjo alinejo), če pa je dobil odgovor, da je konec igre, zaključi igro
- ko igralec klikne na novo polje, se pošlje request z akcijo "new_move" in x ter y pozicijo polja. PHP najprej preveri, če je zadnja poteza v tabeli poteze za to igro od nasprotnika, če ni, potem vrne status "stop_hacking" :D, drugače se v tabelo zapiše nova poteza (to potezo potem nasprotnik dobi, ko njegov browser pošlje request z "check_status"...). PHP odgovori z statusom "move_accepted", javascript pa onemogoči oz. ignorira vse nadalnje klike po poljih, dokler ne dobi z "check_status" nazaj nove poteze, ki jo je naredi nasprotnik. (opomba: bolje je, da se takoj po kliku onemogoči klikanje po poljih igralcu, drugače lahko med čakanjem na odgovor iz strežnika klika po poljih kot blesav, sicer bo PHP spet preveril, če lahko on naredi potezo, samo je to brezvezen overhead..)
- preverjanje zmagovalca naj bo na serverju, PHP po vsaki zabeležbi nove poteze preveri, če je igra končana za to igro ter kdo je zmagovalec oz. če je igra neodločena. Če je igre konec, se v tabeli igra posodobi z statusom "ended"
to je samo okvirno, mislim da sem pokril večino logike, ostalo dodaj sam
server logika:
maš recimo 3 tabele s stolpci:
- igralec (session, nickname)
- igra (id_igre, session1, session2, status)
- poteze (id_igre, session, x_poteza, y_poteza)
session je phpjev session id (PHPSESSID), ki ga dobi vsak browser, ko se poveže s strežnikom in unikatno loči browserje, s tem ločiš uporabnike (neke vrste id). Session1 in session2 sta sessiona od obeh igralcev
1)
- igralec pride na tvoj sajt. PHP preveri, če v tabeli igralec že obstaja igralec s tem sessionom. Če ne obstaja, se mu naloži html, kjer je input za vpis nicknejma in gumbom "new game". Če session že obstaja, imaš nick že shranjen, tako da tistega inputa ni treba izrisovati.
- Ko igralec vpiše nicknejm (če je treba) in klikne na "new game", se z ajaxom pošlje na server request z akcijo "new_game"
- PHP preveri, če v tabeli igra obstaja igra z statusom "waiting". Ker ne obstaja, se vanjo zapiše igralčev session in status "waiting", odgovori z statusom "waiting"
2)
- drug igralec pride na tvoj sajt, zgodi se enako kot prej
- ko ta igralec klikne na "new game", PHP najde v tabeli igre eno igro z statusom "waiting". Status spremeni v "started", odgovori s statusom "started"
client & server logika:
- ko client od serverja po requestu za "new_game" dobi status "started", začne cikel (glej javascript setInterval), recimo na vsake 2 sekundi, kjer se pošilja na server request z akcijo "check_status"
- ko PHP dobi ta request, preveri v tabeli poteze zadnjo potezo za igro, kjer je en izmed session1 ali session2 pripada temu igralcu in vrne x in y, true/false, če je to njegova poteza (če ta session, ki je zabeležen v tej potezi, pripada njemu) ter status igre (recimo: 0 - igra teče naprej, 1 neodločen izid, 2 zmagal je ta igralec, 3 zmagal je nasprotnik - glej čisto zadnjo alinejo)
- client preveri, če je potezo, ki jo je dobil z requestom "check_status" že narisal, če je ni, nariše nov križec/krogec (glede na to, če je bila to igralčeva ali nasprotnikova poteza). Če je bila zadnja poteza od nasprotnika, tudi omogoči nadalnje klikanje po poljih (glej naslednjo alinejo), če pa je dobil odgovor, da je konec igre, zaključi igro
- ko igralec klikne na novo polje, se pošlje request z akcijo "new_move" in x ter y pozicijo polja. PHP najprej preveri, če je zadnja poteza v tabeli poteze za to igro od nasprotnika, če ni, potem vrne status "stop_hacking" :D, drugače se v tabelo zapiše nova poteza (to potezo potem nasprotnik dobi, ko njegov browser pošlje request z "check_status"...). PHP odgovori z statusom "move_accepted", javascript pa onemogoči oz. ignorira vse nadalnje klike po poljih, dokler ne dobi z "check_status" nazaj nove poteze, ki jo je naredi nasprotnik. (opomba: bolje je, da se takoj po kliku onemogoči klikanje po poljih igralcu, drugače lahko med čakanjem na odgovor iz strežnika klika po poljih kot blesav, sicer bo PHP spet preveril, če lahko on naredi potezo, samo je to brezvezen overhead..)
- preverjanje zmagovalca naj bo na serverju, PHP po vsaki zabeležbi nove poteze preveri, če je igra končana za to igro ter kdo je zmagovalec oz. če je igra neodločena. Če je igre konec, se v tabeli igra posodobi z statusom "ended"
to je samo okvirno, mislim da sem pokril večino logike, ostalo dodaj sam
Zgodovina sprememb…
- spremenil: illion ()
illion ::
za pošiljanje parametrov client-server ti predlagam JSON, v javascripti, najbrž boš uporabljal jQuery, pod data nastaviš objekt tipa:
{
action: 'new_move',
x: 1,
y: 2
}
php v $_REQUEST arrayu dobi action, paremeter, kjer se primerno odzove na to akcijo, za odgovor pa kar v PHPjev array zapišeš odgovor, recimo odgovor na 'check_status'
$response = array(
'x' => 1,
'y' => 2,
'is_my_move' => true, // ce je to poteza tega igralca ali nasprotnika
'game_status' => 0
);
in ta array spremeni v json ter ga s primernimi headerji pošlje nazaj:
header('Content-type: application/json');
echo json_encode($response);
exit;
{
action: 'new_move',
x: 1,
y: 2
}
php v $_REQUEST arrayu dobi action, paremeter, kjer se primerno odzove na to akcijo, za odgovor pa kar v PHPjev array zapišeš odgovor, recimo odgovor na 'check_status'
$response = array(
'x' => 1,
'y' => 2,
'is_my_move' => true, // ce je to poteza tega igralca ali nasprotnika
'game_status' => 0
);
in ta array spremeni v json ter ga s primernimi headerji pošlje nazaj:
header('Content-type: application/json');
echo json_encode($response);
exit;
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | JqueryOddelek: Izdelava spletišč | 1814 (1538) | mk818764 |
» | youtube dolpotegOddelek: Pomoč in nasveti | 1107 (1007) | pino |
» | [Ajax in Java] v IE6 dela, v Firefoxu neOddelek: Programiranje | 1922 (1676) | krho |
» | [PHP, javascript] program za seštevanje v dveh posameznih oknihOddelek: Programiranje | 2383 (2253) | |CyGNUS-x |
» | Internet strani kot slideshowOddelek: Izdelava spletišč | 2117 (1868) | sverde21 |