![Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht](misc/logos/logo.png) |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Asmodis
Anmeldungsdatum: 16.04.2018 Beiträge: 2
|
Verfasst am: 16.04.2018, 20:09 Titel: Problem mit verschachtelter Schleife |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
nemored
![](images/avatars/18585278245ddb8b9d8710.png)
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 16.04.2018, 22:50 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Asmodis
Anmeldungsdatum: 16.04.2018 Beiträge: 2
|
Verfasst am: 17.04.2018, 00:31 Titel: |
|
|
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](images/smiles/icon_smile.gif) |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 24.04.2018, 02:27 Titel: Prozeduren |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 24.04.2018, 11:00 Titel: Re: Prozeduren |
|
|
[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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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.
|
|