| 
| Autor | Beitrag |  
| gerd8888  
          Beiträge: 205
 Erhaltene Danke: 3
 
 Win7
 Delphi 10.1 Starter (kostenlos)  Lazarus
 
 | 
Verfasst: Mi 14.09.16 19:00 
 
Jetzt habe ich die Masken in einem array gespeichert und greife direkt zu. Ist etwas schneller.
 Ich habe schon mal ein Schachprogramm geschrieben mit einer brett[1..64] of shortint. 
 Ich habe die beiden Schachprogramme verglichen (nur mit Königen) und da ist immer noch mein altes Programm schneller.
 Wahrscheinlich benoetigt die Schachabfrage viel Zeit. Hier mal die procedure
 												| 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:
 
 | function Bittest (TestZahl : int64;Bitnr: byte):boolean;begin
 
 Result := (testzahl and (Int64(1) shl bitnr)) <> 0;
 end;
 
 
 function sK_im_schach:boolean;
 var a,b,c,d:byte;
 h,schach:boolean;
 begin
 schach:=false;
 for a:=0 to 63 do begin
 if schach=false then
 if bittest(sk,a) then begin
 for b:=1 to 4 do begin
 if schach=false then
 if t_anz[b,a]<>0 then begin
 for c:=1 to t_anz[b,a] do begin
 
 h:=true;
 if bittest(st,t_wege[b,a].zahlen[c]) then begin
 h:=false;
 end;
 if h then begin
 if bittest(wk,t_wege[b,a].zahlen[c]) then begin
 h:=false;
 end;
 if h then begin
 if bittest(wt,t_wege[b,a].zahlen[c]) then begin
 schach:=true;
 h:=false;
 end;
 end;
 end;
 if h=false then break;
 end;
 end;
 end;
 end;
 end;
 if schach then result:=true else result:=false;
 end;
 |  Ich gehe vom König weg und schaue ob da eine Figur steht. Hier sogar nur die T-Züge. Das braucht ziemlich viel Zeit... |  |  |  
| JoelH 
          Beiträge: 806
 Erhaltene Danke: 17
 
 Win10
 Delphi Alexandria 11.2 Patch 1
 
 | 
Verfasst: Do 15.09.16 09:14 
 
Hilfreich sind Variablen die auch etwas aussagen. In deiner Varianten ist der Code mühsam zu entziffern. 
 Sehe ich das richtig, dass du jedes mal über das gesamte Brett gehst um den König zu suchen? Das ist ja mal der absoluten Speedkiller. Wenn es ungünstig läuft benötigst du bei 10.000.000 Stellungen 640.000.000 Iterationen, von denen 630.000.000 überflüssig sind wenn du einfach eine Figurenliste mit führst, die dir zur jeweiligen Stellung die Position des Königs zurück gibt.
 _________________ mfg. Joel
 
 Zuletzt bearbeitet von JoelH am Do 15.09.16 09:16, insgesamt 1-mal bearbeitet
 |  |  |  
| gerd8888  
          Beiträge: 205
 Erhaltene Danke: 3
 
 Win7
 Delphi 10.1 Starter (kostenlos)  Lazarus
 
 | 
Verfasst: Do 15.09.16 11:04 
 
Das stimmt. Das habe ich übrigens noch selbst herausgefunden, dass es besser ist den weissen König und den schwarzen König einfach in ein byte abzuspeichern. Dann habe ich festgestellt, dass ich das auf das bitboard bei königen ganz verzichten kann. Nur bei Königen speichere ich das anders ab, wegen der Schachabfrage.
(Normalerweise habe ich aussagekraeftige Variablen gewaehlt. Nur bei der Schachabfrage waren es alles Schleifen und da habe ich keinen Sinn gesehen)
 |  |  |  
| gerd8888  
          Beiträge: 205
 Erhaltene Danke: 3
 
 Win7
 Delphi 10.1 Starter (kostenlos)  Lazarus
 
 | 
Verfasst: Do 15.09.16 18:11 
 
Habe mir heute mal das sog. magic-bitboard angesehen. 
Die Grundidee ist einfach. Z.B. beim Turm in der Mitte, wird eine Maske (die schon erzeugt wurde und nur noch aufgerufen werden muss) mit der
 bitboard_gesamte_steine xor maske (siehe unten)
 
 00010000
 00010000
 00010000
 00010000
 11101111
 00010000
 00010000
 00010000
 
 Somit spart man sich, wenn man vom König alle Richtungen durchsucht, die Leerfeldabfrage.
 Hast Du das in Deinem Atomschach auch eingebaut?
 |  |  |  
| JoelH 
          Beiträge: 806
 Erhaltene Danke: 17
 
 Win10
 Delphi Alexandria 11.2 Patch 1
 
 | 
Verfasst: Fr 16.09.16 07:20 
 
Nein, habe ich nicht. Ich arbeite ganz oldschool mit Figurentabelle und 10*12 Board. Wie ich schon weiter oben schrieb, mein Hauptaugenmerk legte ich ganz traditionell (ganz vom eigenen Ego getrieben) auf die Stellungsbewertung und nicht auf den Zuggenerator, Oldschool eben. 
 Heute geht es ja fast nur noch um schnelle Zuggeneration und nur noch rudimentäre Stellungsbewertung mit Hauptaugenmerk auf die perfekte Zugsortierung um sehr gute Alpha/Beta Cuts zu bekommen. Das war aber nicht meine Motivation hinter dem Projekt. Mein Ziel war es zunächst einfach nur ein Programm zu schreiben welches mich schlagen kann. Das ging allerdings recht einfach, obwohl ich jetzt gar kein so schlechter Atomicschachler bin. Danach hab ich es eine Weile auf einem Schachserver spielen lassen, mit überraschend guten Ergebnissen. Ich schätze das Programm auf etwa 1800 Schachserver-ELO aber es hat einen Wert von knapp 2500 erreicht. Im weiteren Verlauf habe ich dann immer mehr Ideen zur Stellungsbewertung eingefügt um zu schauen ob meine Ideen auch so funktionieren wie ich mir es vorstelle oder ob ich total daneben liege. 
 Einige Anekdoten dazu findest du in meinem Blog zum Projekt. Da siehst du aber auch, dass ich seit mehr als einem Jahr nichts mehr daran gemacht haben. 
joelh.de/atomystica/?lang=de_________________ mfg. Joel
 |  |  |  
| gerd8888  
          Beiträge: 205
 Erhaltene Danke: 3
 
 Win7
 Delphi 10.1 Starter (kostenlos)  Lazarus
 
 | 
Verfasst: Fr 16.09.16 16:35 
 
JoelH, habe mir Deine Seite angesehen. Mit welchen Spielregeln spielst Du Dein Atomschach. Darf der König direkt geschlagen werden. Oder wird er nur mattgesetzt, wenn er durch eine Explosion vom Brett verschwindet. Da ich an Kunstschach interessiert bin, würde mich interessieren, ob es auch einfache Mattprobleme, wie Matt in 3 Zügen gibt. 
 Jetzt habe ich mich nochmal mit den magic Bitboards beschaeftigt.
 
 00001000
 00001000
 00001000
 11110111
 00001000
 00001000
 00001000
 00001000
 (1 Maske, auf e5 steht ein wT )
 
 
 00000000
 00000000
 00000000
 00101000
 00000000
 00000000
 00000000
 00000000
 (2 Ausgangsstellung)
 
 Maske xor Ausgangstellung
 
 00001000
 00001000
 00001000
 11010111
 00001000
 00001000
 00001000
 00000000
 (3 Attakierten Felder des Turms)
 
 Die Felder a5 und b5 sind auch attakiert. Aber auf dem Feld c5 ist ein
 
 Block.
 
 Es soll nun als Ergebnis das hier herauskommen:
 
 00001000
 00001000
 00001000
 00010111
 00001000
 00001000
 00001000
 00000000
 (4 wirklich attakierten Felder des Turms)
 
 Jetzt ist a5 und b5 nicht blockiert.
 Nun koennte man ein Lookup von Dia 3 und vielen weiteren Stellungen
 erstellen. Das Problem ist nun, dass es hier sehr viele Moeglichkeiten
 gibt. Verringert soll das durch ein "magic bitboard" Maske werden.
 Kann mir das einer erklären, wie das funktionieren soll?
 |  |  |  
| gerd8888  
          Beiträge: 205
 Erhaltene Danke: 3
 
 Win7
 Delphi 10.1 Starter (kostenlos)  Lazarus
 
 | 
Verfasst: Fr 16.09.16 21:06 
 
Das Prinzip habe ich verstanden. Die magic Maske soll praktisch die untenere Maske mit Buchstaben in einer Reihenfolge bringen
 00000000
 0000B000
 0000A000
 0EDC1FG0
 0000H000
 0000I000
 0000J000
 00000000
 
 
 Dann hat man wieder eine Zahl
 BADECIJH
 
 Dann wandelt es die Zahlen in einem Lookup um
 
 Danach macht man alles rueckgaenig und hat das fertige Ergebnis.
 
 Nur ueber eine Kleinigkeit raetsel ich noch.
 Warum sind die ganz aeusseren Felder der Maske nicht besetzt.
 Ich kann doch nicht automatisch einen Rückschluss machen, dass wenn e7 attackiert ist auch e8 attackiert ist, denn wenn auf e7 eine schwarze Figur steht und geschlagen wird, dann ist eben e8 nicht attackiert.
 
 Wer hilft mir jetzt die magischen Zahlen herauszufinden. Wie funktioniert diese Art der Bitmanipulation eigentlich?
 |  |  |  
| JoelH 
          Beiträge: 806
 Erhaltene Danke: 17
 
 Win10
 Delphi Alexandria 11.2 Patch 1
 
 | 
Verfasst: So 18.09.16 11:32 
 
	  |  gerd8888 hat folgendes geschrieben  : |  	  | JoelH, habe mir Deine Seite angesehen. Mit welchen Spielregeln spielst Du Dein Atomschach. Darf der König direkt geschlagen werden. Oder wird er nur mattgesetzt, wenn er durch eine Explosion vom Brett verschwindet. Da ich an Kunstschach interessiert bin, würde mich interessieren, ob es auch einfache Mattprobleme, wie Matt in 3 Zügen gibt. 
 | 
 Es wird nach den Regeln gespielt die hier hinterlegt sind. 
www.unix-ag.uni-kl.de/~chess/atomic/ Der König wird nicht geschlagen sondern geht ganz normal Matt oder er wird indirekt gesprengt, wenn eine eigenen Figur direkt daneben geschlagen wird. Das normale Matt ist dabei von einer einzelnen Dame herbeiführbar in der Ecke. wDb2 sKa1 ist Matt da ein König im Atomic nicht schlagen darf. 
 Alle anderen Regeln des normalen Schachs gelten weiterhin. Also es ist auch Patt möglich. 
 Hier gibt es eine tolle Seite über Atomic
www.nicklong.net/chess/atomic/  da gibt es auch eine Mattaufgaben zu finden www.nicklong.net/chess/atomic/puzzles.htm_________________ mfg. Joel
 |  |  |  
| gerd8888  
          Beiträge: 205
 Erhaltene Danke: 3
 
 Win7
 Delphi 10.1 Starter (kostenlos)  Lazarus
 
 | 
Verfasst: Mo 19.09.16 22:51 
 
Ich habe mir die Atomschachrätsel angesehen. Konnte nur das letzte Problem lösen. Schade, dass es keine Lösungsbesprechung gibt.
 Zurueck zu den Magic Bitboards.
 Ich will jetzt die magischen Masken herausfinden:
 												| 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:
 
 | procedure TForm1.magische_zahlen;var testz,t,magic,erg,i:int64;
 
 begin
 testz:=0;
 bitset(testz,50);
 bitset(testz,43);
 bitset(testz,36);
 bitset(testz,29);
 bitset(testz,22);
 bitboard(testz);
 label1.Caption:=inttostr(low(testz))+' '+inttostr(high(testz));
 update;
 t:=testz;
 for i:= low(testz) to high(testz) do begin}
 if t*i >= low(testz) then if t*i <= high(testz) then begin
 erg:=t*i;
 if bittest(erg,59) then if bittest(erg,60) then if bittest(erg,61) then if bittest(erg,62) then
 if bittest(erg,63) then begin
 bitclear(t,50);
 if not bittest(erg,59) then if bittest(erg,60) then if bittest(erg,61) then if bittest(erg,62) then
 if bittest(erg,63) then begin
 bitset(t,50);
 bitclear(t,43);
 if bittest(erg,59) then if not bittest(erg,60) then if bittest(erg,61) then if bittest(erg,62) then
 if bittest(erg,63) then begin
 bitset(t,43);
 bitclear(t,36);
 if bittest(erg,59) then if bittest(erg,60) then if not bittest(erg,61) then if bittest(erg,62) then
 if bittest(erg,63) then begin
 bitset(t,36);
 bitclear(t,29);
 if bittest(erg,59) then if bittest(erg,60) then if bittest(erg,61) then if not bittest(erg,62) then
 if bittest(erg,63) then begin
 bitset(t,29);
 bitclear(t,22);
 if bittest(erg,59) then if bittest(erg,60) then if bittest(erg,61) then if bittest(erg,62) then
 if not bittest(erg,63) then begin
 magic:=i;
 beep;
 break;
 end;
 end;
 end;
 end;
 end;
 
 end;
 end;
 end;
 beep;
 
 
 
 
 label1.caption:=inttostr(magic);
 
 end;
 |  Nach 2 Stunden habe ich abgebrochen. Ich habe herausgefunden, dass es an der Multiplikation liegt:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 
 | for i:= low(testz) to high(testz) do begin}if t*i >= low(testz) then if t*i <= high(testz) then begin
 erg:=t*i;
 |  Was nun?
 Gerd |  |  |  |