Wie Schleife machen?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • [pwn]
    new string[1+MAX_PLAYERS+65]
    for(new i = 0; i < MAX_PLAYERS; i++){
    if(sStats[pTod] == 1 ){
    format(string, sizeof(string), "Der Spieler %i ist tod ", i);
    SendClientMessageToAll( 0xFFFFFFFF, string);
    }
    }
    [/pwn]

    Hier z.B. wird einfach im Chat für alle ausgegeben, welcher Spieler Tot ist,
    jetzt einfach untereinander, nur zur Demonstration,
    je nach dem, was du nun mit dem machen willst, musst dus nun anpassen.
    Es wird nun di ID des Spielers angezeigt, nicht der Name.
    Um den Namen anzuzeigen nutze einfach GetPlayerName.
    Gruß,
    Dennis
  • Also ne Funktion zum Zählen der Spieler, die noch am leben sind könnte so aussehen:
    (ich gehe davon aus, dass wenn "sStats[ i ][pTod]" 0 ist, der Spieler noch am leben ist)

    [pwn]
    CountLivingPlayers(){
    new lebende = 0;
    for(new i = 0; i < MAX_PLAYERS; i++){
    if(sStats[pTod] == 0 && IsPlayerConnected(i)){
    lebende++;
    }
    }
    return lebende;
    }
    [/pwn]

    Nun kannst du einfach abfragen:
    [pwn]
    if(CountLivingPlayers() == 1){
    SendMessageToAll(0xFFFFFFFF, "Nur noch ein Spieler ist am leben!");
    }
    [/pwn]

    Diese Funktion (Die ich gerade ohne testen und großer Denkerei eben hingeklatscht habe, falls ein Bug existieren sollte, pls mal melden^^)
    Zählt nun die lebende Spieler, also du kannst damit z.B. auch ausgeben, wie viele Spieler noch leben.

    Wenn du eine Funktion willst, die nur true oder false ausgibt, also true, wenn noch 1 Spieler lebt, false, wenn mehr oder weniger,
    dann könnte dies so aussehen:
    [pwn]
    IsOnlyOneLiving(){
    new lebende = 0;
    for(new i = 0; i < MAX_PLAYERS; i++){
    if(sStats[i][pTod] == 0 && IsPlayerConnected(i)){
    lebende++;
    }
    }
    if(lebende == 1){
    return 1;
    }else{
    return 0;
    }
    }
    [/pwn]


    Also die erste Funktion gibt aus, wie viele Spieler noch leben, die 2. gibt true (1) aus, wenn nur noch ein Spieler lebt, an sonsten false (0).
    Mit der 1. Funktion kann man also an sich mehr machen, als mit der 2. ^^.
    Gruß,
    Dennis


    //EDIT:
    Ach ja, die 2. Funktion kann man, sofern man auch die 1. drinnen hat wesentlich einfacher machen:
    [pwn]
    IsOnlyOneLiving(){
    if(CountLivingPlayers() == 1){
    return 1
    }else{
    return 0;
    }
    }
    [/pwn]
    //EDIT: Natürlich IMMER eine for Schleife, und eine 2. variable,
    war verpeilt und zus ehr darauf bedacht, eine doofe locale Variable zu sparen :S
  • Moin,
    hab gestern wegen Zeitdruck nen doofen Flüchtigkeitsfehler in den Schleifen begangen, da ich erstmal die hochzählende Variable i namnte und dann in lebende änderte, da ichs doch verstaendlicher machen wollte.
    im Schleifenkopf muss natuerlich rein:
    lebende < MAX_PLAYERS.
    Bin gerade wieder unterwege vernuenftife erklaerung kommt spaeter dann, Bitte nun alles nochmal angucken, habs korrigiert.
    Gruss,
    Dennis
  • moin,
    so, da ich nun quasi eine Stunde Zeit habe,
    schreibe ich mal eine kleine Erklärung zu den Schleifen ^^.
    "for" und "while" Schleifen sind im Grunde gar nicht so verschieden.
    Beide haben die gleiche Abfrage, BEVOR der Schelifeninhalt abgearbeitet wird (for und while sind Kopfgesteuerte Schleifen).
    Als Abfragekriterium haben wir bei beiden:
    [pwn]i< MAX_PLAYERS[/pwn]
    solange dies true, also wahr ist, solange wird die Schleife abgearbeitet, an sobald dies fals, also falsch ist, wird die Schleife beendet.
    Also wenn MAX_PLAYERS = 500 ist, wird die Schleife beendet, sobald die Variable "i" größer als 500 ist.
    bei der for-Schleife ist das genau das selbe, auch hier wird beendet, sobald "i" größer ist, als MAX_PLAYERS (500).

    Der Unterschied ist, for ist eine Zählschleife,
    bei jedem Schleifendurchgang wird hoch bzw. runtergezählt.
    Bei der for-Schleife wird im Schleifenkopf wesentlich mehr gemacht, als in der while-schleife.
    Im Kopf der for-Schleife wird direkt eine Variable declariert, die auch initialisiert werden kann (also man kann ihr direkt einen Wert geben, was ich immer empfehle, z.b. i=0).
    neben der Declaration und der Abfrage zählt die for-Schleife direkt auch noch in die Variable, also in dem Fall zählt er die Variable i immer um eins hoch (letztes in der for-Schleife: i++).
    Wichtig hierbei und der Grund, warum ich die while-Schleife genutzt habe ist der, dass die Variable i nur local IN der while-Schleife existiert. Weiteres dazu gleich.
    Nun erstmal zum Beispiel:
    [pwn]
    for(new i = 0; i < MAX_PLAYERS; i++){ // Zuerst wird die Variable "i" declariert und initialisiert (ihr wird den Wert 0 gegeben). Dannach geben wir die Abfrage an, also in dem Fall soll die Schleife solange ausgeführt werden, solange i kleiner ist, als MAX_PLAYERS. als letztes zählen wir den Wert von der Variable "i" immer um eins hoch.
    // Hier geschieht bei jedem Schleifendurchgang etwas
    }
    [/pwn]

    Nun habe ich etwas davon gesagt, das die Variable "i" nur local in der for-Schleife vorhanden ist,
    dies bedeutet ganz einfach folgendes:
    [pwn]
    for(new i = 0; i < MAX_PLAYERS; i++){
    printf("Schleifendurchgang: %i", i); // Gibt in der Console den Inhalt von "i" bei jedem Schleifendurchgang aus
    }
    [/pwn]
    hier würde das in der Console so aussehen:

    Schleifendurchgang: 1
    Schleifendurchgang: 2
    Schleifendurchgang: 3
    etc. ....


    Nun, soweit innerhalb der for-Schleife können wir also die Variable "i" nutzen.
    Außerhalb jedoch nicht:

    [pwn]
    for(new i = 0; i < MAX_PLAYERS; i++){
    printf("Schleifendurchgang: %i", i); // Gibt in der Console den Inhalt von "i" bei jedem Schleifendurchgang aus
    }
    printf("Schleifendurchgang: %i", i); // Fehler: Variable "i" existiert nicht
    [/pwn]

    Also können wir mit "i" nicht allzuviel machen, also z.B. keine Endzahl ohne Weiteres ausgeben.
    Daher nutzte ich die while-Schleife, da ich hier zwar im Prinzip das selbe mache, jedoch die Variable "i" schon vor der Schelife declariere und initialisiere, in der Schleife mit dieser Arbeite und dannach ausgebe. Dies geht, da die Gültigkeit der Variable sowohl innerhalb, als auch außerhalb der Schleife gilt.

    [pwn]
    new i= 0; // Ist auch außerhalb der Schleife gültig
    while(i< MAX_PLAYERS){
    i++;
    }
    printf("Ergebnis: %i", i); // gibt das Ergebnis aus, also wieoft hochgezählt wurde.
    [/pwn]

    man kann die Gültigkeit von Variablen in PAWN Hirachisch sehen,
    als Beispiel:
    [pwn]
    new a = 5;
    {
    printf("Ergebnis: %i", a); // Gibt 5 aus
    new b = 3;
    {
    new c = 12;
    printf("Ergebnis: %i", a); // Gibt 5 aus
    printf("Ergebnis: %i", b); // Gibt 3 aus
    printf("Ergebnis: %i", c); // gibt 12 aus
    }
    printf("Ergebnis: %i", a); // Gibt 5 aus
    printf("Ergebnis: %i", b); // gibt 3 aus
    printf("Ergebnis: %i", c); // Error: Variable nicht declariert
    }
    printf("Ergebnis: %i", a); // gibt 5 aus
    printf("Ergebnis: %i", b); // Error: Variable "b" nicht declariert
    printf("Ergebnis: %i", c); // Error: Variable "c" nicht declariert
    [/pwn]

    Also die while-Schleife habe ich nun genutzt, damit ich das Ergebnis der Variable "lebende" auch nach der while-Schleife nutzen kann.
    Die Variable "i" kann ich außerhalb der for-Schleife erstmal nicht mehr nutzen.

    Soviel zur einfachen Erklärung von for und while Schleifen, sowie Gültigkeitsbereiche.
    Natürlich gibt es auch Möglichkeiten, Variablen zu globalisieren usw., was ich aebr dann erst in einem richtigem Tutorial erklären werde (Mein PAWN Tut, was ich eig. auch mal wieder weiter führen möchte).
    Das hier ist jetzt zwar lang usw. geworden, ich werde das nun aebr mal in der Hinterhand behalten, und auch als Ansatz für das kapitel "Schleifen" in meinem PAWN Tutorial verwenden, was dann auch iwann mal kommen wird.

    Auf die if-Abfrage bin ich nun nicht eingegangen, aber ich gehe mal davon aus, das du das soweit kennst, an sonsten kannst du nochmal nachfragen.
    Also die Freistunde habe ich nun immerhin fast zur Hälfte jetzt rum bekommen :D
    Falls du Fragen hast kannst du gern hier fragen,
    ich hoffe das von mir eben hingeklatschte erklärt das ein oder andere.
    Gruß,
    Dennis
  • Die Funktion wie sie oben steht hat einen kleinen (Denk-)Fehler.
    So würde, wenn jemand am Leben ist, immer 500 rauskommen und solange keiner leben würde, sogar in einer Endlosschleife enden.

    Hier die funktionierende Funktion, habe mal versucht das auch nochmal etwas zu erklären, bezogen auf diese Funktion:
    [pwn]CountLivingPlayers() {
    new living = 0; // die Variable living deklarieren, die wir nutzen werden, um die Anzahl der lebenden Spieler zu zählen

    for(new i = 0; i < MAX_PLAYERS; i++) {
    /* i hilft uns in dieser Schleife, um die Anzahl der Schleifendurchläufe zu zählen und mit MAX_PLAYERS zu vergleichen
    am Anfang der Schleife wird i deklariert und auf 0 gesetzt (new i = 0)
    wenn i kleiner als MAX_PLAYERS ist, wird der Schleifeninhalt ausgeführt (i < MAX_PLAYERS)
    i wird nach jedem Schleifendurchlauf um 1 erhöht (i++) */

    if(!sStats[pTod]) { // wenn der Spieler mit der ID i nicht Tod ist (=> folglich noch lebt)
    living++; // wird die Variable living um 1 erhöht
    }
    }
    return living; // living wird als Ergebnis der Funktion übergeben (enthält die Anzahl der lebenden Spieler)
    }[/pwn]

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Piranha ()

  • @Piranha stimmt voll und ganz,
    dass man die Spieler alle durchgehen muss, habe ich da einfach mal ignoriert,
    hatte da nu was anders im Kopf...
    An der Uhrzeit erkennt man vll., warum ich etwas verpeilt bin da :D

    Natürlich müssen wir alle Spieler durchgehen,
    daher selbstverständlich immer mot einer Forschleife arbeiten,
    wir brauchen sowohl die locale Variable i, als auch die Variable lebende.

    [pwn]
    CountLivingPlayers(){
    new lebende = 0;
    for(new i = 0; i < MAX_PLAYERS; i++){
    if(sStats[pTod] == 0 && IsPlayerConnected(i)){
    lebende++;
    }
    }
    return lebende;
    }
    [/pwn]

    So extrem simpel,
    man darf nur nicht verpeilt sein, war gestern echt nen mieser Tag...
    [pwn]
    for(new i = 0; i < MAX_PLAYERS; i++){
    [/pwn]

    Wir gehen alle Spieler durch,

    [pwn]
    if(sStats[i][pTod] == 0 && IsPlayerConnected(i)){
    lebende++;
    }
    [/pwn]
    ist Tod == 0 dann lebende + 1
    NUR Spieler, die online sind, werden berücksichtigt (Da ich lange nichts mit SAMP gemacht habe, war mir diese Abfrage ja gar nicth mehr im Sinne :S )

    So, das müsste es sein,
    sry nochmal,
    hatte damals echt net so diese Denkfehler :S


    //Zu den "stock" Fragen:
    Du kannst genausogut einen "stock" davor machen,
    dies ist lediglich dafür da, Funktionen, die nicht genutzt werden müssen zu markieren,
    heißt,
    hast du eine Funktion mit stock, die du im Skript nicht verwendest,
    dann wird es ignoriert und NICHT mit kompiliert.
    verwendest du kein "stock", dann wird es mitkompiliert und es gibt ein Warning, dass du diese Funktion nicht nutzt.
    stock ist also für Funktionen, die sowieso verwendet werden sinnlos, nur für welche, die evt. nicht verwendet werden, damit sie nicht ins Skript implementiert werden.
    Stock ist also nur ein Zusatz zu einer Funktion.