Servus,
ich möchte eine minimax Funktion erstellen. Es funktioniert auch aber
irgendwie finde ich die Lösung nicht befriedigend.
Ein array ist global definiert:
1
uint8_tfield[ROW][COL];
Dieses muss in der minimax Funktion copiert werden. Das Problem hierbei
ist, dass ich dann bei jeder Methode den neuen Pointer des arrays
mitübertragen muss.
Das sind noch mehr Funktionen, welche ich ändern muss. Der Code stammt
aus java. Dort hat man nur n.move() geschrieben. Voila.
Kann man eine Funktion schreiben, indem man den globalen field
array/Pointer ändert und wieder rückgängig macht? Was ist sicherer?
imperator schrieb:> Kann man eine Funktion schreiben, indem man den globalen field> array/Pointer ändert und wieder rückgängig macht?
Man kann. Aber kannst Du das?
Und hinter n.move() steckt auch nur etwas unbefriedigendes.
Danke erstmal für die Antworten.
Um das Problem klarer zu beschreiben. Es ist ein globales array
definiert. "field[][]". Viele Funktionen greifen auf diese globale
Variable zu allerdings ohne Parameter field.
In einer Funktion muss diese globale array lokal iterativ kopiert
werden. Dadurch müssen viele Funktionen geändert werden. Man muss immer
dieses field Parameter dazuschreiben.
Vielleicht ist es bei c auch der richtige Weg um so vorzugehen.
imperator schrieb:> Es ist ein globales array definiert. "field[][]". Viele Funktionen> greifen auf diese globale Variable zu allerdings ohne Parameter field.
Das ist halt ein lausiges Design.
Du kopierst in dieser Anwendung das Spielfeld normalerweise gar nicht,
sondern Du machst in der Interationsschleife über die Züge einfach jeden
Zug in diesem Feld, so wie es Deiner minimax-Methode übergeben wird, und
machst ihn dann wieder rückgängig.
Eventuall brauchst Du dazu noch einen Zustands-Stack, weil z.B. bei
Schach ein Königszug das Recht auf Rochade verwirken kann - das siehst
Du bei der reinen Rücknahme dem Zug selber aber nicht mehr an.
Achim S. schrieb:> Wie sieht es denn jetzt aus?
Lausig laut Admin.
Ich mache das hier ja nur aus Spaß.
Ist schon interessant bei der minimax Funktion in die "Zukunft" zu gehen
und alle möglichen Züge zu bewerten und das Beste rauszupicken. Dabei
sollte aber das Programm nicht zusammenfallen. Ich melde mich dann noch,
falls ich nichtweiter komme. Danke an für die rege Beteiligung.
imperator schrieb:> Deswegen frage ich ja nach. Wie sollte es besser ausehen?
Keine globalen Variablen verwenden, sondern alle Funktionen so
schreiben, daß alle relevanten Informationen (Adresse des Arrays und
Größeninformationen) den Funktionen übergeben werden. In den Funktionen
selbst sollten keinerlei Informationen verwendet werden, die nicht in
ihrer Argumentenliste stehen.
Dann kann man die Funktionen problemlos wiederverwenden, dann könnte man
auch ein verändertes Programm mit zwei oder mehreren zu bearbeitenden
Arrays schreiben und müsste nur beim Aufruf der Funktionen das konkret
zu nutzende Array angeben.
Rufus Τ. F. schrieb:> Keine globalen Variablen verwenden, sondern alle Funktionen so> schreiben, daß alle relevanten Informationen (Adresse des Arrays und> Größeninformationen) den Funktionen übergeben werden. In den Funktionen> selbst sollten keinerlei Informationen verwendet werden, die nicht in> ihrer Argumentenliste stehen.
Riesige Argumentenlisten sind aber nicht gerade guter Stil,
unübersichtlich und leicht fehleranfällig. Vermeiden lässt sich das
durch geeignete Strukturen und jeweils einem Pointer auf diese Struktur,
der übergeben wird.
Das ist dann Objektorientierung zu Fuß.
Auf welche Art und Weise die Parameter übergeben werden, ist natürlich
eine Frage der Übersichtlichkeit, sie aber in eine Struktur zu verpacken
und das dann "Objektorientiert" zu nennen, ist ein bisschen arg
hochtrabend.
Entscheidend aber ist das auch dann erreichte Ziel, keine globalen
Variablen zu verwenden, und alle relevanten Informationen den jeweiligen
Funktionen zu übergeben.
Servus,
Danke erstmal. Ich versuche mit Strukturen als Pointer Übergabe Herr zu
werden.
Ich bin heute auswärts und habe gestern abends noch mit
Harddefaulthandler zu tun. Aufgrund der Rekursion bekomme an 2. Ebene
diesen Fehler beim return.
Wie muss man die Variablen in der rekursiven Funktion deklarieren? Ich
habe heap und Stack großzügig erhöht. Beim cortex m3 dürfte ich keine
Ressourcen Probleme bekommen. Ich benutze embitz.
Wie kann ich anhand der map Datei eine mögliche Kollision erkennen?
Sollte man beim Aufruf alle Interrupts deaktivieren?
imperator schrieb:> Aufgrund der Rekursion bekomme an 2. Ebene> diesen Fehler beim return.
Du mußt natürlich dafür sorgen, daß die Rekursion auch terminiert!
Typischerweise bekommt die minimax-Funktion einen Parameter für die
Tiefe und prüft ganz zuerst, ob die übergebene Tiefe <= 0 ist. Falls dem
so ist, ruft sie eine Art statischer Stellungsbewertung auf und gibt
deren Wert zurück.
Falls die übergebene Tiefe > 0 ist, ruft minimax beim rekursiven Aufruf
sich selbst auf, aber mit Tiefe um 1 weniger als das, was ihr übergeben
wurde.
Wenn ich mir die Deklaration Deiner Funktion ansehe, dann ist da kein
Parameter für die Tiefe. Daher vermute ich, daß Deine Rekursion nicht
terminiert, sondern solange tiefer geht, bis Dein Stack überläuft - egal
wie groß Du den machst.
Servus,
Danke erstmal für die tollen Tipps. Der Fehler bei lag an einer flachen
Kopie. Mit memcpy() wird in der 2. Ebene die Rücksprungaddresse vom 1.
Pointer überschrieben. Bei structs kann man eine tiefe Kopie einfach mit
den Zuweisungoperator bewerkstelligen.
Hier die Quelle zum nachlesen:
http://blog.zhangliaoyuan.com/blog/2013/01/28/structure-assignment-and-its-pitfall-in-C-language/