Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Problem mit verschachtelter Schleife

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Asmodis



Anmeldungsdatum: 16.04.2018
Beiträge: 2

BeitragVerfasst am: 16.04.2018, 20:09    Titel: Problem mit verschachtelter Schleife Antworten mit Zitat

Hallo erstmal

Ich bin gerade dabei ein Schachprogramm das ursprünglich mal in einer alten Zeilenbasic-Version (ich glaube es war ein 64er, bin aber nicht sicher) geschrieben wurde in Freebasic umzuschreiben. Bei den meisten Routinen war es kein Problem (wenngleich man bei so manchem Code ganz schön umdenken musste).

Nun habe ich aber einen Codeteil, bei dem ich irgendwie ein Brett vorm Kopf habe. Es geht um folgende Zeilen:

Code:
3100 REM MATTSETZEN DES SCHWARZEN KOENIGS
3102 A2% = INT(Figurenliste%(1, 1) / 12): A1% = Figurenliste%(1, 1) - 12 * A2%
3104 A9% = INT(Figurenliste%(2, 1) / 12): A8% = Figurenliste%(2, 1) - 12 * A9%
3106 REM ZENTRALISIERUNG DES SCHWARZEN KOENIGS
3108 HW% = 94 * (ABS(6.5 - A8%) + ABS(5.5 - A9%))
3110 REM ABSTAND VON KOENIG UND SPRINGERN (WEISS) ZUM SCHWARZEN KOENIG
3112 A3% = 2
3114 A5% = ABS(A1% - A8%): A6% = ABS(A2% - A9%)
3116 HW% = HW% + 16 * (14 - (A5% + A6%))
3118 FOR I = A3% TO Figurenzahl%(1)
3120 IF Figurenliste%(1, I) <> weissspringer% THEN GOTO 3128
3122 A3% = I + 1
3124 A2% = INT(Figurenliste%(1, I) / 12): A1% = Figurenliste%(1, I) - 12 * A2%
3126 GOTO 3114
3128 NEXT I
3130 REM GESAMTBEWERTUNG DER STELLUNG
3132 Positionswert% = Materialbalance% + INT(HW% / 10)
3134 RETURN


Letztlich wird hier in Zeile 3112 ein Startwert (A3%=2) für eine Schleife gesetzt, die in Zeile 3114 beginnt und mit Zeile 3126 endet (Rücksprung nach 3114). Die Schleife wird letztlich nur in der Zeile 3120 mit der Bedingung hinter IF verlassen.

Normalerweise kein Problem. In Freebasic würde ich nach der Zuweisung in Zeile 3112 normalerweise eine unendliche DO...LOOP Schleife machen, das Goto 3128 in Zeile 3120 durch sowas wie "Exit Loop" oder "Continue For" ersetzen und alles wäre gut, wenn... ja wenn der Befehl NEXT I nicht wäre.

Die einzig mögliche Abbruchbedingung befindet sich in der FOR...NEXT-Schleife und der NEXT-Befehl befindet sich außerhalb der LOOP. Da aber Do...Loop einen Scope-Block erzeugt, dürfte die Variable I vermutlich außerhalb der Loop nicht bekannt sein.

Verwende ich jetzt "Exit Loop" dann springt das Programm zu einem Next Befehl der zu einem For innerhalb der Loop gehört. Und die zum For gehörende Variable I ist außerhalb der Loop ja nicht bekannt. Das kann nach meinem Verständnis nur schiefgehen.

Verwende ich hingegen "Continue For" dann weiss ich ehrlich gesagt nicht, ob das so gehen kann, da der Next-Befehl ja außerhalb der Loop liegt. Wird dieses Next dann überhaupt gefunden oder wird einfach nur die Laufvariable um 1 erhöhrt und die For-Schleife geht einfach weiter? In diesem Fall hänge ich dann auf ewig in der Loop fest.

Hat jemand eine Ahnung, wie ich das hinkriegen kann? Wie gesagt, im Moment schwirrt mir da gerade der Kopf...

Ein Ansatz war:

Code:
PUBLIC SUB Mattgegenschwarz ()
     A2% = INT(Figurenliste%(1, 1) / 12)
     A1% = Figurenliste%(1, 1) - 12 * A2%
     A9% = INT(Figurenliste%(2, 1) / 12)
     A8% = Figurenliste%(2, 1) - 12 * A9%
     REM Zentralisierung des schwarzen Koenigs
     HW% = 94 * (ABS(6.5 - A8%) + ABS(5.5 - A9%)
     REM ABSTAND VON KOENIG UND SPRINGERN (WEISS) ZUM SCHWARZEN KOENIG
     A3% = 2
     DO
          A5% = ABS(A1% - A8%): A6% = ABS(A2% - A9%)
          HW% = HW% + 16 * (14 - (A5% + A6%))
          FOR I = A3% TO Figurenzahl%(1)
               IF Figurenliste%(1, I) <> weissspringer% THEN
                    CONTINUE FOR
               End IF
               A3% = I + 1
               A2% = INT(Figurenliste%(1, I) / 12)
               A1% = Figurenliste%(1, I) - 12 * A2%
     LOOP
          NEXT I
     REM GESAMTBEWERTUNG DER STELLUNG
     Positionswert% = Materialbalance% + INT(HW% / 10)
END Sub


Aber ob das so funktionieren kann? Keine Ahnung.

Achsoja... Ich weiss natürlich dass man sowas wie GOTO auch in FreeBasic machen kann, aber den schlechten Stil will ich mir gar nicht erst wieder angewöhnen... lach.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4214
Wohnort: ~/

BeitragVerfasst am: 16.04.2018, 22:50    Titel: Antworten mit Zitat

Die Verschachtelung von DO und FOR funktioniert so nicht - Die FOR-Schleife muss entweder komplett innerhalb der DO-Schleife liegen oder umgekehrt. Das hier sollte tun was du willst:
Code:
' MATTSETZEN DES SCHWARZEN KOENIGS
A2 = INT(Figurenliste(1, 1) / 12)
A1 = Figurenliste(1, 1) - 12 * A2
A9 = INT(Figurenliste(2, 1) / 12)
A8 = Figurenliste(2, 1) - 12 * A9

' ZENTRALISIERUNG DES SCHWARZEN KOENIGS
HW = 94 * (ABS(6.5 - A8) + ABS(5.5 - A9))

' ABSTAND VON KOENIG UND SPRINGERN (WEISS) ZUM SCHWARZEN KOENIG
A3 = 2

DO
  A5 = ABS(A1 - A8)
  A6 = ABS(A2 - A9)
  HW = HW + 16 * (14 - (A5 + A6))
  FOR I = A3 TO Figurenzahl(1)
    IF Figurenliste(1, I) <> weissspringer THEN CONTINUE FOR
    A3 = I + 1
    A2 = INT(Figurenliste(1, I) / 12)
    A1 = Figurenliste(1, I) - 12 * A2
    CONTINUE DO
  NEXT I
  EXIT DO
LOOP

' REM GESAMTBEWERTUNG DER STELLUNG
Positionswert = Materialbalance + INT(HW / 10)

(jetzt mal abgesehen von Variablendeklarationen - sind die SHARED?)

Und ansonsten - wenn du innerhalb der Schleife eine Zählvariable verwenden willst, die außerhalb ebenfalls sichtbar ist, brauchst du sie ja nur außerhalb zu deklarieren (und innerhalb dann entsprechend nicht mehr). In FreeBASIC musst du sowieso jede Variable explizit deklarieren.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Asmodis



Anmeldungsdatum: 16.04.2018
Beiträge: 2

BeitragVerfasst am: 17.04.2018, 00:31    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:
Die Verschachtelung von DO und FOR funktioniert so nicht - Die FOR-Schleife muss entweder komplett innerhalb der DO-Schleife liegen oder umgekehrt. Das hier sollte tun was du willst:

...

(jetzt mal abgesehen von Variablendeklarationen - sind die SHARED?)

Und ansonsten - wenn du innerhalb der Schleife eine Zählvariable verwenden willst, die außerhalb ebenfalls sichtbar ist, brauchst du sie ja nur außerhalb zu deklarieren (und innerhalb dann entsprechend nicht mehr). In FreeBASIC musst du sowieso jede Variable explizit deklarieren.


Erstmal danke dass Du Dir die Mühe gemacht hast, meinen Code so umzustellen dass die Sache funktioniert.

Klar, alle Variablen sind explizit deklariert und alles ist auch SHARED, damit ich mir bei den Subs die Variablenübergaben erstmal spare. Mir geht es in erster Linie darum den vorhandenen Zeilenbasic-Code in Freebasic umzuwandeln und dabei so nahe wie möglich am Originalcode zu bleiben. Einzig die Befehle Goto und Gosub sollten natürlich verschwinden (wie gesagt, ich will mir schlechten Stil gar nicht erst angewöhnen).

Wenn nach der Umsetzung dann alles ordnungsgemäß läuft geht es erstmal an die Optimierungen, also eventuell dann keine SHARED Deklarationen mehr, dafür anständige Variablenübergaben und eventuell eine effektivere Gestaltung des Codes insgesamt.

Das Projekt als solches soll für unser Schachcomputerforum sein. Leider gibt es gute Bücher zum Thema nur aus Zeiten, als man noch auf einem C-64 in Basic rumgehämmert hat, wobei die Bücher und der Code sehr gut erklärt sind, aber halt leider mit Steinzeitbasic. Aktuelle Literatur für ein gut erklärtes Demoprogramm ist kaum zu finden, zumindest nicht auf Deutsch. Und daher machen ich und ein paar andere das eben derzeit selber, wobei ich zwar einigermaßen QuickBasic kenne, mit FreeBasic aber noch nicht so viel zu tun hatte. Daher ist es auch für mich eine Gelegenheit mich da reinzufinden und meine Kenntnisse aufzufrischen. Und wo geht das besser als mit einem Thema dass mir auch Spaß macht lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
RockTheSchock



Anmeldungsdatum: 04.04.2007
Beiträge: 133

BeitragVerfasst am: 24.04.2018, 02:27    Titel: Prozeduren Antworten mit Zitat

Zitat:
Wenn nach der Umsetzung dann alles ordnungsgemäß läuft geht es erstmal an die Optimierungen, also eventuell dann keine SHARED Deklarationen mehr, dafür anständige Variablenübergaben und eventuell eine effektivere Gestaltung des Codes insgesamt.


Gerade bei Schachprogrammen bieten sich Prozeduren an. Damit kannst du sehr einfach alles übersichtlicher gestalten und auch deutlich abkürzen.

Z.B. kannst du eine Prozedur zur Erzeugung der Damenzüge übersichtlicher gestalten. Selbst wenn du shared Variablen verwendest ist es schöner, Code in Prozeduren zu packen und wiederzuverwenden:

Code:

'...
Dim Shared stellung as Position
Dim Shared schachs as Zugliste
Dim Shared schlagzuege as Zugliste
Dim Shared anderezuege as Zugliste
Dim Shared farbe as Integer
'...
Sub DamenZuege(f as Feld)
   LaeuferZuege  f
   TurmZuege f
End Sub
'...
Sub GeneriereZuege()
Dim f As Feld
   For i as Integer=0 to 63
      f = stellung.feld(i)
      if f.farbe And farbe then
         If f And BAUER then
            Bauernzuege f
         Else If f And SPRINGER Then
            Springerzuege f
         Else If f And LAUFER Then
            Laeuferzuege f
         Else If f And TURM Then
            Turmzuege f
         Else If f And DAME Then
            DamenZuege f
         Else Iff And KOENIG Then
            KoenigsZuege f
         End If
      End if
   next
End Sub


Es ist schon lange her c.a. 2005. Da habe ich mal versucht ein Schachprogramm in VisualBasic zu schreiben. Ich hatte damals alle Regeln außer der 50 Züge Regel umgesetzt, wenn ich mich Recht erinnere.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
tom_dehn



Anmeldungsdatum: 05.10.2015
Beiträge: 30

BeitragVerfasst am: 24.04.2018, 11:00    Titel: Re: Prozeduren Antworten mit Zitat

[quote="RockTheSchock"][quote]
(...)
Else If f And DAME Then
DamenZuege f
Else Iff And KOENIG Then
KoenigsZuege f
End If
End if
[/code]

Kann sein das Shreibfehller?
Tom
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz