Schach-Programm (Anfangs-tipps)
-
rofl, bester in der Schule.
Kannst du hier den Hard mode schlagen? http://www.chess.com/play/computer.html
-
Hacker schrieb:
Nope. Empfehl mal eins. Oder lass mal zusammen spielen.
Naja, der größte kostenlose ist wohl FICS, oder zumindest kenne ich keine größeren.
Nicht dass du jetzt meinst, ich würde gut spielen... Ich finde eher, dass ich total schlecht spiele. Keine Chance gegen Vereinsspieler.
-
cooky451 schrieb:
rofl, bester in der Schule.
Kannst du hier den Hard mode schlagen? http://www.chess.com/play/computer.htmlJa, ich dich auch rofl. Und: Ich bin weit gekommen... nur leider hat er mir eine völlig unerwartete Gabel gestellt.
-
Wenn hier schon ein wenig abgedriftet wird, dann möchte ich noch die Seite chesstempo.com in den Raum werfen, bei der man sehr gut seine taktischen Fähigkeiten trainieren kann und je nach Spielstärke entsprechend schwere/leichte AUfgaben gestellt bekommt.
-
Ganz nette Seite, ja.
-
Ach danke and _cu für die Seite! Echt ziemlich gut.
-
SeppJ schrieb:
Viel zu konkrete Planung bei viel zu vagem Konzept. Definier doch erst einmal genau, was deine Klassen sind und was sie können, bevor du dir Gedanken um die technische Umsetzung vonwegen Kindklassenzeigern, Nullpointern & Co. machst.
Kacke. Wer nicht hören will muss fühlen. Hab grad ~800 Zeilen Code gelöscht, war alles Crap-Code... Bin gerade bei Heft und Stift.
-
Hacker schrieb:
SeppJ schrieb:
Viel zu konkrete Planung bei viel zu vagem Konzept. Definier doch erst einmal genau, was deine Klassen sind und was sie können, bevor du dir Gedanken um die technische Umsetzung vonwegen Kindklassenzeigern, Nullpointern & Co. machst.
Kacke. Wer nicht hören will muss fühlen. Hab grad ~800 Zeilen Code gelöscht, war alles Crap-Code... Bin gerade bei Heft und Stift.
durch müllcode lernt man am meisten. die fehler wären dir doch auf stift und papier garnicht erst aufgefallen.
-
Tipp: Das Schachbrett ist nicht die zentrale Entität, um die sich die OO-Modellierung drehen sollte. Imho kann die Klasse des Bretts sehr klein und dumm sein und evtl sogar nur ein Array der Figuren wegkapseln sowie kleine Hilfsfunktionen anbieten (z.B: bool Inside(x,y)).
Andere Dinge sind wichtiger und stellen die zentralen Klassen dar: Figuren, Züge und dazu gekoppelt eine History (für das Durchprobieren der KI).
-
µ schrieb:
Tipp: Das Schachbrett ist nicht die zentrale Entität, um die sich die OO-Modellierung drehen sollte. Imho kann die Klasse des Bretts sehr klein und dumm sein und evtl sogar nur ein Array der Figuren wegkapseln sowie kleine Hilfsfunktionen anbieten (z.B: bool Inside(x,y)).
Andere Dinge sind wichtiger und stellen die zentralen Klassen dar: Figuren, Züge und dazu gekoppelt eine History (für das Durchprobieren der KI).
KA wie du das meinst. Aber meine (Board-)Klasse wird ziemlich groß (so sieht der Header bisher aus):
#ifndef BOARD_HXX_INCLUDED #define BOARD_HXX_INCLUDED #include "coordinate.hxx" #include <array> namespace chess { class figure; class Board { struct ChessBoardError; std::array<std::array<figure*, 8>, 8> m_figureArray; std::vector<figure*> m_blackFigures, m_blackEatenFigures, m_whiteFigures, m_whiteEatenFigures; size_t m_amountOfMoves; public: Board(); void move(coordinate, coordinate); static bool check(coordinate, bool = true); std::array<figure*, 8> operator [](size_t); std::array<figure*, 8> at(size_t); std::array<figure*, 8> const operator [](size_t) const; std::array<figure*, 8> const at(size_t) const; figure* at(coordinate); figure const* at(coordinate) const; void add(coordinate, figure*); bool size_t amountOfMoves(); }; } #endif // BOARD_HXX_INCLUDED
-
Wenn die Schachklasse für "moves" verantwortlich ist, reicht ein std::array<std::array<figure*, 8>, 8> nicht aus, damit die KI Züge durchprobieren kann. (Die KI muss Züge beider Farben mehrere Schritte weit simulieren und zu jederzeit rückgängig machen können)
Wie willst Du damit einen Testzug realisieren? Es muss eine Art History geben, einen Stack oder so, der während dem abwechselnden ziehen der KI auf und abgebaut wird.
Eine andere Möglichkeit wäre, den Figuren selbst eine History zu geben. Aber soll sich eine Figur wirklich merken, welche anderen Figuren sie während dem KI-Lauf geschlagen hat? Klingt nach zu vielen Abhängigkeiten.Jetzt kannst Du die interne Repräsentation des Bretts aufbohren. Z.b. durch ein 2D-Array aus Stacks. Dann ist das Brett sowohl für Züge als auch für ein komplexes internes Objekt verantwortlich. Früher oder später kommt grafische Ausgabe dazu. Dann kommt noch X dazu. Dann noch Y. Und am Ende hast Du eine Monsterklasse.
Eine imho bessere Möglichkeit: Halte die Board-Klasse extrem schlank. Lagere alles aus was nur geht. Abstrahiere das Konzept "Zug" bzw. "Move" als eigene Klasse. Abstrahiere die "History" als Klasse die intern einen Move-Stack vorhält.
Mal ein Beispiel aus einem anderen Bereich: Du hast Bitmaps und Bildverarbeitungsalgorithmen. Der naheliegende Ansatz ist eine Bitmapklasse stetig zu erweitern um neue Bildfilter und Algorithmen. Ganz schnell hast Du eine Klasse mit 5000 Zeilen und es dämmert, dass da etwas falsch läuft. Tatsächlich ist ein Bitmap nur ein Datenobjekt mit einfachsten Methoden (bzw. sollte es sein). Alle Algorithmen sind in einer externen Klassenhierarchie und operieren auf Bildern. Das Bitmap weiß nichtmal dass es sowas wie Algorithmen gibt.
Beim Schach ist es nicht soooo wichtig, weil die Anzahl der Operationen und beteiligten Entitäten sehr überschaubar sind. Aber Du hast angedeutet, ein sauberes Design zu wollen. Deshalb diese Anmerkungen.
-
µ schrieb:
Wenn die Schachklasse für "moves" verantwortlich ist, reicht ein std::array<std::array<figure*, 8>, 8> nicht aus, damit die KI Züge durchprobieren kann. (Die KI muss Züge beider Farben mehrere Schritte weit simulieren und zu jederzeit rückgängig machen können)
Wie willst Du damit einen Testzug realisieren? Es muss eine Art History geben, einen Stack oder so, der während dem abwechselnden ziehen der KI auf und abgebaut wird.Ich möchte die Board-Klasse so lassen wie sie ist. Ich finde, mehr Methoden als jetzt kommen eh nicht hinzu(!), und search/evaluation Funktionen sind global (bzw. im chess-Namespace). Aber deine Idee für 'ne History Hast du mir Gegeben: Mit einer Klasse
Move
und einemstd::stack
(sowie noch anderen KlassenHistory
& CO. (werd ich noch planen))dürfts was werden...
Was die graphische Oberfläche angeht: Hmm. Ich habe mich entschieden, 3D zu benutzen (mit Irrlicht, dass ich momentan "entdeckt" habe). Dort kommt noch eine Klasse (oder mehr) hinzu. Das mit dem Bewegen und so hab ich bereits alles geplant.
-
Kennst du eigentlich die Seite?
-
Hacker schrieb:
Was die graphische Oberfläche angeht
Würde ich an Deiner Stelle vorerst drauf verzichten, bis das Ding in der Console läuft.
-
µ schrieb:
Hacker schrieb:
Was die graphische Oberfläche angeht
Würde ich an Deiner Stelle vorerst drauf verzichten, bis das Ding in der Console läuft.
Das ist doch klar. Ich meinte, jetzt so ein ein paar Wochen, wenn das erste Spiel gespielt ist.
-
Hacker schrieb:
µ schrieb:
Hacker schrieb:
Was die graphische Oberfläche angeht
Würde ich an Deiner Stelle vorerst drauf verzichten, bis das Ding in der Console läuft.
Das ist doch klar. Ich meinte, jetzt so ein ein paar Wochen, wenn das erste Spiel gespielt ist.
Warum ein paar Wochen? Mach Dir das Leben nicht so schwer und programmiere drauf los, immer mit dem Hintergedanken, dass die Verantwortlichkeiten verteilt sein müssen. Halte die Klassen extrem Schlank. Verzichte, außer bei den Figuren, auf Vererbung. Führe alle anderen Aktionen als Konstruktorparameter in die Klassen (Dependency-Injection). Verzichte auf Template-Gehacke.
Um ehrlich zu sein kam ich gestern Abend nach dem erneuten Lesen dieses Threads auf den Geschmack.
Habe nun meinen Vorschlag von gestern mal realisiert und es funktioniert ohne Probleme.
Heißt: Spiele gegen eine Random-KI (die aber trotz Random nur gültige Züge abliefert), Spiele zwischen zwei solchen Dumm-KIs und Spiele zwischen zwei Menschen sind bereits möglich.
Ausgabe bisher nur Console. Schachsituation und Rochaden (Remis, Bauerntausch ebenfalls) fehlen noch. Beliebige Aktionen können über eine History-Klasse mit internem Stack von "Move/Zug"-Objekten rückgängig gemacht werden. Die Board-Klasse hat kaum 100 Zeilen und besteht nur aus dümmsten Hilfsfunktionen. (EnemyAt, FriendAt und solche Dinge).
-
µ schrieb:
Hacker schrieb:
µ schrieb:
Hacker schrieb:
Was die graphische Oberfläche angeht
Würde ich an Deiner Stelle vorerst drauf verzichten, bis das Ding in der Console läuft.
Das ist doch klar. Ich meinte, jetzt so ein ein paar Wochen, wenn das erste Spiel gespielt ist.
Warum ein paar Wochen? Mach Dir das Leben nicht so schwer und programmiere drauf los, immer mit dem Hintergedanken, dass die Verantwortlichkeiten verteilt sein müssen. Halte die Klassen extrem Schlank. Verzichte, außer bei den Figuren, auf Vererbung. Führe alle anderen Aktionen als Konstruktorparameter in die Klassen (Dependency-Injection). Verzichte auf Template-Gehacke.
Um ehrlich zu sein kam ich gestern Abend nach dem erneuten Lesen dieses Threads auf den Geschmack.
Habe nun meinen Vorschlag von gestern mal realisiert und es funktioniert ohne Probleme.
Heißt: Spiele gegen eine Random-KI (die aber trotz Random nur gültige Züge abliefert), Spiele zwischen zwei solchen Dumm-KIs und Spiele zwischen zwei Menschen sind bereits möglich.
Ausgabe bisher nur Console. Schachsituation und Rochaden (Remis, Bauerntausch ebenfalls) fehlen noch. Beliebige Aktionen können über eine History-Klasse mit internem Stack von "Move/Zug"-Objekten rückgängig gemacht werden. Die Board-Klasse hat kaum 100 Zeilen und besteht nur aus dümmsten Hilfsfunktionen. (EnemyAt, FriendAt und solche Dinge).WHAT THE ?
In ein paar Stunden? Mannoman....
Wie hast du das mit dem Schach realisiert? Also, wie überprüfst du ob ein Zug gültig ist, wenn danach noch Schach ist ist er das ja nicht?
-
Du mußt dir die Position der Könige merken und schauen, ob einer der gegnerischen Figuren dorthin ziehen kann (also den König schlagen könnte). Einzig bei einer Rochade mußt du auch das jeweils übersprungene Feld zusätzlich auf Schach abfragen.
Habe gerade meine alten Sourcen durchsucht und mein Konsolen-Schackprogramm (in C, auf dem Amiga, von 1993) wiederentdeckt. Hat ca. 500 Zeilen und wurde von mir - laut Kommentar - innerhalb von 4 Tagen erstellt.
-
Th69 schrieb:
Du mußt dir die Position der Könige merken und schauen, ob einer der gegnerischen Figuren dorthin ziehen kann (also den König schlagen könnte).
Das reicht nicht ganz. Der Königszug muss simuliert werden um erst dann zu schauen, ob er bedroht ist. Es könnte nämlich sein, dass ein Feld, auf das der König zieht, sowohl von einem Gegner besetzt als auch gedeckt ist. Die deckende Figur konnte in der ausgangsituation nicht hinziehen, weil dort eine Figur gleicher Farbe stand.
8 | | | | | | | | | - - - - - - - - 7 | | | | | | | | | - - - - - - - - 6 | | | | | | | | | - - - - - - - - 5 | |b| | | | | | | - - - - - - - - 4 | | |r| | | | | | - - - - - - - - 3 | | | |K| | | | | - - - - - - - - 2 | | | | | | | | | - - - - - - - - 1 | | | | | | | | | - - - - - - - - A B C D E F G H
König auf D3 kann nicht auf C4 ziehen, weil der Bauer auf B5 dieses Feld schützt. In dieser Ausgangssituation ist C4 für den Bauer aber eben noch nicht erreichbar.
Umgesetzt: Mögliche Züge für König ermitteln, Historystack puschen (Zug simulieren), schauen ob König bedroht, Stack popen und Zugvorschlag verwerfen.
-
Hallo µ,
genau so meinte ich es ja, d.h. man führt den Zug aus (d.h. simuliert ihn) und überprüft dann, ob der König bedroht ist (und bei einem Zug des Königs selbst wird natürlich auf dessen neue Position überprüft).