Skocz do zawartości
GET

[KOSZ] [PAWN] Drzewa słownikowe, czyli Trie

Rekomendowane odpowiedzi

Zalecam przed nauką obsługiwania się biblioteką "celltrie" naukę "cellarray" gdyż są ów biblioteki dosyć powiązane ze sobą. Niestety biblioteka "celltrie" nie jest opisana ani w dokumentacji na amxx.pl, ani na wiki amxmodx`a, dlatego jeśli popełnię jakieś literówki proszę o wyrozumiałość ;D. Nie sprawdzałem czy w AMXX-Studio jest ich opis gdyż go nie używam. Główną zaletą korzystania z "celltrie" jest możliwość dynamicznego zarządzania pamięcią ;D

 

 

1Różnice CellTrie od CellArray

 w "celltrie" wyszukuje się dane za pomocą stringa (porównywalne do nvault), a w "cellarray" za pomocą indexu.

 nie trzeba po kolei zapełniać miejsca jak w przypadku "cellarray" funkcjami "push"

 

 

2Deklaracja Trie

Tak samo jak w przypadku tablic dynamicznych najpierw trzeba stworzyć zmienną poprzedzoną enum (chodzi o typ zmiennej), która będzie naszym uchwytem.

new Trie:Uchwyt

Po stworzeniu zmiennej możemy do niej "włożyć" nasz uchwyt stwarzany przy deklaracji tablicy Trie.

Uchwyt = TrieCreate()

W ten sposób ulokowaliśmy sobie troszkę miejsca na nasze "drzewko" i uchwyt do niego zapisaliśmy w zmiennej "Uchwyt" ;D

 

 

3Zapis Danych

Jak wyżej wspomniałem w "celltrie" można od razu zapisywać dane w tym miejscu w którym się chce tzn. nie trzeba(nie można) używać funkcji "push"

Można zapisywać dane na trzy sposoby:

• Jako liczbę/znak:

TrieSetCell(Uchwyt,klucz[],wartość)

• Jako ciąg znaków:

TrieSetString(Uchwyt,klucz[],wartość[])

• Jako tablicę danych:

TrieSetArray(Uchwyt,klucz[],wartość[])

• Uchwyt - Uchwyt do naszego "drzewka" 

• klucz - Unikalny klucz(ciąg znaków)

• wartość - Nasze dane, które chcemy zapisać

 

 

4Odczyt Danych

Jeśli już potrafimy zapisać dane to pozostaje nam ich odczytanie.

Podobnie jak w przypadku zapisywania, odczytać można na trzy sposoby:

• Jako liczbę/znak:

TrieGetCell(Uchwyt,klucz[],wartość)

• Jako ciąg znaków:

TrieGetString(Uchwyt,klucz[],wartość[],rozmiar)

• Jako tablicę danych:

TrieGetArray(Uchwyt,klucz[],wartość[],rozmiar)

• Uchwyt - Uchwyt do naszego "drzewka" 

• klucz - Unikalny klucz(ciąg znaków), którego użyliśmy do zapisu

• wartość - zmienna do której referencyjnie zostaną przekazane dane

• rozmiar - maksymalny rozmiar danych jakie chcemy otrzymać

Dodatkowo każda z powyższych funkcji(pobierających dane) zwraca true/false zależnie od tego czy znaleziono nasz klucz

 

 

4Czyszczenie/Niszczenie

Tak samo jak w "cellarray" można czyścić dane, a nawet powinno się (gdy zajmują nie potrzebnie miejsce)

Do tego służy funkcja:

TrieClear(Uchwyt)

Kolejnym podobieństwem do "cellarray" jest funkcja pozwalająca na wyczyszczenie danych oraz zwolnienie ulokowanego przez nas miejsca:

TrieDestroy(Uchwyt)

A jeśli nie chcemy czyścić wszystkich danych tylko dane pod jednym kluczem to możemy posłużyć się tą funkcją:

TrieDeleteKey(Uchwyt, klucz[])

• Uchwyt - Uchwyt do naszego "drzewka"

• klucz - Unikalny klucz(ciąg znaków), którego użyliśmy do zapisu

Funkcja "TrieDeleteKey" dodatkowo zwraca czy klucz istnieje

 

4Funkcje ułatwiające korzystanie z Trie

Niestety jest tylko jedna, która sprawdza czy podany klucz istnieje

TrieKeyExists(Uchwyt, klucz[])

Zwraca czy klucz istnieje

• Uchwyt - Uchwyt do naszego "drzewka"

• klucz - Unikalny klucz(ciąg znaków), którego użyliśmy do zapisu

 

4Praktyczne użycie

Może teraz troszkę praktyki, a więc wychwyćmy moment gdy gracz wpisz na "say" jakieś słowo z podanego pliku, po czym pojawi mu się tekst napisany obok danego słowa.

Opis całego pluginu zamieszczę w komentarzach

  1. #include <amxmodx>
  2. #include <amxmisc>
  3. #include <ColorChat>
  4.  
  5. new Trie:Uchwyt // Stworzenie zmiennej, w której umieścimy uchwyt
  6.  
  7. public plugin_init()
  8. {
  9. register_plugin("Praktyczne użycie Trie", "Final", "BlackPerfum");
  10. register_clcmd("say", "cmd_say")// Wychwycenie momentu(oraz tekstu) gdy gracz napisze coś na "say"
  11. }
  12. public plugin_cfg()
  13. {
  14. new szFilename[ 128 ]//Ścieżka do pliku
  15. get_configsdir( szFilename, 127 )//Pobieram ścieżkę do folderu "config"
  16. add( szFilename, 127, "/Slowa.ini" )//Na końcu ścieżki umieszczam swój plik
  17. if(!file_exists(szFilename))
  18. {
  19. set_fail_state("Plugin zostanie wylaczony z powodu braku pliku Slowa.ini")
  20. //Jeśli plik nie istnieje to wyłączam plugin
  21. return PLUGIN_CONTINUE
  22. }
  23. new iFile = fopen( szFilename, "rt" ) // Otwieram plik
  24. if( !iFile )
  25. {
  26. set_task(10.0,"LoadMaps") // Jeśli jakiś proces używa już pliku to opóźniam otwarcie pliku
  27. return PLUGIN_CONTINUE
  28. }
  29.  
  30. new szData[100] // Do tej zmiennej będe wpakowywał po kolei linijki z pliku
  31. new slowo[20],tekst[90] // Zmienne do podziału lini
  32. Uchwyt = TrieCreate()
  33. while(!feof( iFile ))
  34. {
  35. fgets( iFile, szData, 99 )//Pobieram linie
  36. if( !szData[ 0 ] || szData[ 0 ] == '^n'|| szData[ 0 ] == ';'|| szData[ 0 ] == '/' && szData[ 1 ] == '/' ) continue
  37. // Omijam nie potrzebne linie
  38.  
  39. split(szData, slowo, 19, tekst, 89, " ") // Dziele linie na dwie części (słowo i dalszy tekst)
  40. trim(slowo)// Usuwam białe znaki (o ile są)
  41. replace_all(tekst,89," ", "$") // Zamieniam spacje na dany znak
  42. trim(tekst) // Usuwam białe znaki (tu na pewno jest jeden uciążliwy, chyba że to ostatnia linia)
  43. replace_all(tekst,89,"$", " ") // Zamieniam dany znak na spacje
  44. TrieSetString( Uchwyt, slowo, tekst ) // Zapisuje słowo i tekst
  45. }
  46. fclose( iFile ) // Zamykam plik
  47.  
  48. return PLUGIN_CONTINUE
  49. }
  50. public cmd_say(id)
  51. {
  52. new slowo[20] // Tworzenie zmiennej
  53. read_args(slowo, 19)
  54. // Pobieranie 19 znaków (o ile jest ich co najmniej 19) z tekstu który napisał gracz na "say"
  55. remove_quotes(slowo) //usuwanie "
  56.  
  57. if(!TrieKeyExists(Uchwyt, slowo)) return PLUGIN_CONTINUE
  58. //Sprawdzam czy słowo które napisał gracz jest jednym ze słów które zapisaliśmy
  59.  
  60. new tekst[90]
  61. TrieGetString(Uchwyt,slowo,tekst,89) // Pobieram tekst
  62. ColorChat(id,GREEN,tekst) // Pokazuje graczu tekst
  63.  
  64. return PLUGIN_CONTINUE
  65. }

A tak wygląda nasz plik pod ścieżką "addons/amxmodx/configs/Slowa.ini"

 

amxx Nie oficjalne forum AMX MOD X
[...]

Teraz gdy gracz wpisze na "say" słowo "amxx" to pokaże mu się zielona wiadomość "Nie oficjalne forum AMX MOD X"

 

Źródło: http://amxx.pl/topic/116342-drzewa-s%C5%82ownikowe-czyli-trie/

Poradnik.rar

  • Ustrzel fraga! (+) 1

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dzięki temu można zrobić zapis w pliku, naprzykład zapis fragów dla gracza w pliku. Aby po wyjściu z serwera gracz nie tracił fragów. Już istanieje gotowa funkcja stats[0] na fragi ale gdyby tego nie było to dzięki temu można robić też taki zapis ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

dobra robota

+ za chęci :D

sory spamuje nabijam posty :D

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

to by się przydało np w sytuacji że ktoś wejdzie do pokoju i będzie coś chciał na necie to zamiast być AFK to sobie wyjdzie i fragi będą przy nastepnym wejsciu. A czy kosa tez zostanie czy tylko fragi sie zapiszą ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Wiadomość została wygenerowana automatycznie.

 

Ten temat został oznaczony przez Moderatora jako spam i wyrzucony do -> archiwum.

Jeśli się z tym nie zgadzasz, raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Gość
Ten temat został zamknięty. Brak możliwości dodania odpowiedzi.

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Polityka prywatności