DB für ein Webschach

K

koli.bri

Hallo.

Hab mal meine alten Scripts aufgeräumt und bin über mein altes webschach gestolpert, was jetzt einmal generalüberholt (komplett neugemacht) wird.
Damals hab ich die Werte noch in einer Textdatei gespeichert, die folgendermaßen aussah:

Textdatei schrieb:
t#s#l#d#k#l#s#t
b#b#b#b#b#b#b#b
0#0#0#0#0#0#0#0
0#0#0#0#0#0#0#0
0#0#0#0#0#0#0#0
0#0#0#0#0#0#0#0
B#B#B#B#B#B#B#B
T#S#L#D#K#L#S#T
s#1#0#1#0

Die ersten acht Zeilen haben die Standorte der Figuren gespeichert, die letzte hat zusätzliche Informationen beinhaltet (Wer am Zug ist, und wies mit den Rochaden aussieht).
Der Gange Kram wurde Zeilenweise eingelesen und nachher mit explode() gesplittet.

Und nun will ich das via SQL lösen.

Doch, wie sieht da die "optimale" Datenstruktur aus? Habt Ihr Ideen?
Ziel ist es, dass man mehrere Schachspiele verwalten kann.
Gespeichert werden muss jedes Feld und was drauf steht (anders herum gehts nicht, weil die Bauern ja auch andere Figuren werden können), und halt der ganze Kram wie ob die Türme/König schon bewegt worden sind (Rochade), wer am Zug ist, etc...

Ausgegeben werden muss das ganze in ein Zweidimensionales PHP Array nach dem Schema $feld[buchstabe][zahl]

Habt ihr Ideen?

Derzeit hab ich für jedes der 64 Felder ein eigenes Feld definiert...

gruß
Lukas
 
Ach so, wer fitt in JavaScript ist, und Lust hat ein paar Teile zu programmieren, kann sich gerne melden.
Die Frage ist nur, ob und wie man das Script danach auch benutzt/publik macht... Ich mach das eher nur so nebenbei zum üben (hab auch mal drüber nachgedacht, andere Spiele als Webapplikation zu machen, Siedler, oder Risiko und so..)

gruß
Lukas
 
Nur mal so als Denkansatz:

Die Felder sind nicht variabel, sie zu speichern macht wenig Sinn!
Wie man Schachspiele beschreibt, kann man gut an der Notation in den Schachübungen jeder gehobenen Tageszeitung nachlesen! Ich bin da nicht so Firm, aber etwa b(e2-e3) für Bauer e2 nach e3, sowie Farbe wärn doch interessant!
 
Hab ich auch drüber nachgedacht, nur die Notation zu speichern. Nachteil ist jedoch, dass ich dann für jeden Zug immer die Komplette Partie nachspielen müsste.

Und die Figuren einzeln zu speichern fand ich problematisch, weil die Bauern sich ja in andere Figuren wandeln können, sprich, ich müsste dann im Groben folgende Struktur haben:

Tabelle_Spiel:
-ID_vom_Spiel
-wkonig
-skonig
-wdame
-s....

-wbauer1
-wbauer1figur
-wbauer2
-wbauer2figur

Die "bauerfigur" Felder wären dann das Feld, wo drinsteht, was für Figuren die Bauern sind. Zudem müste ich dann, falls die Figur geschlagen wird, dieses mit einem Nullfeld belegen, etc...
Und das sieht mir nicht nach einer gut durchdachten Struktur aus :)

----
Moment, hab mir das gerade eben noch einmal durchgelesen, was Du geschrieben hast:
Glaube, wir haben da ein Kommunikationsproblem:

Ich meine nicht dern Verlauf der Partie, den würd ich ganz simpel so speichern, wie die Notation ganz normal aussieht.
Es geht hier darum, wie man eine Position auf dem Schachbrett speichern kann.
Ziel des Projekt ist ein Webschach, mit dem zwei Menschen spielen können. Nicht das archieren von Partien.

Dennoch danke für die Hilfe

gruß
Lukas
 
wenn du nur abspeichern willst welche Figur auf welcher position steht sollte das doch ein fach mit einer Zweispaltigen Tabelle getan sein.
FELDNr(int) | Figur
1
2
.
.
.
64

Die Figuren würde ich wahrscheinlich auch als zahlen werte ablegen sprich bauer=1 Turm=2 ...

Die Rochaden würde ich auch in einer Zweispaltigen Tabelle ablegen Alternaiv könntest du der Belegungstabelle eine Spalte Spiel_Nr zuweisen, womit jedes feld genau einem Spielfeld zugeordnet ist.


Farbe | Rochade_Möglich (bool)
Schwarz | 1
Weiss | 1

Du kannst für verschiedene Spiele eigene Tabellen anlegen. Alternativ kannst du der Belegungstabelle noch eine Spalte Spiel_nr hinzufügen, die jedes Spielfeld einem Spielbrett zuordnet
 
Hm... Es gibt wohl keine Andere möglichkeit, als für jedes Feld eine eigene Spalte zu machen, wie?

sir.hacks.alot:
An die Idee hab ich bereits gedacht, der Nachteil ist jedoch, dass ich Tabellennamen ja nicht dynamisch abfragen kann, oder?

Ein Multiuser-System, bei dem jeder User eine eigene Tabelle hat wäre doch ein wenig (viel) umständlich, oder?

Naja, ich hab ja auch nicht damit gerechnet, dass es einfach wird....

gruß
Lukas
 
koli.bri schrieb:
Hm... Es gibt wohl keine Andere möglichkeit, als für jedes Feld eine eigene Spalte zu machen, wie?

sir.hacks.alot:
An die Idee hab ich bereits gedacht, der Nachteil ist jedoch, dass ich Tabellennamen ja nicht dynamisch abfragen kann, oder?

Ein Multiuser-System, bei dem jeder User eine eigene Tabelle hat wäre doch ein wenig (viel) umständlich, oder?

Naja, ich hab ja auch nicht damit gerechnet, dass es einfach wird....

gruß
Lukas

Wie man den Zugriff auf die Tabellennamen dynamisch gestalten würde wüsste ich jetzt auch nicht so direkt, könnte mir duraus vorstellen daß das geht. Der Vorteil wäre, daß die Daten leichter zu verwalten sind, wenn jedes Spiel ne eigene Tabelle hat. Im Zweifelsfall kannst du ja ne Tabelle machen in der dem User bzw Userpaar ein Tabellenname zugeordnet wird.
 
ja warum machst Du es dann nicht so, daß Du 32 Figuren als Objekte ablegst?

Eigenschaften:

x_pos [1..8]
y_pos [1..8]
art [bauer|turm|springer|laeufer|dame|koenig]
farbe [schwarz|weiß]
aktiv [1|0]


fertig ists! Wird eine Figur gewandelt wird sie umbenannt, wird sie bewegt ändern sich x_pos/y_pos ( gemäß Regeln). Ist sie geschlagen wird aktiv==0 und das Objekt nicht mehr dargestellt! Mehr braucht man doch gar nicht!
 
danke wegus, ich schau mir das mal an, ob das für meine Zwecke taugt. Denke aber schon.

vielen lieben Dank (auch wenn wir uns im Promillefred nicht gut verstanden haben)

und gruß
Lukas
 
koli.bri schrieb:
auch wenn wir uns im Promillefred nicht gut verstanden haben

[OT]
ein gern gemachter Fehler! Unterschiedliche Meinungen zu haben ist nicht verwerflich! Ich diskutier ungern mit Leuten die immer meiner Meinung sind, das bringt doch nix, wenn jeder dem andern sagt er habe recht ;)
[/OT]
 
koli.bri schrieb:
[..]Ich meine nicht dern Verlauf der Partie, den würd ich ganz simpel so speichern, wie die Notation ganz normal aussieht.
Es geht hier darum, wie man eine Position auf dem Schachbrett speichern kann.
[..]

Um eine allgemein eine Schachposition zu speichern benötigst du folgende Daten:
- Für (maximal 16) Steine das Feld (e4) und den Figurentyp (sL).
- Rochadestatus Weiss und Schwarz (Sparer machen das mit einem eigenen Figurentyp für die Könige und Türme, je nachdem ob diese noch rochadefähig sind, lohnt sich aber eher nicht)
- ep-Status (wenn zuletzt ein Bauer zwei Felder gezogen hat und neben einem gegnerischen gelandet ist, so muss das gemerkt werden, da dann ein Ep-Schlagen möglich sein könnte.)
- Wie lange zurück kein Bauer gezogen oder ein Stein geschlagen wurde. (Um remis durch 50 Zügeregel zu reklamieren.)
- Wer denn am Zuge ist.

Aber ehrlich gesagt würde ich keine SQL Datenbank dazu benutzen. Es sei denn, du möchtest ganze Partien archivieren und darin suchen. Nach dem Motto "Welcher Grossmeister hat 1899 in welcher Partie denselben dummen Fehler wie mein Gegner gemacht?" :)
Du wirst im übrigen kaum SQL-Befehle angeben können, die einen Zug auf Legalität überprüfen können. Wenn du dir das wirklich antun willst, so verwende BitBoards, das sind 64 Bit lange Strings (wie passend dass 64 auch die Wortlänge von CPUs ist, oder 2x32 für 32 Bit Maschinen). Du brauchst dann für jeden Figurentyp einen String und an der Position x steht eine 1 wenn dort eine Figur diesen Typs steht, sonst 0. Das genau zu erklären da liefert Google zig Seiten. Die Idee ist letztlich dass logische Verknüpfungen (AND, OR, XOR) dann auf 64 Feldern gleichzeitig operieren können.

Wenn du vor dem Problem stehst, eine Stellung in der Datenbank wiederzufinden, so speichere einen Hashwert für jede Stellung ab. Dazu füllt man ein 8x8 Feld mit Zufallszahlen (32 oder 64 Bit lang) und wendet die XOR Funktion auf alle mit Figuren belegten Felder an. So liefert jede Stellung eine Zahl und sucht man eine Stellung so berechnet man deren Kennzahl (Hashwert) und dann liefert eine einfache Suche der Form "...where (Hashwert = MyWert)" alle Kandidaten für Stellungen.
Dabei können Kollisionen auftreten (bei 64 Bit seltener), so dass man u.U. mehrere Ergebnisse bekommt. Diese muss man dann noch durchtesten mit einer anderen Methode. Suchzeiten liegen im Millisekunden Bereich für Datenbanken mit Millionen von Stellungen. Google Suche nach "Transposition Tables" anwerfen, so heissen die in Englisch.

Viele Grüße
Thomas
 
ThomasC schrieb:
Um eine allgemein eine Schachposition zu speichern benötigst du folgende Daten:
- Für (maximal 16) Steine das Feld (e4) und den Figurentyp (sL).
- Rochadestatus Weiss und Schwarz (Sparer machen das mit einem eigenen Figurentyp für die Könige und Türme, je nachdem ob diese noch rochadefähig sind, lohnt sich aber eher nicht)
- ep-Status (wenn zuletzt ein Bauer zwei Felder gezogen hat und neben einem gegnerischen gelandet ist, so muss das gemerkt werden, da dann ein Ep-Schlagen möglich sein könnte.)
- Wie lange zurück kein Bauer gezogen oder ein Stein geschlagen wurde. (Um remis durch 50 Zügeregel zu reklamieren.)
- Wer denn am Zuge ist.

Aber ehrlich gesagt würde ich keine SQL Datenbank dazu benutzen. Es sei denn, du möchtest ganze Partien archivieren und darin suchen. Nach dem Motto "Welcher Grossmeister hat 1899 in welcher Partie denselben dummen Fehler wie mein Gegner gemacht?" :)
Du wirst im übrigen kaum SQL-Befehle angeben können, die einen Zug auf Legalität überprüfen können. Wenn du dir das wirklich antun willst, so verwende BitBoards, das sind 64 Bit lange Strings (wie passend dass 64 auch die Wortlänge von CPUs ist, oder 2x32 für 32 Bit Maschinen). Du brauchst dann für jeden Figurentyp einen String und an der Position x steht eine 1 wenn dort eine Figur diesen Typs steht, sonst 0. Das genau zu erklären da liefert Google zig Seiten. Die Idee ist letztlich dass logische Verknüpfungen (AND, OR, XOR) dann auf 64 Feldern gleichzeitig operieren können.

Wenn du vor dem Problem stehst, eine Stellung in der Datenbank wiederzufinden, so speichere einen Hashwert für jede Stellung ab. Dazu füllt man ein 8x8 Feld mit Zufallszahlen (32 oder 64 Bit lang) und wendet die XOR Funktion auf alle mit Figuren belegten Felder an. So liefert jede Stellung eine Zahl und sucht man eine Stellung so berechnet man deren Kennzahl (Hashwert) und dann liefert eine einfache Suche der Form "...where (Hashwert = MyWert)" alle Kandidaten für Stellungen.
Dabei können Kollisionen auftreten (bei 64 Bit seltener), so dass man u.U. mehrere Ergebnisse bekommt. Diese muss man dann noch durchtesten mit einer anderen Methode. Suchzeiten liegen im Millisekunden Bereich für Datenbanken mit Millionen von Stellungen. Google Suche nach "Transposition Tables" anwerfen, so heissen die in Englisch.

Viele Grüße
Thomas

Vielen lieben Dank, auch wenn ich nur die Hälfte verstanden habe :)

Zu dem Überprüfen der Züge:
Dass passiert mit JavaScript.

gruß
Lukas
 
wegus schrieb:
[OT]
ein gern gemachter Fehler! Unterschiedliche Meinungen zu haben ist nicht verwerflich! Ich diskutier ungern mit Leuten die immer meiner Meinung sind, das bringt doch nix, wenn jeder dem andern sagt er habe recht ;)
[/OT]

Warum ein Fehler???
 
weil Du unterstellst das man sich schlecht versteht - nur weil man andere Meinungen hat!
 
Zurück
Oben Unten