Jump to content
  • 0

pomoc Pořadí výsledků v cyklu


Boolove

Dotaz

Dobrý den, potřebuji vytvořit příkaz, který mi vyprintuje seznam všech hráčů dle skóre od nejvyššího (nahoře) po nejnižší (dole). Používám klasický cyklus for a opírám se o hodnotu MAX_PLAYERS. Problémem je, že řazení je od nejnižšího ID po nejvyšší. Jakým způsobem lze přidat podmínku, aby bylo tohle řazení výsledků ovlivněno dle toho, jak jsem psal výše? Děkuji.

Link to comment
Share on other sites

4 odpovědí na tuto otázku

Recommended Posts

  • 2
před 1hodinou, Boolove said:

Mohl bys mi prosím ukázat néjaký názorný příklad

Takto by mohlo vyzerať riešenie pomocou spomínaného include inline-sort na zoradenie hráčov (a napríklad ZCMD na vytvorenie príkazu):

Spoiler

#define FILTERSCRIPT

#include <a_samp>
#include <sort-inline>
#include <ZCMD>

stock PrintPlayersSortedByScore()
{
    // najskôr sa uložia do poľa sortedPlayers všetky ID od 0 až po MAX_PLAYERS - 1 
    // napr. pre MAX_PLAYERS = 100 by to boli ID 0, 1, 2, 3, ..., 98, 99
    new sortedPlayers[MAX_PLAYERS] = {0, 1, ...};

    // toto pole sa pomocou include inline-sort zoradí tak, ako potrebujeme
    sortInline sortedPlayers => (R = left > right) {
        new lc = IsPlayerConnected(left);
        new rc = IsPlayerConnected(right);

        if (lc != rc) {
            R = lc > rc;
        } else {
            R = GetPlayerScore(left) > GetPlayerScore(right);
        }
    }

    // v tomto bode je už pole sortedPlayers zoradené a stačí ho len postupne prejsť a vypísať nick a score každého nájdeného ID (ak je hráč s daným ID pripojený)
    for (new i = 0; i < sizeof(sortedPlayers); ++i)
    {
        new playerid = sortedPlayers[i];
        if (IsPlayerConnected(playerid))
        {
            new name[MAX_PLAYER_NAME + 1];
            GetPlayerName(playerid, name, sizeof(name));

            new msg[144];
            format(msg, sizeof(msg), "%s: %d score", name, GetPlayerScore(playerid));
            SendClientMessageToAll(-1, msg);
        }
    }
}

CMD:printscore(playerid)
{
    PrintPlayersSortedByScore();
    return 1;
}

 

 

Edited by DuFF
  • Děkuji (+1) 1
Link to comment
Share on other sites

  • 0

Zdravím,
najskôr skúsim pre istotu vysvetliť, prečo sa vypisujú mená a skóre hráčov v takom poradí, v akom sa vypisujú: 
Predpokladám, že aktuálne kód vyzerá približne takto:

Spoiler

for (new i = 0; i < MAX_PLAYERS; ++i)
{
    if (IsPlayerConnected(i))
    {
        new msg[144];
        new name[MAX_PLAYER_NAME + 1];
        GetPlayerName(i, name, sizeof(name));
        format(msg, sizeof(msg), "%s: %d score", name, GetPlayerScore(i));
        SendClientMessageToAll(-1, msg);
    }
}

 

Ako bolo povedané - ide o klasický for cyklus. Do premennej i sa na začiatku uloží hodnota 0 a následne sa vykoná telo cyklu. To znamená, že sa overí, či je hráč s ID 0 pripojený, a ak áno, vypíše sa jeho nick a skóre všetkým hráčom do chatu. Následne hodnota i stúpne o 1. Potom sa overí, či je hodnota uložená v premennej i menšia ako MAX_PLAYERS, a ak je, opäť sa vykoná telo cyklu s tým, že v i bude uložená hodnota 1. Teda sa overí, či je pripojený hráč s ID 1, a ak je, vypíše sa do chatu jeho nick a skóre. Týmto spôsobom sa pokračuje až dovtedy, kým neprestane platiť podmienka i < MAX_PLAYERS.

Teraz k riešeniu problému:
Problém je možné riešiť uložením si ID hráčov do nejakého poľa a následným zoradením tohto podľa takým spôsobom, že ak má napr. ID 3 vyššie skóre ako ID 1, tak bude ID 3 uložené v poli na nižšom indexe ako ID 1. Keď je už pole takto zoradené, nie je problém (for cyklom) prejsť postupne jeho prvky (od najnižších indexov k najvyšším) a vypisovať nicky a skóre. Na zoradenie poľa existuje množstvo algoritmov, z ktorých má každý nejaké výhody a nevýhody. Môžem spomenúť napríklad Bubble sortInsertion sortMerge sortHeapsort, ... Implementácia nejakého z týchto algoritmov nemusí byť pre začiatočníka jednoduchá. Preto uvediem aj odkaz na include, pomocou ktorého je možné zoradiť pole celkom pohodlne (a využíva Merge sort). V spodnej časti stránky je aj príklad použitia tohto include, v ktorom sa rieši presne tento problém - zoradenie hráčov podľa ich skóre. 

Edited by DuFF
Link to comment
Share on other sites

  • 0
před 10hodinami, DuFF said:

blém je možné riešiť uložením si ID hráčov do nejakého poľa a následným zoradením tohto podľa takým spôsobom, že ak má napr. ID 3 menšie skóre ako ID 1, tak bude ID 3 uložené v poli na nižšom indexe ako ID 1. Keď je už pole takto zoradené, nie je problém (for cyklom) prejsť postupne jeho prvky (od najnižších indexov k najvyšším) a vypisovať nicky a skóre.

Mohl bys mi prosím ukázat néjaký názorný příklad toho, jak manipulovat s těma hodnotama v poli a jakým způsobem je následně seřazovat (tipuji, že i při tom seřazovaní bude muset být použit nějaký cyklus)?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...