Codeausführung unterbrechen und auf Event warten
-
Hehe irgendwie habe ich das Gefühl wir reden aneinander vorbei XD
Ich verusch die Situation noch mal zu erklären:
Es gibt vier Spieler 3 x CPU und 1 x menschlich.
Ich habe eine Klasse NewGame. In dieser Klasse, so habe ich es mir Gedacht, wird es eine Methode geben die eine neue Runde des Spiels beihaltet. Eine Runde kann man vergleichen mit einer Hand beim Poker.
Diese Methode habe ich mir folgendermaßen überlegt:
NeueRunde() { CPU1.PlayCard(); // Der erste CPU Spieler legt eine Karte auf den Tisch CPU2.PlayCard(); // Der zweite CPU Spieler kann anhand interner Klassenmehtoden entscheiden welche Karte er auf den Tisch legt und tut dies //Jetzt kommt der menschliche Spieler ins Spiel. //Er hat keine Methoden die für Ihn entscheide welche Karte gelegt wird, //sonst wäre das Spiel ja auch langweilig. Er kann durch anklicken einer //Karte in seiner Hand entscheiden was er spielen will. //Wie kann ich hier angeben das der Spieler jetzt dieses Click_Event //ausführen muss und es kann erst weitergehen, wenn das passiert ist? CPU3.PlayCard() // Der dritte CPU-Spieler entscheide wieder mit seinen Methoden welche Karte er spielen soll // Jetzt wird noch alles ausgewertet und die Punkte werden verteilt. }
Mein Denk/Lösungsproblem liegt an der Stelle, an der der mesnchliche Spieler SELBER entscheiden muss welche Karte er spielt. Das kann er natürlich durch ein Click_Event machen. Im Eventhandler des Click_Events wird das dann verabreitet und die Karten "auf den Tisch" gelegt.
-
Erstell einfach ein IPlayer interface, dies bietet ein Property "IsKI" oder ähnliches.
In der methode zur steuerung des "NextPlayer" (Kann ja variieren wer als nächstes dran ist) wird dann unterschieden, wenn IsKI == true dann wird CalculateCard() aufgeufen und das ruft dann wieder NextPlayer auf, am sonsten passiert nichts und es geht erst weiter nachdem der Benutzer eine Karte oder den Stapel anklickteHmmm das klingt sehr interessant, da werd ich noch etwas drüber nachdenken müssen damit ich ganz verstehe. Habe schon länger nichts mehr mit Interfaces zu tun gehabt...
-
Du könntest ein modales Fenster öffnen in dem der Spieler die zu spielende Karte auswähle oder pollen ob die nächste Karte auf dem Stapel gelegt wurde.
-
Oder noch einfacher Du setzt einfach ein Flag welches dir anzeigt ob der Player schon
seine Kartren ausgespielt hat. Dieses Flag (einfache zb. ein bool bPlayed) kannst Du
dann in den CPU spielern abragen, und diese Spielen nur aus wenn es true ist.bsp:
bool bPlayed = false; // in deiner Funktion bim CPU Player dann einfach: if(bPlayed) { CPUPlayer1Play(); CPUPlayer2Play(); bPlayed = false; } Player3Play(); // Hier spielst Du aus if(bPlayed) { CPUPlayer3Play(); }
-
Du musst doch auch noch entscheiden können was beim aussetzen passiert...
Solch eine feste "kontroll-methode" ist eine schlechte idee.Spiel Startet:
var player = GetFirstPlayer();
player.Proceed();und in der Proceed klasse wird entschieden was als nächstes passiert, entweder "CalculateCard()" wenn es ein KI player ist, oder nichts wenn es ein Menschlicher Spieler ist.
Sobald ein Mensch drann ist, geht es erst in der Click Methode weiter.Hier mal etwas Pseudo code:
public interface IPlayer { public bool IsKI { get; set; } public void Proceed(); } public class HumanPlayer : IPlayer { public bool IsKI { get; set; } public void Proceed() { } } public class KIPlayer : IPlayer { public bool IsKI { get; set; } public void Proceed() { CalculateCard(); TableManager.NextPlayer(); } } public class TableManager { public void NextPlayer() { ActivePlayer = Players[2]; ActivePlayer.Proceed(); } } List<IPlayer> Players = new List<IPlayer>(); Players.Add(new HumanPlayer()); Players.Add(new KIPlayer()); Players.Add(new KIPlayer()); Players.Add(new KIPlayer()); Players.First().Proceed();
Mit ein bischen überlegen und intelligendes abstraieren, kümmern sich die Objekte automatisch darum was wie als nächstes passiert.
Nicht einfach drauf los Programmieren und alles in die CodeBehind packen wie es gerade passt!PS. Ich habe auch schon ein Kartenspiel implementiert (MauMau in allen möglichen Regeln, alles einstellbar, auch Spieler Anzahl) das Projekt ist derzeit durch andere Prioritäten aber eingefrohren.
-
Erst mal Danke für alle Antworten!
Je öfter ich Deinen Vorschlag lese und je mehr ich darüber nachdenke, desto mehr verstehe ich es
Danke CSL
Wenn das Projekt fertig ist (spätestens 25.03) werde ich berichten, wie ich es tatsächlich gelöst habe.
Gruß
Markus
-
Hallo Gamester,
generell mußt du bei der GUI-Programmierung ereignisorientiert programmieren (event-based), d.h. du mußt die Aktionen in viele kleine Methoden packen.
Der Ansatz von CSL ist in Ansätzen schon mal gut, du mußt dann nur noch einen 'CurrentPlayer' im TableManager deklarieren, der dann je nach erfolgreicher Aktion (KI bzw. Button-Click) weitergesetzt wird.public class TableManager { int CurrentPlayer = 0; public void NextPlayer() { CurrentPlayer++; if(CurrentPlayer >= Players.Count) CurrentPlayer = 0; IPlayer ActivePlayer = Players[CurrentPlayer]; ActivePlayer.Proceed(); } }
Und beim Button-Click mußt du dann entsprechend die Karte ausspielen und auch NextPlayer aufrufen (d.h. im Prinzip wie bei KIPlayer.Proceed).
Weitere Aktionen kannst du dann in NextPlayer integrieren (d.h. wenn alle Spieler ihre Aktionen ausgeführt haben oder wenn Spielende ist etc.).
P.S: Für C++ (und der Borland VCL) hätte ich dir ein selbstgeschriebenes Framework empfehlen können:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-193889-and-highlight-is-.html
(Th war mein alter Account - extra eingefroren bei 1442 Beiträgen!)
-
Gamester schrieb:
SpielMethode() { CPU1.PlayCard(); CPU2.PlayCard(); //Spieler muss Karte spielen und kann diese durch anklicken wählen CPU4.PlayCard(); }
definiere doch einfach den Spielablauf etwas um
SpielMethode() { //Spieler muss Karte spielen und kann diese durch anklicken wählen CPU4.PlayCard(); CPU1.PlayCard(); CPU2.PlayCard(); }
somit hast Du schon mal den Spieler an erster Stelle ... mit etwas "Substitution" kannst Du auch folgendes machen
//Spieler muss Karte spielen und kann diese durch anklicken wählen computer[0].PlayCard(); // CPU 4 - Spieler 4 computer[1].PlayCard(); // CPU 1 - Spieler 1 computer[2].PlayCard(); // CPU 2 - Spieler 2
dann muss Du in der Form nur auf den entsprechenden Klick auf die Karte (Button?PictureBox?...) warten ... anschließend rennst Du mit den CPU-Spieler durch
public void Click_KarteXX(/* ... */) { legeSpielerKarte(); for(int i = 0; i < 3; i++) compuer[i].PlayCard(); }
hand, mogel
-
Was ich bereits schrieb ist natürlich nur ein Teil des ganzen, und war nur Pseudocode.
Ich habe leider mein Ablaufdiagramm von meinem MauMau nicht mehr, eventuell bekomm ich es noch zusammen:1. Beim Spiel start, erstelle Kartenstapel
Jede Karte bekommt ihre eigene Regel zugeordnet (2 ziehen) und ihre dazugehörige auflösung (blocken, weitere 2 ziehen Karte)
Das alles je nach Settings.2. Spieler werden erstellt.
3. Es wird ermittelt welcher Spieler anfängt
4. Next Player wird aufgerufen
5. Next Player ermittelt wer dran ist, und ruft dessen Ausfürhungsmethode auf
6. In der Ausfürhungsmethode wird geschaut ob es eine KI ist, wenn nein passiert nichts, wenn ja
6a. Gewünschte Karte ermitteln
6b. Karte als Put Request an den Tisch schicken7. Wenn ein Spieler auf eine Karte oder den Stapel Klickt
7a. Ist der Spieler drann?
7b. Karte als Put Request an den Tisch schicken8. Der RuleManager prüft ob die gewünschte Karte gelegt werden darf, dazu fragt er einfach die Karte ob sie mit der Neuen Karte aufgelöst werden kann und antwortet entsprechend.
9. Karte wird gelegt, dabei wird die Aktive Regel entweder erweitert (Statt 2 jetzt 4 ziehen) oder aufgelöst (Es wurde gezogen, dh 2 ziehen gilt nicht mehr) oder eine neue Regel gesetzt
10. Next Player wird aufgerufen
Note:
- Next Player prüft auch immer ob das Spiel beendet ist.
- Die KI simuliert in einem eigenen Thread eine Wartezeit, damit man sieht das noch etwas Passiert.
- Alle Methoden sind am ende sehr kurz, und die eingestellten Rules kümmern sich alle selber um ihr zeug, so hat man auch keine if else ketten
- Auf solchen wegen kann man belibige Regeln ein und aus schalten, bis hin zur Spieler anzahl.
-
So ich muss mich nochmal bei allen bedanken, speziell bei CSL!
Habe eben mal ein kleines Testprojekt geschrieben und es funktioniert wunderbar! Genau so wie ich mir das vorgestellt habe
Manchmal muss man eben in die richtige Denkrichtung geschubst werden, wenn man sich zu sehr auf einen Lösungsweg versteift hat.
Ich wäre wohl im Leben nicht auf die Lösung durch ein Interface gekommen, obwohl es so nahe liegt... Naja wie Loddar so schön sagt: "Ägän wot lörnd!"
-
Das Projekt für die Schule, ist das auf freiwilliger basis? Wird es bewertet? Schreibst du alles allein? Hast du Grafiken der Karten in verwendung?
-
Wir konnten entscheiden, ob wir eine Schulaufgabe oder ein Projekt machen wollen. Wir haben uns für das Projekt entschieden (trotz Abendschule und dadurch sehr wenig Zeit...). Jeder macht ein eigenes Projekt in etwa der selben Größenordnung.
Ja, ich habe die Kartengraphiken, hab sie mir extra eingescannt und in PS bearbeitet.
Projekt wird nach Punkten bewertet. Folgendes gibt Punkte:
Pflichtenheft.
Fallbeispiele.
Klassendiagramme.
Dokumentation.
Lauffähiges Programm.
Code.Ob das jetzt alles war, kann ich nicht 100%ig sagen, da der Zettel zu Hause liegt. Wie die Punkteverteilung ist staht da ebenfalls drauf.
Ja, ich mache das Projekt alleine.