Autor Beitrag
gerd8888
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Fr 22.11.13 19:25 
hallo,

ich will meine brettdarstellung auf bitboards umstellen. (Die sollen schneller sein) Gibt es dazu vielleicht ein kleines Demo-Beispiel wie z.B. Vier gewinnt oder aehnliches, das ich mir mal anschauen koennte?
gerd8888 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Sa 23.11.13 13:06 
Im Wesentlichen interessieren mich 2 Sachen:

0 0 0 0 0 1 0 1

Wenn ich die 6. Position auslesen will. Wie macht man das. Ich will wissen ob sich an einer bestimmen Position eine 1 oder eine 0 befindet.

Wie bekommt man schnell an eine Position mit aller 1 en?

Und die 2 Frage, was schneller ist. Ein Bitverschiebung oder wenn man ein zweites Bit miteinander verknuepft.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Sa 23.11.13 14:21 
Hilft Dir das hier weiter? Vielleicht habe ich die Frage aber auch nicht richtig verstanden.
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Sa 23.11.13 14:26 
user profile icongerd8888 hat folgendes geschrieben Zum zitierten Posting springen:

Wenn ich die 6. Position auslesen will. Wie macht man das.

Wenn DU die Positionen im Byte so zählst: 76543210, dann etwa so:
ausblenden Delphi-Quelltext
1:
if (DeinByte AND 01000000)=01000000 then ...					

user profile icongerd8888 hat folgendes geschrieben Zum zitierten Posting springen:

Wie bekommt man schnell an eine Position mit aller 1 en?

Meinst Du 8 Einsen in einem Byte (=255) oder 8 aufeinanderfolgende Einsen in einem Stream?
user profile icongerd8888 hat folgendes geschrieben Zum zitierten Posting springen:

Und die 2 Frage, was schneller ist. Ein Bitverschiebung oder wenn man ein zweites Bit miteinander verknuepft.

Das ist schon die 3. Frage :wink:
Aber konkret: Ein zweites Bit willst Du mit was verknüpfen. Erkläre Dein Problem doch besser mal an einem Beispiel.
gerd8888 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Sa 23.11.13 15:57 
Ich glaube ich habe es verstanden. Das mit der Position brauche ich ja auch nicht, da die Leerfelder auch ein Bitboard darstellen.
Ich schreibe jetzt das Programm, und wenn es fertig ist werde ich das hier vorstellen.
Besten Dank.
gerd8888 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Sa 23.11.13 16:38 
wenn ich jetzt ein byte var b:byte habe und sage b:=7
aber ich möchte das so machen, dass ich in b:=00000111 (direkt in die speicheradresse reinschreibe)
wie macht man das?
und wie kann ich b:=7 auslesen, dass ich 00000111 bekomme ?

Gerd
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Sa 23.11.13 17:09 
Du verwechselst da etwas: 7 = 7, es gibt nur unterschiedliche Darstellungen (binär, oktal, dezimal, hexadezimal, etc.). Wenn Du also der Variablen b die Zahl 7 in dezimaler Schreibweise zuweist, dann enthält sie auch 7. Dasselbe, wenn Du das in hexadezimaler Schreibweise tust ($07).
gerd8888 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Sa 23.11.13 18:17 
Ich versuche mein Problem darzustellen.
Ich arbeite mit einem int64 (8 byte) (64 bit) (Schachbrettgroesse)
Bei der Zahl 7 koennte ich die Binaerzahl leicht herausbekommen, indem ich immer durch 2 dividiere.
Bei der int64 habe ich das Problem, das die Zahl in den Minus-Bereich kommt.

Was ich letztendlich will ist folgendes:

Die 64 Bit (int64):
00100000001000 ... (dann folgen bis zur 64. Stelle nur 0 en)

Jetzt habe ich diese Zahl mit 2 "1" von denen ich ahnungslos bin, wo sie sind und wieviele es sind und will das an der 3. Stelle um 2 nach rechts Verschieben also
00001000001000 ...

und die 2 "1" auch um 2 verschieben, so:
00100000000010 ...

Wie will ich suchen, wenn mir die int64 Zahl unbekannt ist?
1000000.... (Dezimalzahl?, die ich fuer die Suche brauche)
0100000....
0010000....
usw

Und dann noch die Frage, wie ich das am schnellsten verschiebe. Mit slr duerfte das mit 2 "1"en nicht gehen??

Ich will also in einem int64 die "1" aufsuchen und um 2 nach rechts verschieben, aber nicht beide gleichzeitig.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Sa 23.11.13 18:57 
Hallo,

bei Bitboard geht es um die Moeglichkeit moeglichst schnell Stellungen auf Sieg zu pruefen.
Insbesondere bei Verwendung bei 4 Gewinnt von 64 Bit Zahlen.
Ich stelle das mal dar:
Bei 4 gewinnt wirft man die Steine spaltenweise in ein Gestell/Spielfeld mit 7 Spalten und 6 Zeilen ein.Damit waere es anschaulich, diese auch so zu speichern.
Auf Bitebene waeren also 7 Byte mit belegten Bits fuer die Zeilen 0..5
Ein Spielfeld haette damit 7 Byte, fuer den Computer optimal sind aber 8 Byte = 64 Bit, also laesst man dieses eine Byte immer auf 0.
Jeder Spieler verwaltet so ein Spielfeld fuer sich mit den nur von ihm belegten Feldern und die Vereinigungsmenge beider ergibt das tatsaechliche Spielfeld oder wird zusaetzlich verwaltet.
Man erstellt alle moeglichen Anordnungen von 4 in einer Reihe als Bitmasken
Spalte 0..3/Zeile = 0 waere dann ( 2 hoch 0 = 1 )
0|0|0|0|1|1|1|1| = 16843009dez = 0x0000000001010101 (hex)
Spalte 0..3/Zeile = 5 waere dann ( 2 hoch 5 = 32 )
0|0|0|0|32|32|32|32| = 538976288dez = 0x0000000020202020
das sind 69??? verschiedene ( horizontal = 6*4,vertikal 3*7, links steigende diagonalen 3*4 und rechts steigende Diagonalen 3*4,forum softgames/developia gibt es scheinbar nicht mehr. TGGC und hamsterofdeath aegerten sich wie so oft...)
Ein Test, ob man gewonnen hat waere also ein Vergleich darauf, ob ein logisches UND mit der Maske, die Maske selbst ergibt.
IF Maske[i] AND MeinSpielfeld = Maske[i] then
gewonnen :-)
Man testet aber nicht mit allen Masken, sondern nur mit denen die fuer das Feld, in das man den letzten Stein geworfen hat, gelten.

Grusz Horst
P.S.
BitTest,BitSet und BitClear gibt es sicher in tausend Varianten.Hier mal pascal.
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:
// Edit wegen 1 shl Bitnr wird sonst nur 32 bittig ausgefuehrt 
const
  EinsInt64 : Int64 = 1;

function Bittest (TestZahl : int64,Bitnr: integer):boolean;
{var
  Bitmaske : int64;
begin
  Bitmaske := EinsInt64 shl BitNr;
  result := TestZahl AND BitMaske <> 0;}

begin
  result := TestZahl AND (EinsInt64 shl BitNr) <> 0;
end;

procedure BitSet(var TestZahl : int64,Bitnr: integer);
begin
  TestZahl := TestZahl OR (EinsInt64 shl BitNr);
end;

procedure BitClear(var TestZahl : int64,Bitnr: integer);
begin
  TestZahl := TestZahl AND NOT(EinsInt64 shl BitNr);
end;


Zuletzt bearbeitet von Horst_H am Mo 25.11.13 09:45, insgesamt 1-mal bearbeitet
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 23.11.13 19:36 
Hallo Gerd,

Bitboards hatte ich mir vor einiger Zeit auch angeschaut (der Wikipedia-Artikel zu dem Thema ist ziemlich gut, da steht eigentlich alles drin was man braucht *klick*). Letztendlich habe ich ein anderes Verfahren (0x88 Methode) genommen, mit dem es sehr leicht wird zu prüfen ob ein Zug das Brett verlassen würde (z.B. für Springer sehr wichtig): Neben dem Spielfeld wird ein zweites, virtuelles, Brett positioniert und die 128 Felder beider Bretter werden nummeriert. Dann läuft ein Zug, der das eine Brett verlässt, automatisch auf das andere. Außerdem ist es möglich, mit elementaren bitweisen Operationen herauszufinden auf welchem Brett ein Feld liegt und was seine Koordinaten sind.

Möglicherweise kann man auch beide Verfahren in einem Programm verwenden und zusätzlich Bitboards für Tabellen-lookups haben?

lg,
Daniel

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
gerd8888 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Sa 23.11.13 21:04 
Hallo Horst,

habe gerade mal die bitset und bitclear getestet und funktioniert einwandfrei.
Ich dachte mir, dass ich mir die (Bitmaske := 1 shl BitNr;) durch konstante Zahlen ersetzten muss.
Wuerde immerhin auch die Bitverschiebung einsparen. Aber ich glaube, dass die so schnell ist, dass das so gut wie keine Zeit kostet.
Das war wirklich sehr hilfreich.

So wie es im Wikipedia-Artikel zu lesen ist, genau so habe ich es mir auch vorgestellt. Ich mache ein brett_w[1..6 (Figurentypen) ] of int64 und
ein brett_s[1..6] of int64 und ein leerfeld: int64. Die 0x88 Methode habe ich nicht ganz verstanden. Aber es hat natürlich einen Vorteil, wenn
man das Brett kopiert, insbesondere wenn man einen Zug zuruecknimmt. Wenn ich das richtig verstanden habe hat man ein brett:array[1..8] of byte ?
gerd8888 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: So 24.11.13 00:18 
Hier gibt es ein Problem bei int64, dass beim Setzen 2 bit (1 und 33) oder (2 und 34) gesetzt werden.

www.entwickler-ecke....zt+sind_80126,0.html
Aber die Loesungen helfen nicht, wenn ich z.B. ueber 32 einen bit setzen will.

??
Gerd
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 24.11.13 01:26 
Kann ich so nicht bestätigen. Was hast du für ein Delphi? Das hier funktioniert in D7 akkurat...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  x: int64;
begin
  // (für "wild auf der Tastatur gehämmert" sieht die auffallend Regelmäßig aus, oder?)
  x:= $A292888868222949;     // 1010001010010010100010001000100001101000001000100010100101001001
  //vorher: Bit an gleicher Stelle im Hi und LowDWORD gesetzt
  Assert((x and (Int64(1shl 61)) <> 0);
  Assert((x and (Int64(1shl 29)) <> 0);
  //ändern                   // 1000001010010010100010001000100001101000001000100010100101001001
  x := x and not (Int64(1shl 61);
  //nachher: nur eins von beiden geändert
  //
  Assert((x and (Int64(1shl 61)) = 0);
  Assert((x and (Int64(1shl 29)) <> 0);

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."