Diskuze: Průběh souboje - ukládání do databáze
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 50 zpráv z 69.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
To přeci záleží na tom jestli chceš mít údaje o jednotlivých kolech
nebo ne, jak to máme vědět?
Cituji: "Poškození ovlivní několik různých faktorů a popis každého
kola se poté objeví ve zprávě o souboji."
Chci dát hráči vědět o detailním průběhu souboje, čili i o každém
kolu. Varianta "co kolo, to insert" je podle mě lepší, ale nejsem expert na
databáze a nevím, jak by to mohlo být zatěžující.
Může hráč ovlivnit, zda bude další kolo nebo prchne?
Samozřejmě insert. Jestli ho databáze provede nebo jen udělá update záleží jen na ní.
Stále jsi mi neodpověděl. Že aplikace zobrazí nějaké zprávy o souboji neimplikuje, že je bude také ukládat. Mohla by jen uložit výsledek souboje, ne průběh. Inserty nemusíš dělat postupně, ale najednou (jedním dotazem) až zápas skončí, takže to pak pomalé nebude.
Hráč prchnout nemůže. Další kolo proběhne jen v případě, že oba soupeři mají vyšší život než 0.
Tím máš na mysli, abych si ukládal do pole průběh souboje a na konci provedl INSERT v tomto smyslu?
INSERT INTO table (col1, col2)
VALUES (val1, val2), (val1, val2), (val1, val2)
A co když jsou dva souboje současně?
Jaká je časová prodleva mezi jednotlivými koly?
Souboj probíhá pomocí nekonečného cyklu, který se přeruší v
případě, že život jednoho ze soupeřů klesne na nulu.
Když bude chtít hráč na někoho zaútočit, klikne na tlačítko, PHP
vygeneruje souboj a stránka se hned přesměruje.
To znamená, že hráč nevidí průběh souboje ale až výsledek?
V podstatě ano, uvidí až výsledek. Po vygenerování souboje se stránka přesměruje na stránku se zprávami, kde hráč uvidí, jak souboj probíhal. Ale v době generování souboje hráč nic neuvidí.
Tak ten souboj udělej přímo v databázi. Jeden SQL dotaz, který zavolá vloženou proceduru. Bude to i rychlé.
Obávám se, že tak daleko mé znalosti nesahají.
Je to programování jako každé jiné. Procedura je uložena přímo v databázi v přeloženém stavu. Jenom jí dodáš, kdo s kým válčí.
Teď to zkouším a je pravda, že je to jednoduché. Jen mi to oproti PHP přijde docela nepřehledné.
Pokud to chápu správně, pak nejvhodnější bude předat pouze ID soupeřů a procedura si vše potřebné najde sama a provede souboj. Znamená to, že pak bude stačit zavolat něco takového:
$q = $pdo->prepare("CALL fight (?, ?)");
$q->execute(array($attackerID, $defenderID));
Edit:
Mohl by ses, prosím, podívat, zda na to jdu správně?
DELIMITER $$
CREATE PROCEDURE fight(attackerID INT, defenderID INT)
BEGIN
SELECT `damage`, `health` INTO @a_damage, @a_health FROM attribute WHERE user_id = attackerID;
SELECT `damage`, `health` INTO @d_damage, @d_health FROM attribute WHERE user_id = defenderID;
SET @winner = "attacker";
loop_fight: LOOP
SET @d_health = @d_health - @a_damage;
INSERT INTO fight_lap (id, attacker_health, defender_health) VALUES (NULL, @a_health, @d_health);
IF @d_health <= 1 THEN
LEAVE loop_fight;
END IF;
SET @a_health = @a_health - @d_damage;
INSERT INTO fight_lap (id, attacker_health, defender_health) VALUES (NULL, @a_health, @d_health);
IF @a_health <= 1 THEN
SET @winner = "defender";
LEAVE loop_fight;
END IF;
END LOOP;
END; $$
DELIMITER;
Přijde mi lepší napsat si tu logiku hezky objektově v PHPčku, SQL na tohle není dělané a vždy to bude nepřehledné. Na konci jen zavoláš jeden dotaz s pár inserty jak jsi napsat nahoře.
OOP není všelék. Business logika v databázi být může. Relační databáze nejsou jen skladištěm dat. Použitím OOP by se to dost zpomalilo. Kompilace několika set SQL dotazů je mnohem náročnější než kompilace jednoho.
Vypadá to dost dobře. Možná ještě lépe než v OOP. Máš to docela přehledné.
Díky. Zkusím to napsat v SQL verzi a uvidím, jak to půjde. Koneckonců se
naučím něco nového.
Také díky. Ještě bych se rád zeptal, zda nevadí vytváření hodně proměnných a provádění hodně výpočtů. Jde o to, že to, jaké hráč způsobí poškození, ovlivní cca 7 faktorů s tím, že se všechny faktory ještě přepočítávají na procentuální šanci (např. kritický útok, blokování, úhyb apod.).
Zatím se vytváří 27 proměnných pro jednoho hráče, čili 54 proměnných jen pro oba soupeře. Z toho 8 proměnných pracuje s funkcí RAND().
A říkám snad, že ano? Je opravdu hloupost dělat tohle v databázi, jedná se o simulaci, k tomu jsou určené objekty. Stored procedures jsou mocným nástrojem, ale určitě ne na tohle, kdy se ukládá jen výstup nějakého procesu, nedochází tedy k zpomalení databáze.
Nevadí to. Jenom je to takové podivné. Podle mne tu hru děláš příliš komplexní.
Nemusíš to všechno cpát do jedné procedury.
Ten tvůj způsob zatíží a zpomalí tu databázi mnohem víc.
Tím, že uložím hotový výsledek? To ani ne. Má tak jednoduchou logiku že to více nejde a cituji tebe: " Podle mne tu hru děláš příliš komplexní.". Nechci vidět, jak bude v tom GOTO paskvilu vypadat až to bude opravdu komplexní.
Abys ten výsledek spočítal, musíš nejprve z databáze ty parametry vytáhnout a to je hodně velká zátěž, pokud jich má tolik. Taháš pak data mezi PHP a DB jak kočka koťata.
Ten cyklus můžeš zjednodušit tak, že při každém běhu prohodíš role.
Až ten LOOP paskvil nahradí WHILE @health > 0
, tak už to
nebude vypadat tak hrozně.
Na co ty nepoužíváš SQL. Přijde mi, že 98% tvých rad je něco jako:
"Proč používat tenhle jazyk, když to jde přes databázy...". Popř. když
hájíš nějaký jazyk, oháníš se maticemi a nebo do každého sql kódu
házíš triggery. V SQL
se nevyznám na takové úrovni, ale rohodně není všemocná. Je to
dotazovací jazyk, tak proč tam dávat výpočetní funkce? Chci jen
vysvětlení a argumentaci. Netvrdím, že nemáš pravdu.
Každopádně pokud opravdu chce
zaznamenávat každé kolo, bude to rychlejší.
Ty výpočty vůbec nejsou složité, dají se napsat do jednoho selectu. Ani nejsou výpočetně náročné a navíc tyto operace SQL zvládá lépe než PHP.
Základním argumentem je co nejjednoduší a co nejméně početná komunikace mezi vrstvami aplikace, ale i třeba mezi objekty. Tedy princip zapouzdření a izolovanosti.
Nenašel jsem nic, co by cyklus přerušilo, žádný ekvivalent k break. Proto mi přišlo nejvhodnější použít slovo LOOP, se kterým to jde snadno.
Edit: Pardon, kecám nesmysly. Potřebuji ukončit cyklus podle jedné nebo
druhé podmínky, ale nedošlo mi, že to jde.
Možná by se sem měla přidat i možnost smazání vlastního příspěvku,
ať pak nejsem za blbce.
SQL není jen dotazovací jazyk. To je jen jedna část ze čtyř.
Jo jo, díky za nápad, to by mi rovnou mělo vyřešit i další problém.
Jestli děláš hru jako shakes and fidget, gladiatus atp. tak nač potřebuješ ukládat průběh jednotlivých kol do databáze ?
Podle mně by bylo lepší ... hráč klikne na zaútočit na hráče BLABLA, přejde se na jinou stránku abc.cz/utok/blabla kde se provede výpočet a následně se provede animace kolo po kole souboje, nebo můžeš přeskočit na konečný výsledek.
Databázi do toho zatáhneš jen tak, že odečteš body či peníze apod. co hráč získá/ztratí...
Vážně nevidím důvod proč bys měl zaznamanávat průbehy jednotlivých kol ...
Abys měl přehled o souboji i poté, co ho provedeš. A kdo ví, co se s těmi daty dá ještě dělat, přinejmenším nějaké statistiky, které by hráči určitě uvítali (a to mluvím z vlastní herní zkušenosti).
Kdysi jsem to takhle měl, že se uložilo prakticky jen to, kdo vyhrál a kolik jsi získal, ale průběžné ukládání je, alespoň pro mě, mnohem vhodnější.
K čemu ti to bude ? Na konci zápasu vyhodnotíš celkové poškození, ubrané věci, získané věci atp.
Nejvyšší poškození porovnáš se současným a kdyžtak změníš a tak to uděláš podobně s dalšíma statistikama ... přičteš bod k vítězství/porážce atp.
trochu jsem nepochopil způsob, který jsi zvolil.
Neznám princip tvé hry, ale jestli jsem pochopil:
co kolo to cca jeden záznam do DB, jeden hráč, sto kol. Sto hráčů deset
tisíc záznamů...
není to tak trochu zbytečné hromadění informací?
Spíš bych to viděl na podrobnější popis hráče, od záznamu zdraví, síly a pod.
Právě proto jsem se na začátku ptal, zda každé kolo má být jeden insert.
Záleží na tom, co od toho chceš.
Bral bych to ve více rovinách. Zaznamenávat vývoj postavy je určitě
potřebné, ale tam bych to zredukoval na záznam kdy dosáhl dalšího levelu,
kdy koho porazil. Pak nějaký inventář který se bude také asi dost
měnit.
A pak ten boj. A u toho bych si asi vystačil jen s tím, že bych updatoval
data.
Podle funkce v DB soudím, že o programování něco víš a nerad bych tě
svedl z tvé cesty. Je to na tobě
To že ti radím, ještě neznamená, že mám pravdu
A když budu chtít vidět, jak probíhala jednotlivá kola, tak to jinak než za pomocí insertů udělat nemohu, ne? Kdybych chtěl například vidět, do kterého kola jsme si se soupeřem byli rovni, a od kterého šly mé šance na výhru výrazně dolu. Výsledky soubojů nebudou tak jasně předem určené, proto bych chtěl dopřát detailní výpis.
Rád si vyslechnu každý názor, nápad a kritiku. Sice už nějakou dobu
programuji, ale vím, že v tom pořád nejsem dobrý - a právě proto jsem
založil tohle téma.
ale stejně bych to raději dal do dvou vrstev a oddělil statistku od samotné hry.
Když chceš udělat detailní výpis tak si ho udělej (nejdřív vypočítáš souboj a poté si to z informací vytáhni), ale nic neukládej do databáze, jsou to zbytečnosti...
Hráč ho chce vidět jen jednou, pak ho zajímá jen vítězství/prohra...
Kompletní statistiku, pokud podle ní nebudeš vyhledávat, můžeš také do DB uložit jako jeden string v JSON nebo XML. Tím se to hodně zjedoduší.
Nevím, jestli tou statistikou máš na mysli to, co já, ale pokud ne, tak bych JSON formátem tedy mohl uložit klidně i detaily souboje (kolo po kolu). V PHP bych to pak dekódoval pomocí json_decode() a dostal bych pole, které bych pak jen prošel a vypsal detaily.
Jako vážně nechápu proč pořád chceš ukládat celý zápas - 100 kol - do databáze, tam pak budeš mít strašně hodně záznamů a úplně zbytečných
Prostě budeš mít :
stránka 1 : vybereš si hráče na kterého zaútočíš -> klik -> odkaz na stranku 2
stránka 2 : výpočet souboje, vytáhnutí dat do statistiky(max úder atp.) + animaci souboje, zkontrolování ocenění (max úder, přidat 1 k vítězství/prohře), změna peněz/předmětů
do databáze si tedy uložíš jen maximálně záznam že jsi měl zápas a prohra/vítězství a případně si přeuložíš ocenění...
jako mít tam při 1000 soubojů denně 100,000 zápisů je zbytečnost ...
Při JSON formátu by tam bylo tolik záznamů, kolik by bylo soubojů. Možná se budeš divit, ale hodně hráčů zajímají detaily souboje i potom, co se provede.
nevidím důvod proč by to chtěli, ale je to tvá hra, tvá věc
mě teda nezajímá, že jsem před měsícem v souboji udeřil silou 550 ...
OK, jestli mi s tím nemáš jak pomoci, tak bych byl nerad, aby se to tu zaspamovalo. Díky.
Zobrazeno 50 zpráv z 69.