Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 37

Thema: Fragen zum SCL-Code

  1. #1
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Guten Tag

    Ich programmiere ein 4 Gewinnt. Ich kann schon spielen einfach ohne auswertung.
    Die Auswertung habe ich angefangen zu programmiern.
    Unten seht ihr meinen Code für die Auswertung. Wenn man noch den Restlichen Code braucht einfach fragen.

    Code:
    #Sieg_Rot := 0;
    
    FOR #a := 1 TO 7  BY 1 DO
     FOR #b := 0 TO 5 BY 1 DO
       IF #Rot_Speicher[#a,#b] = 1 THEN
         #Sieg_Rot := #Sieg_Rot + 1;
       ELSE
         #Sieg_Rot := 0;
       END_IF;
     END_FOR;
    END_FOR;
    
    IF #Sieg_Rot = 1 THEN
      #Rot_Sieg := 1;
    ELSE
      #Rot_Sieg := 0;
    END_IF;
    Gruss
    Zitieren Zitieren Fragen zum SCL-Code  

  2. #2
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 919 Danke für 740 Beiträge

    Standard

    Zitat Zitat von bkizilkaya Beitrag anzeigen
    IF #Sieg_Rot = 1 THEN
    #Rot_Sieg := 1;
    ELSE
    #Rot_Sieg := 0;
    END_IF;
    [/CODE]
    Warum tut man sich so 'ne IF-Orgie an anstatt einfach zu schreiben:
    Code:
    #Rot_Sieg := #Sieg_Rot;

    PS: OK, vergiß das, Sieg_Rot kann ja auch größer als 1 sein.

    Mal davon abgesehen, müßten es nicht eigentlich 4 Steine und dies diagonal, neben- oder übereinander sein?
    Zum Einen wird Sieg_Rot nur auf 1 abgefragt und zum Zweiten wird ja auch weiter addiert, wenn der letzte Stein der Reihe rot war und der erste Stein der nächsten Reihe es auch ist. Und zum Dritten kann ich die Abfrage auf diagonal oder übereinander gar nicht sehen.
    Geändert von hucki (31.10.2013 um 09:49 Uhr)

  3. #3
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Ja ich weiss schon.

    Ich wollte zuerst nur die vertikalen testen bevor ich die restlichen testen will.

    Mein problem ist es das die IF abfrage nicht funktioniert und die For schleife ist jetzt auch nicht am funktionieren

  4. #4
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hucki
    Wie würdest du es machen. Unten siehst du meine ganzen Code vom Programm.

    Code:
    //Alle Zellen mit Null füllen
    IF "Reset" = true THEN 
    FOR #x := 1 TO 7 BY 1 DO                 
      FOR #y := 0 TO 5 BY 1 DO        
        #Grün_Speicher[#x,#y] := 0;
        #Rot_Speicher[#x,#y] := 0;
        
       END_FOR;          
     END_FOR;
    END_IF;
    
    // Auswertung ob grüner spieler an der reihe
    IF #wahlschalter_rot = true  THEN
      
    
    // Abfrage für die Veränderung von den Schalters
    #in1:= #IN;
    IF #in1 AND NOT #mem THEN
      #out:= true;
     
      
    IF #eingang_1 = TRUE THEN       
      #x:= 1;        
      ELSIF       
      #eingang_2 = TRUE THEN        
      #x:= 2;        
      ELSIF       
      #eingang_3 = TRUE THEN        
      #x:= 3;        
      ELSIF       
      #eingang_4 = TRUE THEN        
      #x:= 4;        
      ELSIF       
      #eingang_5 = TRUE THEN        
      #x:= 5;        
      ELSIF       
      #eingang_6 = TRUE THEN        
      #x:= 6;        
      ELSIF       
      #eingang_7 = TRUE THEN        
      #x:= 7;
    ELSE #x := 0;  
    END_IF;    
    
    #y:=0;
    #Gefunden:= 0;
    
    WHILE #Gefunden = 0  DO
     IF  #Grün_Speicher[#x,#y] = 0 AND #Rot_Speicher[#x,#y] = 0 THEN
          #Grün_Speicher[#x,#y] := 1;
             #Gefunden:= 1;
        ELSE
          #y:=#y+1;
          IF #y = 5 THEN
            #Gefunden:= 1;
          END_IF;
        END_IF; 
      END_WHILE;
      
    ELSE
      #out:=false;
      
    END_IF;
    
    #mem:=#in1;
    #horizontal:= #x;
    #vertikal := #y;
      
    END_IF;
    
    
     // Auswertung ob roter spieler an der reihe 
       IF #wahlschalter_grün = true   THEN
     
      // Abfrage für die Veränderung von den Schalters
    
      #in1:= #IN;
    IF #in1 AND NOT #mem THEN
      #out:= true;
     
      
    IF #eingang_1 = TRUE THEN       
      #x:= 1;        
      ELSIF       
      #eingang_2 = TRUE THEN        
      #x:= 2;        
      ELSIF       
      #eingang_3 = TRUE THEN        
      #x:= 3;        
      ELSIF       
      #eingang_4 = TRUE THEN        
      #x:= 4;        
      ELSIF       
      #eingang_5 = TRUE THEN        
      #x:= 5;        
      ELSIF       
      #eingang_6 = TRUE THEN        
      #x:= 6;        
      ELSIF       
      #eingang_7 = TRUE THEN        
      #x:= 7;
    ELSE #x := 0;  
    END_IF;    
    
    
    #y:=0;
    #Gefunden:= 0;
    WHILE #Gefunden = 0  DO
        IF #Rot_Speicher[#x,#y] = 0 AND #Grün_Speicher[#x,#y] = 0 THEN
          #Rot_Speicher[#x,#y] := 1;
             #Gefunden:= 1;
        ELSE
          #y:=#y+1;
          IF #y = 5 THEN
            #Gefunden:= 1;
          END_IF;
        END_IF; 
    END_WHILE;
      
      ELSE
      #out:=false;
      
    END_IF;
    
    #mem:=#in1;
    #horizontal:= #x;
    #vertikal := #y;
    
    END_IF;

  5. #5
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 919 Danke für 740 Beiträge

    Standard

    Also erstmal verstehe ich nicht, warum Du zwei Spielfelder anlegst.
    Ich würde nur eins verwenden und der Wert der jeweiligen Adresse zeigt Dir dann an: 0=leer 1=Spieler1 und 2= Spieler2.

    Beim Einwerfen weißt Du ja zum Einen, wer dran ist, und Zum Anderen, welche Spalte er gewählt hat.
    Du gibst also die Spalte vor und fängst mit der Zeile 1 an und arbeitest Dich nach oben, bis Du eine Zelle mit dem Wert 0 findest. Dort trägst Du die Nummer des aktuellen Spielers ein.

    Wichtig ist, Dir diese Zelle für die Auswertung zu merken, denn nur diese Zelle kann den Gewinn des Spiels vollständig gemacht haben. Und auch nur der Spieler, der gerade dran ist, kann gerade gewonnen haben.

    Dann zur Auswertung ->
    1. Spalte:
    Nach oben - ist kein Gewinn möglich, weil leer.
    Nach unten - ist die aktuelle Spaltenadresse noch kleiner als 4, kann dort kein Gewinn stattgefunden haben und die Auswertung somit übersprungen werden. Ansonsten von der aktuellen Zeilenadresse fortlaufend nach unten schauen, ob dort die gleiche Spielernummer eingetragen ist. Wenn nicht, aus der Schleife aussteigen.

    2. Zeile:
    nach links: ist die aktuelle Spaltennummer kleiner 3 - Auswertung überspringen, sonst siehe Spalte (nur nach links schauen)
    nach rechts: ist die aktuelle Spaltennummer größer 4 - Auswertung überspringen, sonst siehe Spalte (nur nach rechts schauen)

    3. Diagonale:
    nach links unten: ...
    nach rechts unten: ...

    Du brauchst also 5 Schleifen, die beginnend an der aktuellen Adresse entweder zum Gewinn führen oder jeweils abgebrochen werden, wenn ein Spielstein des Gegners auftaucht oder das Spielfeld beendet ist.

  6. Folgender Benutzer sagt Danke zu hucki für den nützlichen Beitrag:

    PN/DP (31.10.2013)

  7. #6
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 919 Danke für 740 Beiträge

    Standard

    2. und 3. ist so nicht richtig durchdacht von mir, denn man kann ja auch einen mittleren Stein als letztes einwerfen.
    (Bei der Spalte geht das logischer weise nicht.)

    Ich würd' also bei der Zeile und den beiden Diagonalen jeweils an einem der möglichen Enden anfangen und dann die komplette Reihe prüfen.

  8. #7
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 919 Danke für 740 Beiträge

    Standard

    Zitat Zitat von bkizilkaya Beitrag anzeigen
    Hucki
    Wie würdest du es machen.
    Bis hierhin und dem Test der Spalte ungefähr so:
    Code:
    VAR_INPUT
        EB: BYTE;                                                                       // Eingangsbyte für vertikale Auswahl (Reihe)
        RESET: BOOL;                                                                    // Spielfeld leeren
    END_VAR
    
    VAR_IN_OUT
        SPIELER: BOOL;                                                                  // Spielerauswahl -> 0 = Spieler 1 (ROT), 1 = Spieler 1 (GELB)
                                                                                        // wird intern nach Spielzug umgeschaltet,
                                                                                        // kann extern vorgegeben werden
    END_VAR
    
    VAR
        SPIELFELD: ARRAY [1 .. 7, 1 .. 6] OF INT;                                       // Spielfeld (7 Spalten, 6 Zeilen)
        SPIELZUEGE: ARRAY [1 .. 42, 0 .. 2] OF INT;                                     // Speicher Spielzüge (max. 7 x 6 = 42 Spielzüge,
                                                                                        //                          0 enthält Spalte 
                                                                                        //                          1 enthält Zeile
                                                                                        //                          2 enthält Spieler)
        SPIELZUG_Nr: INT;                                                               // Zähler Spielzüge
        EB_OLD: BYTE;                                                                   // Bytemerker für Eingangsbyte
    END_VAR
    
    VAR_TEMP
        Spielzug: BOOL;                                                                 // Neuen Spielzug versuchen
        Fehler: BOOL;                                                                   // Spielzug korrekt absolviert
        Gewinn: BOOL;                                                                   // Spielzug mit Gewinn absolviert
        Spalte: INT;                                                                    // Index-Variable horizontal (7 Spalten nebeneinander)
        Zeile: INT;                                                                     // Index-Variable vertikal   (6 Zeilen übereinander)
        Folge: INT;                                                                     // Folge gleicher Spielsteine für Gewinnauswertung
    END_VAR
    
    
        // Spielfeld rücksetzen
        IF RESET THEN                                                                   // nur bei Reset ausführen (man könnte
            FOR Zeile:= 1 TO 6 BY 1 DO                                                  // die 6 Zeilen durchlaufen
                FOR Spalte:= 1 TO 7 BY 1 DO                                             // die 7 Spalten durchlaufen
                    SPIELFELD[Spalte, Zeile]:= 0;                                       // Spieler aus Feld löschen
                END_FOR;
            END_FOR;
            FOR SPIELZUG_Nr:= 42 TO 1 BY -1 DO                                          // die maximal möglichen Spielzüge rückwärts durchlaufen
                SPIELZUEGE[SPIELZUG_Nr, 0]:= 0;                                         // Spalte  auf 0 setzen
                SPIELZUEGE[SPIELZUG_Nr, 1]:= 0;                                         // Zeile   auf 0 setzen
                SPIELZUEGE[SPIELZUG_Nr, 2]:= 0;                                         // Spieler auf 0 setzen
            END_FOR;                                                                    // SPIELZUG_Nr ist am Ende auf 1 zurückgesetzt
        END_IF;
        
        // Neuer Spielzug?
        Spielzug:= EB <> EB_OLD;                                                        // Eingangsbyte ungleich dem letzten Zyklus
        EB_OLD:= EB;                                                                    // Eingangsbyte für nächsten Zyklus speichern
    
        // nur bei neuem Spielzug ausführen
        IF Spielzug THEN                                                                // Wenn das Eingansbyte verändert wurde 
    
            // Initialisierung
            Fehler:= true;                                                              // Fehler initialisieren
            Gewinn:= false;                                                             // Gewinn initialisieren
        
            //Spaltenabfrage
            CASE BYTE_TO_INT (EB) OF
                0:      Spalte:= 0;                                                     // keine Spalte gewählt
                1:      Spalte:= 1;                                                     // Spalte 1 definieren
                2:      Spalte:= 2;                                                     // Spalte 2 definieren
                4:      Spalte:= 3;                                                     // Spalte 3 definieren
                8:      Spalte:= 4;                                                     // Spalte 4 definieren
                16:     Spalte:= 5;                                                     // Spalte 5 definieren
                32:     Spalte:= 6;                                                     // Spalte 6 definieren
                64:     Spalte:= 7;                                                     // Spalte 7 definieren
                ELSE:   Spalte:= -1;                                                    // falsche (mehrfache) Auswahl
            END_CASE;
    
            // Leeres Feld suchen
            IF Spalte > 0 THEN                                                          // nur wenn eine (korrekte) Spalte ausgewählt wurde
                // Leere Zeile suchen
                FOR Zeile:= 1 TO 6 BY 1 DO                                              // die 6 Zeilen durchlaufen
                    IF SPIELFELD[Spalte, Zeile] = 0 THEN                                // wenn Spielfeld leer,
                        SPIELFELD[Spalte, Zeile]:= SEL (G:= SPIELER, IN0:= 1, IN1:= 2); // dann Spieler eintragen
                        SPIELZUEGE[SPIELZUG_Nr, 0]:= Spalte;                            //      Spalte  des Spielzuges merken
                        SPIELZUEGE[SPIELZUG_Nr, 1]:= Zeile;                             //      Zeile   des Spielzuges merken
                        SPIELZUEGE[SPIELZUG_Nr, 2]:= SPIELFELD[Spalte, Zeile];          //      Spieler des Spielzuges merken
                        Fehler:= false;                                                 //      Spielzug OK, Fehler rücksetzen
                        EXIT;                                                           //      FOR-Schleife verlassen
                    END_IF;
                END_FOR;
            END_IF;                                                                     
    
            // Spielzug fehlerhaft?
            IF Fehler THEN                                                              // Fehlerauswertung
                ;
            ELSE                                                                        // Gewinnauswertung
    
                //Spalte prüfen
                IF SPIELZUEGE[SPIELZUG_Nr, 1] > 3 THEN
                    Folge := 1;                                                         // Folge gleicher Spielsteine initieren
                    Spalte:= SPIELZUEGE[SPIELZUG_Nr, 0];                                // Spalte des aktuellen Spielzuges auslesen
                    Zeile := SPIELZUEGE[SPIELZUG_Nr, 1];                                // Zeile  des aktuellen Spielzuges auslesen
                    REPEAT
                        Zeile:= Zeile - 1;                                              // letzten Wert für Zeile um eins verringern
                        Folge:= SEL (G:= SPIELFELD[Spalte, Zeile] =                     // Im Spielfeld der
                                        SEL (G:= SPIELER, IN0:= 1, IN1:= 2),            //      gleicher Spieler eingetragen?
                                     IN0:= 0,                                           // nein: Folge gleicher Spielsteine auf 1 rücksetzen
                                     IN1:= Folge + 1);                                  // ja:   Folge Spielsteine um 1 erhöhen
                    UNTIL Folge = 0 OR Folge = 4 OR Zeile = 1                           // Schleife eventuell wiederholen
                    END_REPEAT;
                    Gewinn:= Folge = 4;                                                 // Gewinn setzen, wenn Folge=4
                END_IF;
    
            END_IF;                                                                     // Ende Fehler-/Gewinnprüfung
    
            // automatischer Spielerwechsel
            IF NOT (Fehler OR Gewinn) THEN                                              // korrekter Spielzug ohne Gewinn
                SPIELER:= NOT SPIELER;                                                  // Spieler wechseln
                SPIELZUG_Nr:= SPIELZUG_Nr + 1;                                          // nächster Spielzug
            END_IF;
    
        END_IF;                                                                         // Ende Spielzug
       
    
    
    PS: Ist aber nicht getestet, sondern nur die Umsetzung meiner Gedanken von oben. Die Untersuchung der 3 anderen möglichen Gewinnreihen erfolgt in ähnlicher Weise. Wichtig ist halt den richtigen Startpunkt und die entsprechende Zeilen-/Spaltenweiterschaltung zu finden.


    Bei der Suche nach dem Feld für den aktuellen Zug ist es einfacher, in den Zeilen von unten nach oben nach dem ersten leeren zu suchen.

    Wenn ich jedoch an die Darstellung auf dem Bildschirm denke, wäre es natürlich optisch schöner, den Spielstein wie in real von oben in die Spalte "plumsen" zu lassen, bis es nicht mehr weitergeht. Damit man das auch sehen kann, müsste man das aber zeitlich verzögern, sprich die Leere-Feld-Suche über mehrere Zyklen verteilen. Das wäre dann für mich die Herausforderung bei der Erweiterung.
    Geändert von hucki (01.11.2013 um 17:43 Uhr)

  9. #8
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 919 Danke für 740 Beiträge

    Standard

    @all,
    Zitat Zitat von hucki Beitrag anzeigen
    Code:
    SEL (G:= SPIELER, IN0:= 1, IN1:= 2)
    kann ich z.B. auch durch
    Code:
    BOOL_TO_INT (SPIELER) + 1
    ersetzen.
    Welche Variante ist denn in der Praxis schneller und welche lesbarer?

    Ich glaub', ich würd' mich doch eher für Letzteres entscheiden.

  10. #9
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Danke für deine Antwort

    Ich habe 2 Spielfelder, weil ich eine Visualisierung habe die nicht erkenne kann ob es eine 1 oder 2 ist und sie trotzdem leuchtet.

    Deswegen mit zwei spielfelder.

    gruss

  11. #10
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 919 Danke für 740 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Das kann ich nicht wirklich glauben.

    Ich vermute mal, Du hast es nur nicht entsprechend programmiert, oder?


Ähnliche Themen

  1. TIA Fragen zum code
    Von bkizilkaya im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 21.10.2013, 12:21
  2. Exponent im SCL Code
    Von paula23 im Forum Simatic
    Antworten: 26
    Letzter Beitrag: 08.09.2013, 19:40
  3. Fehlersuche SCL-Code
    Von Sinix im Forum Simatic
    Antworten: 23
    Letzter Beitrag: 12.07.2011, 14:53
  4. Fehler im SCL Code
    Von Felse im Forum Simatic
    Antworten: 15
    Letzter Beitrag: 18.06.2009, 12:33
  5. SCL code
    Von awl-scl im Forum Simatic
    Antworten: 21
    Letzter Beitrag: 14.01.2008, 17:02

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •