002
05.01.2005, 22:58 Uhr
Kuriosus
|
So, ich hab an dem Projekt weitergewerkelt, und auch die Zieldatei des Links aktualisiert. (Ausserdem eine Funktion zum SEHR zügigen Aufstellen der Steine)
Der Fehler mit dem plötzlichen Aufhängen war die Folge eines logischen Fehlers meinerseits, der während der Generierung der Aufstellung der Steine des Computers (sehr selten, aber doch) auftreten konnte. Mittlerweile ausgemerzt. Trotzdem danke für den Hinweis.
Vor allem am 'KI', wie du es nennst, hab ich eine Menge verbessert, so stürmt das Programm nicht mehr wie entfesselt drauf los, sondern umgeht kurzzügige Fallen (ziemlich geschickt, nur auf wirklich gute Fallen fällt es nach wie vor herein). Ich habe schon früher einmal eine Schachvariante umgesetzt, und habe feststellen müssen, dass Stratego doch total anders ist. Beim Schach kennt das Programm zu jedem Zeitpunkt jeden auf dem Brett befindlichen Stein und die mit verknüpften Zugvektoren, was es theoretisch erlaubt, den Rechner in eine beliebige taktische Rechentiefe vordringen zu lassen, solange man als Programmierer brav auf den zur Verfügung stehenden Hauptspeicher achtet. Beim Stratego dachte ich ursprünglich, ähnlich an die Lösung herangehen zu können (Für jeden gefundenen regelgerechten Zug generiere ein Duplikat des aktuellen Brettes, führe darauf den Zug aus, bewerte die Stellung, speichere die Bewertung. Mach das mit jedem möglichen Zug und führ dann den Zug aus, der die beste Bewertung erzielt hat). Mittendrin, zu meiner Schande, bemerkte ich, dass es beim Stratego nicht möglich ist, gegnerische Antworten einzukalkulieren, da zum Teil nicht einmal bekannt ist, welche Zugvektoren mit den betreffenden Steinen verknüpft sind. Nach spätestens einem Halbzug (dem eigenen) Halbzug Rechentiefe muss die Methode, die bei Schach (auch bei Vier gewinnt und ähnlichen Spielen, bei denen jede mögliche Antwort des Gegners vorausgesehen kann) so gut klappt, eben bei Stratego nicht klappt.
Meine Computerzugfunktion speichert zuerst jeden nach den Regeln zulässigen Zug in einem ziemlich grossen Array: Vektor hilfsvektorarray[2][200], wenn der erste Index 0 ist, ist das Startfeld gemeint, wenn er 1 ist, das Zielfeld.
Dann ruft die Funktion eine Filterfunktion auf, die erstmal ganz grobe Schnitzer aus den gefundenen möglichen Zügen entfernt, (sofern immer noch zumindest ein möglicher Zug überbleibt, natürlich!)
Dann kriegt eine andere Funktion das möglicherweise schon geschrumpfte Array mit möglichen Zügen in die Finger und prüft, ob sie unter den möglichen Zügen einen Zug entdeckt, der unbedingt notwendig ist und Priorität vor allen anderen Zügen hat. In diesem Fall entfernt die Funktion alle anderen Züge aus dem Array mit den möglichen Zügen mit Ausnahme des 'unbedingt notwendigen' Zuges (dringende Fluchtzüge und dergleichen)
Wenn nach Aufruf der beiden vorhergehenden Funktionen immer noch jede Menge Züge im Array gespeichert sind, sucht das Programm eine Möglichkeit, möglichst irgendetwas zu schlagen.
Falls es dann immer noch nicht erfolgreich war, bekommen sämtliche Züge, die eine Vorwärtsbewegung ins gegnerische Lager bedeuten, Priorität (darum erscheint das Programm etwas ungestüm).
Falls dann immer noch kein sinnvoller Zug gefunden wurde, macht rand() hoffentlich noch das beste daraus.
Ziemlich genau so operiert die Computerzugfunktion, und mich überrascht selbst, dass das Programm in wenigen Millisekunden Dutzende Schleifen durchläuft und auch noch die Anzeige auf dem Bildschirm updatet.
*** Trotzdem danke für die Motivation, so schnell werf ich nicht das Handtuch!!!*** Dieser Post wurde am 05.01.2005 um 23:00 Uhr von Kuriosus editiert. |