Hallo!
folgende Situation (bei mir ists nicht genau dieselbe, aber von der Art her schon):
angenommen ihr wolltet TicTacToe programmieren. Dargestellt wird das ganze über UI/Swing. Geleitet wird das Spiel von einer Spielleiterklasse, die den einzelnen Spieler-Objekten sagt, wann sie ihren Zug machen sollen, Siege zählt, die GUI-Methoden zur Darstellung des Spielgeschehens aufruft, etc.
Die Spieler sollen entweder menschlich sein (Eingabe über GUI) oder vom Computer gesteuert (die KI berechnet den Zug). Dazu habe ich eine abstrakte Player-Klasse geschaffen, die angibt, welche Methoden ein Player haben muss und zusätzlich die für beide Player-Arten gemeinsamen Methoden zur verfügung stellt (zB getName(). Von dieser Klasse abgeleitet gibts dann HumanPlayer und AIPlayer.
bei player.itsYourTurn() berechnet im einen Fall die KI den Zug, beim anderen klickt der menschliche Spiele mit der Maus auf ein leeres Feld, um sein Kreuzchen zu machen.
jetzt mein Problem:
zunächst hatte ich bei itsYourTurn() einfach den Rückgabe-Wert abfragt. wenn die KI aber länger berechnet, dann blockiert in der Zeit das System (also zB. kann ich keine Buttons klicken) - das liegt wohl daran, dass das alles noch im selben Thread ist...
Noch viel schlimmer ists bei HumanPlayer: der erwartet ja eine Eingabe vom Spieler, das System blockiert aber total (wohl weils in der Schleife gefangen, die abfragt, ob schon eine Eingabe gemacht wurde)...
das ist so nicht recht schön, also hab ich mir gedacht, es gibt einfach keinen rückgabewert. itsYourTurn sagt dem Spieler-Objekt nur, dass es dran ist. ich habe ein eigenes Event-System gemacht (also eigenes Event-Object, EventListener Interface). Player castet einen Event, wenn eine Entscheidung getroffen wurde.
leider habe ich beim programmieren entdeckt, dass das ganze EventSystem auch nicht mehr ist, als dass die Player-Objekte ihre Spielleiter-Klasse kennen und eine Methode (in dem Fall processEvent(event) aufrufen)).
das stört mich deshalb, weil ich dann ja wieder die Methode aufrufe, aus der ich schon gekommen bin:
play() ruft player.itsYourTurn() auf, was wiederum direkt (oder eben über umwege mit events) play() aufruft...
(eben eine klassische situation für returnwerte...)
das "neue" play() ruft das nächste itsYourTurn() auf, das dann wieder play() etc... ich glaube das sollte man nicht machen, denke da kann es auch zu nem StackOverFlow kommen...
trotzdem: wenn ich itsYourTurn() nun aber in die run() methode von Player schreibe, und Player als zweiten Thread starte, funktioniert auch die Eingabe über GUI (wohl weil der andere Thread nicht mehr blockiert ist).
ich habe jetzt aber ganz seltsame errors. ohne zeilenangabe... und ich kann sie mit debug-meldungen nicht lokalisieren, wei sie immer woanders zu sein scheinen. ich schätze mal das liegt an der nicht vorhandenen synchronisation...
wenn ich itsYourTurn() nicht wieder play() aufrufen lassen, dann müsste play von außen gestartet werden. ich denke da jetzt an einen TimerThread, der sagen wir alle 500ms prüft, ob der spieler schon seine wahl getroffen hat und dann eben play aufruft. ich würde mir auch ansehen, ob ich etwas mit synchronized machen kann...
davor würde ich aber gerne wissen, ob man sowas nicht komplett anders macht bzw wie es ihr machen würdet! (also ob ich am richtigen weg bin oder da totale design-feher drinstecken)
---------------------
und ich habe noch ein verständnisproblem zu threads bzw der ausführung von java-programmen:
1 Thread arbeitet einfach den code ab, right? ist daher immer genau in einer Zeile einer Methode einer Klasse.
wenn ich also itsYourTurn() aufrufe, dann springt java in die itsYourTurn() methode und geht - egal ob auf einen return-wert gewartet werden muss oder nicht - zuerst nur diese neue Methode durch und in der ursprünglichen klasse gehts erst weiter, wenn diese methode fertig abgearbeitet wurde. right?
wenn ich jetzt 2 threads habe, laufen die parallel ab. aber das geht dann auch innerhalb von 1er klasse oder? sprich es könne beide threads methoden einer klasse abarbeiten oder gar dieselbe, right?
das wäre bei mir wohl der fall. für sowas brauch ich dann synchronisation oder?
naja, ich denke ich kann mein kleines Problem lösen, aber ich würde eben gerne wissen, wie man es richtig macht. danke auf jeden fall fürs lesen
folgende Situation (bei mir ists nicht genau dieselbe, aber von der Art her schon):
angenommen ihr wolltet TicTacToe programmieren. Dargestellt wird das ganze über UI/Swing. Geleitet wird das Spiel von einer Spielleiterklasse, die den einzelnen Spieler-Objekten sagt, wann sie ihren Zug machen sollen, Siege zählt, die GUI-Methoden zur Darstellung des Spielgeschehens aufruft, etc.
Die Spieler sollen entweder menschlich sein (Eingabe über GUI) oder vom Computer gesteuert (die KI berechnet den Zug). Dazu habe ich eine abstrakte Player-Klasse geschaffen, die angibt, welche Methoden ein Player haben muss und zusätzlich die für beide Player-Arten gemeinsamen Methoden zur verfügung stellt (zB getName(). Von dieser Klasse abgeleitet gibts dann HumanPlayer und AIPlayer.
bei player.itsYourTurn() berechnet im einen Fall die KI den Zug, beim anderen klickt der menschliche Spiele mit der Maus auf ein leeres Feld, um sein Kreuzchen zu machen.
jetzt mein Problem:
zunächst hatte ich bei itsYourTurn() einfach den Rückgabe-Wert abfragt. wenn die KI aber länger berechnet, dann blockiert in der Zeit das System (also zB. kann ich keine Buttons klicken) - das liegt wohl daran, dass das alles noch im selben Thread ist...
Noch viel schlimmer ists bei HumanPlayer: der erwartet ja eine Eingabe vom Spieler, das System blockiert aber total (wohl weils in der Schleife gefangen, die abfragt, ob schon eine Eingabe gemacht wurde)...
das ist so nicht recht schön, also hab ich mir gedacht, es gibt einfach keinen rückgabewert. itsYourTurn sagt dem Spieler-Objekt nur, dass es dran ist. ich habe ein eigenes Event-System gemacht (also eigenes Event-Object, EventListener Interface). Player castet einen Event, wenn eine Entscheidung getroffen wurde.
leider habe ich beim programmieren entdeckt, dass das ganze EventSystem auch nicht mehr ist, als dass die Player-Objekte ihre Spielleiter-Klasse kennen und eine Methode (in dem Fall processEvent(event) aufrufen)).
das stört mich deshalb, weil ich dann ja wieder die Methode aufrufe, aus der ich schon gekommen bin:
play() ruft player.itsYourTurn() auf, was wiederum direkt (oder eben über umwege mit events) play() aufruft...
(eben eine klassische situation für returnwerte...)
das "neue" play() ruft das nächste itsYourTurn() auf, das dann wieder play() etc... ich glaube das sollte man nicht machen, denke da kann es auch zu nem StackOverFlow kommen...
trotzdem: wenn ich itsYourTurn() nun aber in die run() methode von Player schreibe, und Player als zweiten Thread starte, funktioniert auch die Eingabe über GUI (wohl weil der andere Thread nicht mehr blockiert ist).
ich habe jetzt aber ganz seltsame errors. ohne zeilenangabe... und ich kann sie mit debug-meldungen nicht lokalisieren, wei sie immer woanders zu sein scheinen. ich schätze mal das liegt an der nicht vorhandenen synchronisation...
wenn ich itsYourTurn() nicht wieder play() aufrufen lassen, dann müsste play von außen gestartet werden. ich denke da jetzt an einen TimerThread, der sagen wir alle 500ms prüft, ob der spieler schon seine wahl getroffen hat und dann eben play aufruft. ich würde mir auch ansehen, ob ich etwas mit synchronized machen kann...
davor würde ich aber gerne wissen, ob man sowas nicht komplett anders macht bzw wie es ihr machen würdet! (also ob ich am richtigen weg bin oder da totale design-feher drinstecken)
---------------------
und ich habe noch ein verständnisproblem zu threads bzw der ausführung von java-programmen:
1 Thread arbeitet einfach den code ab, right? ist daher immer genau in einer Zeile einer Methode einer Klasse.
wenn ich also itsYourTurn() aufrufe, dann springt java in die itsYourTurn() methode und geht - egal ob auf einen return-wert gewartet werden muss oder nicht - zuerst nur diese neue Methode durch und in der ursprünglichen klasse gehts erst weiter, wenn diese methode fertig abgearbeitet wurde. right?
wenn ich jetzt 2 threads habe, laufen die parallel ab. aber das geht dann auch innerhalb von 1er klasse oder? sprich es könne beide threads methoden einer klasse abarbeiten oder gar dieselbe, right?
das wäre bei mir wohl der fall. für sowas brauch ich dann synchronisation oder?
naja, ich denke ich kann mein kleines Problem lösen, aber ich würde eben gerne wissen, wie man es richtig macht. danke auf jeden fall fürs lesen