Skript:Sortowanie listy zmiennych

Z skript.pl wiki
Skocz do: nawigacja, szukaj

Autorzy[edytuj]

Oryginalnym autorem treści jest użytkownik o nicku piratjsk. Treść została przemigrowana z forum skript.pl.

Wstęp[edytuj]

W tym poradniku będziemy dążyć do stworzenia rankingu (dla przykładu: ilości wykopanego kamienia). Poradnik ten jest adresowany do osób posiadających podstawową wiedzę o pisaniu skryptów dla pluginu Skript.

Skrypt[edytuj]

Tworzenie skryptu[edytuj]

Na początek musimy stworzyć listę zmiennych przechowującą wartości liczbowe. W praktyce krok ten będzie polegał na przykład na stworzeniu skryptu zliczającego wykopany kamień:

on join:
    {stone::%player%} is not set:
        set {stone::%player%} to 0
    {nick::%player%} is not set:
        set {nick::%player%} to uncolored display name of player
on mine of stone:
    add 1 to {stone::%player%}

Stworzyliśmy więc listę zmiennych w formacie {stone::nazwa_gracza} przechowującą wartość liczbową, w naszym przypadku ilość wykopanego przez gracza kamienia. Dodatkowo stworzyliśmy zmienną przechowującą nick gracza z uwzględnieniem wielkości znaków.

Sortowanie listy[edytuj]

Następnym krokiem będzie stworzenie komendy /top, która będzie wyświetlała 5 najlepszych kopaczy kamienia:

command /top [<integer=1>]:
    trigger:
        set {_strony} to rounded up (size of {stone::*} / 5)
        arg is between 1 and {_strony}:
            send "ranking kopaczy kamienia"
            loop {stone::*}:
               set {_lista::%loop-index%} to loop-value
            set {_num} to size of {_lista::*}
            set {_max} to arg * 5
            set {_min} to {_max} - 4
            loop {_max} times:
                loop {_lista::*}:
                    {_wartosc.%loop-number%} is not set:
                        set {_wartosc.%loop-number%} to loop-value-2
                        set {_nazwa.%loop-number%} to loop-index
                    loop-value-2 is more than {_wartosc.%loop-number%}:
                        set {_wartosc.%loop-number%} to loop-value-2
                        set {_nazwa.%loop-number%} to loop-index
                    delete {_lista::%{_nazwa.%loop-number%}%}
                    loop {_max} times:
                        loop-number is between {_min} and {_max}
                        loop-number <= {_num}:
                            send "%loop-number%. %{nick::%{_nazwa.%loop-number%}%}% (%{_wartosc.%loop-number%}%)"
                            {_max} is more than {_num}:
                                set {_r} to {_num}
                                loop {_max} - {_num} times:
                                    add 1 to {_r}
                                    send "%{_r}%. brak"
                                send "Strona: %arg% z %{_strony}%"
                                stop
                            {_strony} is 1:
                                send "Wyniki mieszcza sie na 1 stronie."
                                stop
                            send "Wyniki mieszcza sie na %{_strony}% stronach."

Schemat działania[edytuj]

  • Definiujemy komendę uwzględniając argument będący liczbą całkowitą wskazujący na stronę wyników którą chcemy zobaczyć.
  • Zapisujemy do zmiennej {_strony} ilość stron jaką zapełnią wyniki.
  • Sprawdzamy czy podana strona mieści się w przedziale od 1 do wcześniej zdefiniowanej zmiennej {_strony}.
  • Dla bezpieczeństwa kopiujemy naszą listę - tworzymy listę roboczą na której będziemy pracować.
  • Zapisujemy do zmiennej {_num} ilość wyników.
  • Zapisujemy do zmiennej {_max} nr ostatniego wyniku, który zmieści się na wybranej stronie.
  • Sortujemy:
    • Zapętlamy {_max} ilość razy, czyli tyle do jakiego miejsca w rankingu potrzebujemy wyniki.
    • W każdym zapętleniu wykonujemy następujące czynności:
      • zapętlamy listę
      • zapisujemy wartość (do {_wartosc.%loop-number%}) i nazwę (do {_nazwa.%loop-number%}) pierwszej zmiennej. %loop-number% jest to numer zapętlenia, czyli pierwsze zapętlenie - 1, drugie - 2 itd...
      • sprawdzamy wartość każdej zmiennej czy nie jest większa od tej zapisanej - jeśli jest nadpisujemy ją. w ten sposób po sprawdzeniu wartości wszystkich zmiennych w {_wartosc.%loop-number%} mamy zapisaną tą o najwyższej wartości
      • usuwamy zapisaną zmienną z listy
    • i następne zapętlenie, czyli nasz kod się powtarza z tą różnicą, że zmienna o największej wartości jest już inna gdyż pierwszą usunęliśmy z listy.
    • Efektem naszej dotychczasowej pracy są pary zmiennych:
      • {_wartosc.1}, {_nazwa.1} - przechowują zmienną o największej wartości
      • {_wartosc.2}, {_nazwa.2} - przechowują zmienną o mniejszej wartości
      • {_wartosc.3}, {_nazwa.3} - przechowują zmienną o mniejszej wartości
  • Wyświetlamy
    • Ponownie zapętlamy kod tyle razy, do którego miejsca w rankingu potrzebujemy wyniki.
    • W każdym zapętleniu wykonujemy następujące czynności:
      • sprawdzamy czy numer zapętlenia mieści się w przedziale wyników, które chcemy zobaczyć na danej stronie
      • sprawdzamy czy numer zapętlenia nie jest większy niż ilość wpisów z listy (w naszym przypadku kopaczy kamienia)
      • jeśli powyższe warunki są spełniony wyświetlamy wiadomość "%loop-number%. %{nick::%{_nazwa.%loop-number%}%}% (%{_wartosc.%loop-number%}%)", która będzie miała postać np: "1. PiratJaskiniowy (99)"

Uzupełnienie wpisu[edytuj]

Sortowanie wartości od najmniejszej do największej[edytuj]

Co w przypadku gdy chcemy posortować listę w odwrotnym kierunku? Wystarczy w 12 linii zmienić "more" na "less". Otrzymamy wtedy wyniki w takiej formie jak wcześniej z tą różnicą, że zmienna {_wartosc.1} będzie przechowywać najmniejszą wartość.

Co się stanie gdy ostatnia strona nie zostanie zapełniona?[edytuj]

Będzie krótsza od reszty, jednak możemy temu zaradzić:

  • Sprawdzamy czy taki stan ma miejsce. (czy maksymalna ilość wyników jest większa niż przechowywana w naszej liście)
  • Zapisujemy ilość zmiennych w liście do {_r}.
  • Zapętlamy kod /maksymalna ilość wyników minus liczba wpisów z naszej listy/ razy.
  • Dodajemy 1 do {_r}.
  • Wyświetlamy wiadomość "%{_r}%. brak", która będzie miała postać np: "33. brak".