Autor |
Beitrag |
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: Di 14.01.14 17:52
Das Programm löst Mattprobleme in n Zügen(n<=9) (17 Halbzüge dauern natürlich )
Einige(46) Aufgaben sind mitgeliefert.
Eine Stellung wird eingegeben durch anklicken der Figur mit anschließendem
Setzen auf dem Brett. Figuren lassen sich mit Rechtsklick löschen,
verschieben ist möglich wenn der D&D-Modus aktiviert ist (Klick aufs Panel).
Ist der Schlüsselzug gefunden, kann dieser per D&D ausgeführt werden,
Schwarz am Zug wird aktiviert, nächste Suche, Zug ausführen,
Weiß ist am Zug, Mattsuche verringern und nächste Suche.
So kann man sich langsam durchackern.
Die meisten Stellungen stammen von
de.wikipedia.org/wiki/Schachkomposition
Zur Programmierung:
// internes SpielFeld
{
110 111 112 113 114 115 116 117 118 119
100 101 102 103 104 105 106 107 108 109
-----------------------------------
090 | 091 092 093 094 095 096 097 098 | 099
080 | 081 082 083 084 085 086 087 088 | 089
070 | 071 072 073 074 075 076 077 078 | 079
060 | 061 062 063 064 065 066 067 068 | 069
050 | 051 052 053 054 055 056 057 058 | 059
040 | 041 042 043 044 045 046 047 048 | 049
030 | 031 032 033 034 035 036 037 038 | 039
020 | 021 022 023 024 025 026 027 028 | 029
-----------------------------------
010 011 012 013 014 015 016 017 018 019
000 001 002 003 004 005 006 007 008 009
}
Es werden alle legalen Zugkombinationen generiert und im letzten Zug geprüft ob Schachmatt.
Es gibt keine Datenbank oder Hashtabelle.
Viel Spaß beim Testen
Fiete
Rev4: Stellungsauswahl und en Passant Wahlmöglichkeit
Rev5: die Stellungen sind nach Zügen sortiert
Einloggen, um Attachments anzusehen!
_________________ Fietes Gesetz: use your brain (THINK)
Zuletzt bearbeitet von Fiete am Fr 14.02.14 18:54, insgesamt 3-mal bearbeitet
Für diesen Beitrag haben gedankt: Mathematiker
|
|
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: Fr 17.01.14 15:53
Rev1: en Passant ist implementiert, weitere Beispiele sind hinzugekommen,
der berechnete Schlüsselzug kann durch anklicken ausgeführt werden.
Die Schachnotation wurde verbessert.
_________________ Fietes Gesetz: use your brain (THINK)
|
|
GuaAck
Beiträge: 378
Erhaltene Danke: 32
Windows 8.1
Delphi 10.4 Comm. Edition
|
Verfasst: Fr 17.01.14 21:21
Hallo Fiete,
hübsches Programm, gut gemacht. Ich habe ein ähnliches Programm vor vielen Jahren gemacht, einige Procedures könnten wir fast austauschen. Somit habe ich Deinen Quellcode auch schnell verstanden.
Und dann habe ich einen Vergleich gemacht:
Zweizüger: Dein Programm war gut schneller.
Fünfzüger: Dein Programm rechnet noch, während ich hier schreibe, meines war nach 1 s fertig. (W: Kc6, Ta7; S: Ke8).
Ich glaube, es ist in dem alpha-beta-Algorithmus ein Denkfehler drin, ganz sicher bin ich mir aber nicht und kann mich auch nicht den ganzen Abend in Deinen Code hinein denken. Man muss ja alpha-beta für jeden Unterbaum anwenden und trotzdem mit dem des TOP-Zuges (jeder Farbe) vergleichen. Mein Code ist diesem Bereich jedenfalls viel umfangreicher, ansonsten haben ich es mit dem rekursiven Aufruf von "SucheZug" ebenso gemacht.
Ist schon eine wirklich interessante Sache!!!
Viel Erfolg weiterhin,
Gruß
GuaAck
P. S.: Schachbrett und Randbuchstaben/Zahlen passen bei mir nicht zueinander, d1 muss weiß sein.
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Sa 18.01.14 10:46
Hallo,
Bei mir braucht Brehmer3 108.4 Sekunden und testet 1298452 Stellungen.
Also 12000 Stellungen pro Sekunde.
Das Programm soll doch nur nach Schachmatt suchen und ist in keinster Weise optimiert.
Sollte es auch nicht, um klar verständlich zu bleiben.
Zum Beispiel:
Delphi-Quelltext 1:
| function TMattsuche.Weiss_im_Schach(Feld:TSpielFeld):Boolean; |
das große Feld wird immer wieder kopiert, obwohl es nicht bearbeitet wird.
Delphi-Quelltext 1:
| function TMattsuche.Weiss_im_Schach(const Feld:TSpielFeld):Boolean; |
bringt nur 20%.
Oder der Zuggenerator, in dem ständig Dinge in Zug eingetragen werden, die dort schon drin sind:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| function NichtErlaubt(i:TFeld;Feld:TSpielFeld):Boolean; begin NichtErlaubt:=(Feld[i].Gestalt=illegal) or (Feld[i].Farbe=Amzug) end;
procedure LaeuferZuege(StartFeld:TFeld;Feld:TSpielFeld;var N:Integer); var j,ZugLaenge,ZielFeld:TFeld; Zug:TSpielZug; begin for J:=1 to 4 do begin ZugLaenge:=1;ZielFeld:=StartFeld+L_Weite[j]*ZugLaenge; while Feld[ZielFeld].Gestalt=Leer do begin Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Amzug; inc(N);ZL[N]:=Zug;inc(ZugLaenge); ZielFeld:=StartFeld+L_Weite[j]*ZugLaenge; end; if not NichtErlaubt(ZielFeld,Feld) then begin Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Amzug; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug end end end; |
Geht auch so :
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| function NichtErlaubt(const a:TFigur):boolean; begin with a do NichtErlaubt := (Farbe=Amzug) OR (Gestalt=illegal); end;
procedure LaeuferZuege(StartFeld:TFeld;const Feld:TSpielFeld;var N:Integer); var j,ZugLaenge,ZielFeld:TFeld; Zug:TSpielZug; begin Zug.von:=StartFeld; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Amzug; Zug.Entferne:=119; for J:=1 to 4 do begin ZugLaenge:=1; repeat ZielFeld:=StartFeld+L_Weite[j]*ZugLaenge; Zug.nach:=ZielFeld; inc(N); ZL[N]:=Zug; inc(ZugLaenge); IF Feld[ZielFeld].Gestalt<> Leer then break; until false; if NichtErlaubt(Feld[Zielfeld]) then dec(N); end end; |
Aber das sind wohl nicht die größten Bremsen.
Ich weiß nicht, ob man den Zuggenerator nicht ändern sollte.Zwischen zwei Zügen ändert sich doch nicht viel und damit auch nicht die Zugmöglichkeiten der anderen Figuren.Das ist natürlich ein großer Aufwand, für jedes Feld, die sie erreichenden Figuren zu speichern.Aber es gibt auch nur 32 (Bit) Figuren.Zudem müsste man bei einer Bewegung dann die neuen Möglichkeiten der betroffenen unbewegten Figuren ermitteln.Eine sich bewegende Dame ist ja enormer Aufwand, ein bewegter Bauer fast keiner.
Lange Rede keinen Sinn, man wüßte sofort ob Schach oder nicht.
Gruß Horst
|
|
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: Sa 18.01.14 12:19
Moin Horst_H,
das Original ist 1992 unter TP4(DOS) entstanden als ich mich mit Strategieprogrammen beschäftigt habe.
Ich wollte keinen großen Aufwand betreiben
Es bleibt viel zu optimieren, für mich war wichtig dass der Schlüsselzug gefunden wurde.
@GuaAck: den alpha-beta-Algorithmus habe ich ohne nachzudenken benutzt, das Programm sollte laufen(jetzt hinkt es wohl )
Gruß Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Sa 18.01.14 12:44
Hallo,
Zitat: | Ich wollte keinen großen Aufwand betreiben |
Lohnt auch nicht "Heute" sind scheinbar 1 Mio/s drin. ( Houdini oder so ähnlich )
Aber es funktioniert.
Gruß Horst
|
|
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: Di 28.01.14 12:42
Moin,
habe den Zuggenerator beschleunigt und Rangecheck deaktiviert.
Die Suche läuft jetzt 5x schneller, natürlich kein Houdini
Gruß Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Di 28.01.14 14:02
Hallo,
ganz erstaunlich :
Jetzt bei mir :
459054 Stellungen in 3,69 sek
zuvor
1298452 Stellungen in 108.4 Sekunden
also nur ein Drittel der Stellungen in 1/30 der Zeit.
Das muss ich mir mal genauer anschauen.
Gruß Horst
Edit:
Die Laufzeiten sind enorm schwankend.Zwischen 3.5 bis über 6.6 Sekunden.
Guttman5 46493500 Stellungen in 170 Sekunden
Ich habe mal Lazarus 1.2RC2 probiert. Mit viel Brimborium zwischen 2.8 ( oft 3.2 ) und 9.9 Sekunden.
Wahrscheinlich sind die Energiespareinstellungen von Windows7 rigoros.
Edit2:
Ich hätte nicht auf Energiesparmodus gehen sollen
Nun 2.32 Sekunden für Brehmer3:-)
Nun habe ich die Version geändert.
Zuerst habe ich Zugliste dieses ständige Zuweisen von VirFeld= Feld eliminiert, indem ich nur den Zug selbst wieder rückgängig mache.Das war dann 1.7 Sekunden.
Jeder mögliche Zug wird darauf getestet, ob man sich ins Schach begibt.
Dabei wird jedes mal der König gesucht.Das muss nicht sein.
Ich merke mir die Position des Königs und schon sind es nur noch 1.2 Sekunden oder besser Guttmann5 in 56 Sekunden < 1 min = für ~46.?? Mio Züge = 821428 Züge pro Sekunde ist schon etwas besser.
Gruß Horst
Zuletzt bearbeitet von Horst_H am Sa 01.02.14 15:40, insgesamt 1-mal bearbeitet
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 29.01.14 22:28
Hallo,
das Programm findet für Stellung Loyd5 keine Lösung. Fiete Rev 2 auch nicht nach 644 Sekunden.
Gibt es da dennoch eine?
Gruß Horst
|
|
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: Do 30.01.14 13:10
Moin Horst,
es gibt eine Lösung: b2-b4, de.wikipedia.org/wiki/Samuel_Loyd
Deine Verbesserungen sind sehr gut, es gibt nichts was man nicht verbessern könnte.
Ich muss noch mal die Bauernzüge und die Bewertung kontrollieren, irgendwo da liegt der Fehler.
Gruß Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 30.01.14 14:15
Hallo,
die Verbesserungen sind ja Quelltextmäßig nur marginal, aber fehlerbehaftet.
Manchmal steht der König doch nicht da, wo er eigentlich bei Machzug gespeichert ist.
Ich habe mal fritz 5.32 installiert ( Win98/me kompatibel eingestellt) der saust mit bis zu 20 Mio Knots/s dahin
GuAcks vorgeschlagener 5-Züger ist ja mit Tastendruck erledigt.
Vielleicht sollte man sich die Stellung der Figuren merken, um eine schon geprüfte Stellung vorzeitig abzubrechen.Sicher kommt in der Zugfolge so was vor: wTurm eins links,sTurm eins rechts,wTurm eins rechts,sTurm eins links, <- kann ab hier wegfallen, da Ausgangsposition. Das lohnt wohl nur ab 3 Zügen aufwärts.
Ich bin gespannt, wie man den Fehler bei Loyd5 finden kann.Einfach anzeigen lassen, wann der Zug b2-b4 gemacht wird?
Jedenfalls ist das Programm besser als fpChess ( nicht mal mit Quellcode ) was kein enpassant kennt und einfach mit dem König ins Schach zieht und den Zug zurücknimmt und nicht weiterspielt. Es scheint auch mehr als GUI für Schachserver geplant gewesen zu sein.
Gruß Horst
|
|
JoelH
Beiträge: 806
Erhaltene Danke: 17
Win10
Delphi Alexandria 11.2 Patch 1
|
Verfasst: Do 30.01.14 16:16
Hi ihr zwei,
der Fehler (ich habe das Programm runter geladen aus dem ersten Posting) liegt am Zuggenerator. Er erzeugt bei der Bauernumwandlung nicht alle Züge wenn die Verwandlung mit einem Schlagzug kombiniert ist.
Also in dieser Lloydstellung erzeugt er b7-b8D, b7-b8T, b7-b8L und b7-b8S aber dann nur noch b7xa8 und in der Zugliste bleibt die Verwandlung unberücksichtigt. Er lässt auf a8 einen Bauern stehen. Das ist zum einen nicht mal legal. Und da dies der letzte Schlüsselzug ist also b7xa8L# bzw. b7xa8D# findet das Programm das Matt nicht.
Anbei die Schlüsselstellung etwas umgebaut (anstatt Schlagzug mit Umwandlung direkt Umwandlung), da findet er das Matt in 1 sofort.
Einloggen, um Attachments anzusehen!
_________________ mfg. Joel
Für diesen Beitrag haben gedankt: Horst_H
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 30.01.14 17:01
Hallo,
das kommt davon, wenn man keine Ahnung vom Schach hat jedenfalls ich nicht.
Mal schauen, ob ich es einfügen kann.
en passant gibt es in der Reihe aber nicht?
Gruß Horst
|
|
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: Do 30.01.14 18:41
Moin Horst,
im Zuggenerator habe ich einiges vergessen, JoelH hat dies gut beschrieben.
Wenn ein Schlagzug in die letzte Reihe erfolgt fehlt die Umwandlung.
Loyd5 wird in 579s mit 127745944 Stellungen gelöst.
die veränderte Prozedure:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203:
| procedure BauernZuege(StartFeld:TFeld;Feld:TSpielFeld;var N:Integer); var ZielFeld:TFeld; Zug:TSpielZug; begin if Amzug=Weiss then begin ZielFeld:=StartFeld+10; if Feld[ZielFeld].Gestalt=Leer then begin Zug.von:=StartFeld;Zug.nach:=ZielFeld; if ZielFeld>90 then begin Zug.Figur.Gestalt:=Dame;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Turm;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Springer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end else begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end; ZielFeld:=StartFeld+20; if (StartFeld<39) and (Feld[ZielFeld].Gestalt=Leer) then begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end; end; ZielFeld:=StartFeld+9; if Feld[ZielFeld].Farbe=Schwarz then begin if ZielFeld>90 then begin Zug.von:=StartFeld;Zug.nach:=ZielFeld; Zug.Figur.Gestalt:=Dame;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Turm;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Springer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end else begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end end; ZielFeld:=StartFeld+11; if Feld[ZielFeld].Farbe=Schwarz then begin if ZielFeld>90 then begin Zug.von:=StartFeld;Zug.nach:=ZielFeld; Zug.Figur.Gestalt:=Dame;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Turm;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Springer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Weiss;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end else begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end end; if StartFeld in[61..68] then begin if (Feld[StartFeld+11].Gestalt=Leer) and (Feld[StartFeld+21].Gestalt=Leer) then begin if (Feld[StartFeld+1].Gestalt=Bauer) and (Feld[StartFeld+1].Farbe=Schwarz) then begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss; Zug.von:=StartFeld;Zug.nach:=StartFeld+11; Zug.Entferne:=StartFeld+1; inc(N);ZL[N]:=Zug end end; if (Feld[StartFeld+9].Gestalt=Leer) and (Feld[StartFeld+19].Gestalt=Leer) then begin if (Feld[StartFeld-1].Gestalt=Bauer) and (Feld[StartFeld-1].Farbe=Schwarz) then begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss; Zug.von:=StartFeld;Zug.nach:=StartFeld+9; Zug.Entferne:=StartFeld-1; inc(N);ZL[N]:=Zug end end; end; end else begin ZielFeld:=StartFeld-10; if Feld[ZielFeld].Gestalt=Leer then begin Zug.von:=StartFeld;Zug.nach:=ZielFeld; if ZielFeld<30 then begin Zug.Figur.Gestalt:=Dame;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Turm;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Springer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end else begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end; ZielFeld:=StartFeld-20; if (StartFeld>80) and (Feld[ZielFeld].Gestalt=Leer) then begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Schwarz; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug end end; ZielFeld:=StartFeld-9; if Feld[ZielFeld].Farbe=Weiss then begin Zug.von:=StartFeld;Zug.nach:=ZielFeld; if ZielFeld<30 then begin Zug.Figur.Gestalt:=Dame;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Turm;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Springer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end else begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Schwarz; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug end; end; ZielFeld:=StartFeld-11; if Feld[ZielFeld].Farbe=Weiss then begin Zug.von:=StartFeld;Zug.nach:=ZielFeld; if ZielFeld<30 then begin Zug.Figur.Gestalt:=Dame;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Turm;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Springer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; Zug.Figur.Gestalt:=Laeufer;Zug.Figur.Farbe:=Schwarz;Zug.Entferne:=119; inc(N);ZL[N]:=Zug; end else begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Schwarz; Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119; inc(N);ZL[N]:=Zug end; end; if StartFeld in[51..58] then begin if (Feld[StartFeld-11].Gestalt=Leer) and (Feld[StartFeld-21].Gestalt=Leer) then begin if (Feld[StartFeld-1].Gestalt=Bauer) and (Feld[StartFeld-1].Farbe=Weiss) then begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Schwarz; Zug.von:=StartFeld;Zug.nach:=StartFeld-11; Zug.Entferne:=StartFeld-1; inc(N);ZL[N]:=Zug end end; if (Feld[StartFeld-9].Gestalt=Leer) and (Feld[StartFeld-19].Gestalt=Leer) then begin if (Feld[StartFeld+1].Gestalt=Bauer) and (Feld[StartFeld+1].Farbe=Weiss) then begin Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Schwarz; Zug.von:=StartFeld;Zug.nach:=StartFeld-9; Zug.Entferne:=StartFeld+1; inc(N);ZL[N]:=Zug end end; end; end end; |
Gruß Fiete
_________________ Fietes Gesetz: use your brain (THINK)
Zuletzt bearbeitet von Fiete am So 02.02.14 14:32, insgesamt 1-mal bearbeitet
Für diesen Beitrag haben gedankt: Horst_H
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 30.01.14 21:28
Hallo,
ich wußte, dass Bauernbehandlungsroutine viel Zeit frißt: viele Bauern, kuriose Zugmöglichkeiten.
Aber statt 1.21s für Brehmer3 nun 2.68s ist doch etwas happig
Müßte man die komplette Zugfolge nicht in SucheZug in einem Feld speichern können und nicht nur den BestZug,also in einem Feld Zugfolge[ 0..Maxtiefe, TSpieler] of tZug;
Etwa so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TMattsuche.SucheZug ... ..PosKoenige := tmpPosKoenige; .... if M < AlphaBeta then begin M := AlphaBeta; ZugFolge[N,Amzug] := Zug if N = Tiefe then BestZug := Zug; end; .. |
Gruß Horst
Das Feld Zugfolge funktioniert wohl nicht. Jetzt wird der Zug gefunden, durch eine Korrektur meiner Bauernumwandlung.
Ich hatte vergessen nach der ganzen Umwandlerei zum Schluß wieder einen Bauern aus der Figur zu machen, damit die nachfolgenden Tests nicht plötzlich mit einem Lauefer durchgeführt werden, zudem musste auch bei enpassant wieder auf entferne wieder auf 119 gesetzt werden.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| procedure BauernZuege(StartFeld: TFeld; const Feld: TSpielFeld); var ZielFeld: TFeld;
procedure Bauernumwandlung; begin with gblZug do begin Inc(ZugNr);Figur.Gestalt := Dame;ZL[ZugNr] := gblZug; Inc(ZugNr);Figur.Gestalt := Turm;ZL[ZugNr] := gblZug; Inc(ZugNr);Figur.Gestalt := Springer;ZL[ZugNr] := gblZug; Inc(ZugNr);Figur.Gestalt := Laeufer;ZL[ZugNr] := gblZug; Figur.Gestalt := Bauer; end; end;
begin with gblZug do begin von := StartFeld; Entferne := 119; with Figur do begin Gestalt := Bauer; Farbe := Amzug; end; end;
if Amzug = Weiss then ... |
I
|
|
JoelH
Beiträge: 806
Erhaltene Danke: 17
Win10
Delphi Alexandria 11.2 Patch 1
|
Verfasst: Fr 31.01.14 01:26
Horst_H hat folgendes geschrieben : | Hallo,
ich wußte, dass Bauernbehandlungsroutine viel Zeit frißt: viele Bauern, kuriose Zugmöglichkeiten.
Aber statt 1.21s für Brehmer3 nun 2.68s ist doch etwas happig
|
Die Zeit frisst die Suche, nicht die Zugerzeugung! In diesem Fall ist es natürlich ein wenig anders, da das Programm ja quasi auf Matt getrimt ist und dazu noch die Zugzahl mitgegeben bekommt. Aber andernfalls ist die Suchoptimierung deutlich der Zuggenerierung zu bevorzugen!
Horst_H hat folgendes geschrieben : |
Müßte man die komplette Zugfolge nicht in SucheZug in einem Feld speichern können und nicht nur den BestZug,also in einem Feld Zugfolge[ 0..Maxtiefe, TSpieler] of tZug;
|
Dazu empfehle ich
chessprogramming.wikispaces.com
alleine die Bitboarddarstellungen und Züge via Bitshifting sind grandios (schnell)! bzw. darum ist Houdini 100x schneller als wir.
PS: Interesanterweise habe ich ein Spiel geschrieben das ähnlich wie Schach ist. Ich bekomme aber auch hier nicht signifikant mehr Knoten bewertet. Obwohl die Regeln anders sind, aber die Suche ist AlphaBeta und die Suche bringt ca. 100.000 Züge in der Sekunde zustande. Sprich, es liegt nicht an der Generierung, somdern an der Suche.
_________________ mfg. Joel
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Fr 31.01.14 10:00
Hallo,
don't overdo it, nichts übertreiben
Mir ging es nur darum, mit minimalen Änderungen die Geschwindigkeit zu steigern und nicht das komplette Prinzip des Datenaufbaus zu ändern.
Natürlich wäre es erheblich schneller mit Bitboards Stellungen zu überprüfen, am besten auf einem 64-Bit Betriebssystem.
Wenn Fiete daran Spaß findet, kann er das sicher zügig mit Int64 umsetzen.
Gruß Horst
Zuletzt bearbeitet von Horst_H am Di 11.02.14 09:46, insgesamt 1-mal bearbeitet
Für diesen Beitrag haben gedankt: Mathematiker
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: So 02.02.14 17:07
Hallo,
was ist an der Stellung Albrecht2 so schwer, das nichts gefunden wird?
Als Dreizüger gerechnet kommt das naheliegende wBauer d5-d6+
Ich sehe nicht, wie man den König über 3 Züge retten kann :confused:
Da wäre es schön, wenn man die Zugfolgen ausgeben könnte.Aber wie in SucheZug speichern.
Gruß Horst
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: So 02.02.14 17:27
Hallo,
Horst_H hat folgendes geschrieben : | was ist an der Stellung Albrecht2 so schwer, das nichts gefunden wird?
Als Dreizüger gerechnet kommt das naheliegende wBauer d5-d6+
Ich sehe nicht, wie man den König über 3 Züge retten kann :confused: |
Es ist ein zweizügiges Matt. Der korrekte Zug ist Dg7-e7. Allerdings findet das Programm den Zug nicht.
Das Problem EnPassant3 ist nicht ganz korrekt. Damit ein Programm erkennt, dass es den b5-Bauern schlagen kann, müsste ihm mitgeteilt werden, dass der letzte schwarze Zug b7-b5 ist. Ich frage mich, wo die versteckte Information ist oder genügt schon der Dateiname?
Kennt man den letzten schwarzen Zug dagegen nicht, ist das Problem ein 4-Züger mit der Lösung Sc8-b6.
Ähnliches gilt für EnPassant1.
Auch EnPassant2 funktioniert ohne Zusatzinformation nicht. Die Lösung Kd5-d6 ist nur dann richtig, wenn man sicher weiß, dass Schwarz König und Turm schon gezogen hat. Andernfalls kann Schwarz mit der Rochade 0-0 antworten und entgeht dem zweizügigen Matt.
Beste Grüße
Mathematiker
|
|
Fiete
Beiträge: 611
Erhaltene Danke: 347
W7
Delphi 6 pro
|
Verfasst: So 02.02.14 19:37
Moin Horst,
In der Stellung Albrecht2 gibt es eine Lösung wenn die e.p. Züge nicht berücksichtigt werden. Eine Checkbox wäre die Lösung. Den letzten schwarzen Zug kann man natürlich nur vermuten(s.Mathematiker).
Deine neue Version ist schön schnell
Gruß Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
|