Das andere Lizenssystem, oder: 1 + 10 = 3

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hey Leute,


    da es mich doch immer wieder wundert, wie... umfangreich einige Booleans ( true / false ) speichern, mache ich hier mal ein Tutorial, wie man in einer Variable speichert, welche von 5 ( oder mehr ) Scheinen man hat.
    Das geht natürlich bei allen anderen Anwendungsgebieten auch, ob ihr nun 85 Gegenstände habt und alle müssen gefunden werden, ihr habt aber keine Lust, 85 Einträge in der Benutzerdatei zu machen, ...


    Vorwissen:

    Spoiler anzeigen

    Ich erkläre euch "schnell und dreckig", wie binär gezählt wird.
    Sicherlich kennt ihr "Zahlen",, die z.B. so aussehen:

    Code
    000100100001001100111000

    Spoiler anzeigen
    und so weiter. Man kann sie in dezimal umrechnen, indem man von rechts nach links immer 2^(Stelle - 1) addiert, wenn der Wert der Stelle 1 ist.
    Als Beispiel:

    Code
    1. Reihe sind die Stellen2. die "Binäre Zahl"8765432100101100Von rechts nach links:Stelle 1 ist 0, nichts machen.Stelle 2 ist 0, nichts machen.Stelle 3 ist 1, 2^(3 - 1) = 4 ( 2 * 2 ). Zwischenstand: 4Stelle 4 ist 1, 2^(4 - 1) = 8 ( 2 * 2 * 2 ). Zwischenstand: 4 + 8 = 12Stelle 5 ist 0, nichts machen.Stelle 6 ist 1, 2^(6 - 1) = 32 ( 2 * 2 * 2 * 2 * 2 ). Zwischenstand: 12 + 32 = 44Stelle 7 ist 0, nichts machen.Stelle 8 ist 0, nichts machen.


    Haubtteil:

    Spoiler anzeigen

    Was ihr sicher nicht gemerkt habt, ist, dass ihr jetzt gerade 8 Werte gespeichert habt / speichern könnt.
    Jeder Stelle in der binären Zahl kann man 1 Wert zuweisen, so ist Wert 1 "false", Wert 2 "false", Wert 3 "true", Wert 4 "true", Wert 5 "false", Wert 6 "true", Wert 7 "false", Wert 8 "false" - das könnt ihr mit der Zahl 44 ausdrücken.
    So wird aus

    Code
    pCarLicense,  pBoatLicense,  pFishingLicense,  pTruckLicense,  pSchlagmichtodLicense,  pMotorbikeLicense,  pPlaneLicense,  pHelikopterLicense

    Spoiler anzeigen
    ein einfaches

    Code
    pLicenses

    Spoiler anzeigen
    Und es müssen keine 8 Zeilen in der Datei ( 8 Rows in der Datenbank ) stehen, sondern nur 1 :O
    Dasbeste daran: Man kann den Inhalt von pLicenses auch einfach in die Datei schreiben und wieder auslesen, man muss dabei nichts beachten - es bleibt in der Datei als einfache Zahl stehen.


    Der Code-Teil:

    Spoiler anzeigen

    Die Abfrage, ob eine Lizens vorhanden ist, eine zu vergeben oder eine wegzunehmen, ist einfach. Dafür brauchen wir nur "+" ( Plus ), "-" ( Minus ) und "&" ( Binäres und ).
    Die Lizensen definieren wir gan oben als Zahl, angefangen mit "1" - die nächste ist der Vorgänger-Wert mal 2 ( oder 2^(Stelle - 1) ).

    Code
    #define LICENSE_CAR         1#define LICENSE_BOAT        2#define LICENSE_PLANE       4#define LICENSE_BIKE        8#define LICENSE_HELI        16#define LICENSE_LKW         32#define LICENSE_FISCHING    64#define LICENSE_KEINEAHNUNG 128

    Spoiler anzeigen
    Wollen wir dem Spieler jetzt eine Lizenz geben, was ja nicht sooo unwarscheinlich ist, addieren wir die Lizens einfach zu seinen Lizensen dazu.

    Code
    PlayerLicenses[playerid] += LICENSE_CAR;PlayerLicenses[playerid] += LICENSE_LKW;

    Spoiler anzeigen
    Ist er jetzt 80 Km/h zu schnell geblitzt worden, ist der Führerscheinlappen erst einmal wieder weg :( 

    Code
    PlayerLicenses[playerid] -= LICENSE_CAR;

    Spoiler anzeigen
    Und wenn er dann noch mit dem LKW angehalten wurde, und seinen Schein vorzeigen soll, lässt sich das auch leicht prüfen:

    Code
    if(PlayerLicenses[playerid] & LICENSE_LKW)    SendClientMessage(playerid, 0xFF00FF, "Du hast eine LKW-Lizens :O");

    Spoiler anzeigen
    .
    Very Very Very important Notiz: Gebt einen Spieler nur dann eine Lizenz, wenn ihr genau wisst, dass er keine hat, und zieht ihm nur dann eine ab, wenn ihr wisst, dass er eine hat.
    Sonst überkreuzt sich das gesammte System ;)


    Voll-funktionierender Code ( mit nur 5 Lizensen, die gegeben, genommen und geprüft werden :(

    Code
    #include <a_samp>#define LICENSE_CAR         1#define LICENSE_BOAT        2#define LICENSE_PLANE       4#define LICENSE_BIKE        8#define LICENSE_HELI        16new licenses = 0;public OnFilterScriptInit(){	print("--- Teste Boolean as Bit ---");	licenses = 0;	// Geben von ein paar Lizensen	licenses += LICENSE_CAR;	licenses += LICENSE_BIKE;	printLicenses();	// Wegnehmen der Bike-Lizens	licenses -= LICENSE_BIKE;	printLicenses();	return 1;}public OnFilterScriptExit(){	return 1;}stock printLicenses(){	print("--- Lizensen ---");	if(licenses & LICENSE_CAR)	    print(" Auto: Vorhanden");	else	    print(" Auto: Nein");	if(licenses & LICENSE_BOAT)	    print(" Boot: Vorhanden");	else	    print(" Boot: Nein");	if(licenses & LICENSE_PLANE)	    print(" Flugzeug: Vorhanden");	else	    print(" Flugzeug: Nein");	if(licenses & LICENSE_BIKE)	    print(" Motorräder: Vorhanden");	else	    print(" Motorräder: Nein");	if(licenses & LICENSE_HELI)	    print(" Helikopter: Vorhanden");	else	    print(" Helikopter: Nein");	print(" ");}


    Tutorial Ende. Feedback, pls :)


    Anmerkung: Das ist kein Copy- und Paste-Tutorial und auch nur Beispieltext, wie ihr Zeilen sparen könnt ;)

  • Vielen Dank!
    Recht verständlich erklärt, erleichtert unnötiges Erstellen von weiteren Variablen.
    Für jemanden, der sich nie mit dem Binär-System auseinander gesetzt hat, ist dies sehr nützlich.


    Zitat

    Dafür brauchen wir nur "+" ( Plus ), "-" ( Minus ) und "&" ( Binäres und ).


    Du könntest noch erklären, was genau hier das "binäre Und" bewirkt.


    Grüße

  • Hallo


    Meiner Meinung nach eine gute Idee. Aber wirf mal einen Blick nach C++ (Denkanstoss, kein Pawn vs C/++ Vergleich) und überleg dir mal , wann man zu bitmässigem AND/OR (und Bitshifting) rät und greifen sollte und wann nicht. Dazu kommt noch das wie. Ein Integer ist so klein, da sparst du fast nichts und zumal alloziert die Pawn Virtual Machine ihren Speicher aufgrund der Angaben im Fileheader in der Initialisierungsphase, von dem her also...


    Aber mal ein abwechslungsreicher Post hier im Forum ;)


    PS: Dazu hier ein Beitrag in C/++. Beachte den Beitrag über "Sinn" und Werkzeug zum setzen:


    http://stackoverflow.com/quest…ngle-bit-in-c/47990#47990

  • tonyalva: Kann ich bei Zeit noch mal machen :)


    Dudalus: Ich bin mir nicht mehr ganz sicher, aber Pawn regelt die Variablengrößen selber, oder ?
    Mir ging es in erster Linie nur darum, dass mich 26 Variablen für jeden Mist einfach annerven, vor allem beim speichern. So muss man nur 1 Wert speichern :)