Autor Beitrag
Fiete
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: Di 14.01.14 17:52 
Das Programm löst Mattprobleme in n Zügen(n<=9) (17 Halbzüge dauern natürlich :wink: )
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

user defined image

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 376
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
function TMattsuche.Weiss_im_Schach(Feld:TSpielFeld):Boolean;					

das große Feld wird immer wieder kopiert, obwohl es nicht bearbeitet wird.
ausblenden 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:
ausblenden 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 :
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: 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 :wink:
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 :roll: )

Gruß Fiete

_________________
Fietes Gesetz: use your brain (THINK)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: 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 :wink:
user defined image
Gruß Fiete

_________________
Fietes Gesetz: use your brain (THINK)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 28.01.14 14:02 
Hallo,

ganz erstaunlich :zustimm: :
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 806
Erhaltene Danke: 17

Win10
Delphi Alexandria 11.2 Patch 1
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: 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:

ausblenden volle Höhe 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:
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 // Bauernumwandlung
          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<39and (Feld[ZielFeld].Gestalt=Leer) then
          begin
           Zug.Figur.Gestalt:=Bauer;Zug.Figur.Farbe:=Weiss; // zwei Felder vor
           Zug.von:=StartFeld;Zug.nach:=ZielFeld;Zug.Entferne:=119;
           inc(N);ZL[N]:=Zug;
          end;
        end;
       ZielFeld:=StartFeld+9// eventuell schlagen
       if Feld[ZielFeld].Farbe=Schwarz then
        begin
         if ZielFeld>90 then // Bauernumwandlung
          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// eventuell schlagen
       if Feld[ZielFeld].Farbe=Schwarz then
        begin
         if ZielFeld>90 then // Bauernumwandlung
          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;
       // en passant
       if StartFeld in[61..68then
        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 // Schwarz am Zug
      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>80and (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 // hatte ich vergessen
        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;
              // en passant
       if StartFeld in[51..58then
        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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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:
ausblenden 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.
ausblenden volle Höhe 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:
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;
        // Muss wieder Bauer sein
        Figur.Gestalt := Bauer;
      end;
    end;

  begin
    // Erstmal die Standartbelegung
    with gblZug do
    begin
      von := StartFeld;
      Entferne := 119;
      with Figur do
      begin
        Gestalt := Bauer;// Ist es eigentlich sowieso
        Farbe := Amzug;
      end;
    end;

    if Amzug = Weiss then
...


I
JoelH
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 806
Erhaltene Danke: 17

Win10
Delphi Alexandria 11.2 Patch 1
BeitragVerfasst: Fr 31.01.14 01:26 
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
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!

user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 02.02.14 17:27 
Hallo,
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: 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 :zustimm:
Gruß Fiete

_________________
Fietes Gesetz: use your brain (THINK)