Announcement

Collapse
No announcement yet.

Mensch-ärger-dich-nicht-Projekt

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mensch-ärger-dich-nicht-Projekt

    Hi,
    ich bin seit 4 Wochen frischer Azubi und habe mir, da ich mit Delphi arbeiten werde bereits alle Grundlagen wieder hervorgeholt (habe es in der Schule gehabt) und habe mich bis zur Objektorientierung vorgearbeitet (Mit Theorie und Praxis). Nun versuche ich mit Hilfe der OOP ein kleines Mensch-ärger-dich-nicht-Spiel zu programmieren. Leider haperts an einer Stelle und ich komme patu nicht weiter und deswegen wende ich mich heute an euch

    Für eine leichtere Programmierung für mich selbst, habe ich das Projekt auf ein Minimum heruntergebrochen, da mein Fokus momentan auf der korrekten Bewegung der Figuren über das Spielfeld liegt.

    Zur Grundidee:

    Ein StringGrid dient mir als optisches Spielfeld. Im Hintergrund fülle ich ein zweidimensionales Array mit folgenden Werten:

    0 - Nicht begehbares Gebiet
    1 - Startspot
    2 - Weg
    3 - Feld vor der sicheren Zone
    4 - Sichere Zone

    0 0 0 0 2 3 1 0 0 0 0
    0 0 0 0 2 4 2 0 0 0 0
    0 0 0 0 2 4 2 0 0 0 0
    0 0 0 0 2 4 2 0 0 0 0
    1 2 2 2 2 4 2 2 2 2 2
    3 4 4 4 4 0 4 4 4 4 3
    2 2 2 2 2 4 2 2 2 2 1
    0 0 0 0 2 4 2 0 0 0 0
    0 0 0 0 2 4 2 0 0 0 0
    0 0 0 0 2 4 2 0 0 0 0
    0 0 0 0 1 3 2 0 0 0 0
    Wie habe ich nun vor die Figuren zu bewegen?:

    Mein Ansatz besteht daraus, von der Position, an der meine Figur steht nach oben, unten, links, und rechts 'zu schauen', also alle angrenzenden Feldkoodinaten zu nehmen und mit den Werten aus meinem Array zu vergleichen. Findet er eine 1, 2 oder 3 und ist die Figur noch nicht einmal rum (Fortschritt-Variable), dann bewegeRichtung(). Dabei lass ich noch schaun ob Y < oder > 5 ist sodass beispielsweise nur nach links oder nach rechts gegangen werden kann um rückwärtslaufen auszuschließen.

    Worin liegt mein Problem?:

    Probierts euch mal aus. Tragt ihr in das EditFeld eine '1' ein, so kommt ihr prima um das Feld. Setzt ihr aber etwas Größeres als 1 ein und landet zufällig auf den Feldern [0,4],[0,6] oder [6,10] zeigt mein Programm ein komisches Verhalten. Per Haltepunkte habe ich gesehen das mein Programm an diesen Punkten das Programm einmal anstandslos durchführt und dann nochmal in die Schleife geht obwohl die Startbedingung nicht mehr erfüllt wird.

    Was ich dabei garnicht verstehe: All diese Punkte an denen es hapert, sind kommende Startpunkte (1) der selben oder anderen Farbe, aber der mittlere unten bei [10,4] funktioniert einwandfrei wenn die Figur nach links geht. Allerdings kann ich keinen Fehler in den Bewegungsfunktionen finden.

    Vielleicht könnt ihr mir ja helfen, ich such derweil weiter.

    Mit freundlichen Grüßen
    Kev

    PS: Ich häng euch mal meinen Projektteil als Source an, ich habe versucht vieles so einfach wie möglich zu strukturieren und zu kommentieren damit ihr euch zurrecht findet.
    Figuren bewegen durch ein Stringgrid.zip
    PPS: Stört euch nicht an den Warnungen wegen der Rückgabewerte der Funktionen. Die brauch ich im vollen Programm, habe sie aber entfernt damit der Quelltext für mich übersichtlicher bleibt

  • #2
    Mal ein anderer Ansatz:
    für das Spielfeld eine schicke Grafik, wobei die Felder in definierten Größen (bsp. 50x50) dargestellt werden. Die Felder werden einfach von 0 - einmal rum (ich weiss jetzt nicht wieviel das sind) in einem eindim. Array abgelegt. Jede Spielfigur befindet sich auf einer Position in diesem Array. Sonderfall sind die Zielfelder. Die Bewegung ergibt sich aus der Summe des Wurfes und wird der akutellen Position raufaddiert. Ist die Summe aller getätigten Würfe der Spielfugur größe als die Anzahl der Felder ist die Figur einmal rum. Dazu gibt es eine Methode, die die Arrayposition in eine Position auf der Grafik umrechnet. Somit hast du eine bessere Darstellung, das Problem der Zulässigkeit der Bewegung entfällt usw.
    Christian

    Comment


    • #3
      Ja der Ansatz klingt redundanzfreier, da ich hier patu nicht weiterkomme werd ich mal zur Auflockerung des Tages diese variante probieren Nach dem ersten Durchdenken fallen so auch einige Funktionen weg die ich so dann nicht mehr benötige Danke für den Einfall.

      Mit freundlichen Grüßen
      Kev

      Comment


      • #4
        Ich wollt mich nochmal fix melden. So geht es wunderbar. Ist zwar ein wenig Schreibarbeit aber es lohnt sich

        Comment


        • #5
          Da ich noch an dem Projekt arbeite und momentan wieder ein wenig feststecke benutz ich ihn einfach weiter

          Zum Werdegang und Problem:

          Ich habe ein Array of TPoint, das alle meine Felder des Spielbrettes als Koordinatenwerte enthält, darüberhinaus hab ich noch ein 2. Array of TPoint das alle Zielfelder als Koordinatenwerte enthält. Meine Funktion TFigur.bewegeFigur(Felder : Integer) lotst meine Figuren durch dieses Feld (mit Umrechnungen für Blau, Grün und Gelb, damit diese am richtigen Flecke laufen). Zusätzlich dazu habe jetzt meine 16 Figuren in eine TObjectList eingepflegt und komme so ganz komfortabel an ihre Eigenschaften um Figuren beispielsweise leicht 'kicken' zu können. Ich schaffe es so auch jeweils die erste Figur eines jeden Hauses rauszusetzen und dann Feld für Feld bis ans Ende der Zielgeraden zu befördern.

          Im logischen Schluss wollte ich nun daran arbeiten die 2. Figuren zu setzen und diese dann ebenfalls das Feld durchlaufen zu lassen, nur da hängts bei mir gerade.

          Unzwar kommt in mir gerade die Frage auf, wie ich eine TObjectList gescheit nach Objekteigenschaften durchsuchen kann um beispielsweise Objekte zu finden die die Eigenschaft Farbe(String) 'rot' haben um dann von denen das Objekt mit der höchsten Position zu ermitteln. Erschlagt mich mit wenn ich den Wald vor lauter Bäumen nicht sehe

          Mit freundlichem Gruße
          Kev

          PS: Quelltext: HauptUnit.zip (D5)

          Comment


          • #6
            Die Liste durchlaufen, bei jedem Objekt prüfen, ob "Farbe" gleich rot ist, dann die Position mit dem "vorhergehenden " Rot-Treffer vergleichen. Ist die Position höher, wird diese als "vorhergehenden " Rot-Treffer gemerkt (ev. auch das Objekt dazu). Am Ende des Durchlaufes enthält der "vorhergehenden " Rot-Treffer die höchsten Daten. Zum Start wird der "vorhergehenden " Rot-Treffer mit Werten initialisiert, die garantieren, dass der erste Rot-Treffer höher ist -> bsp. -1 oder 0
            Christian

            Comment


            • #7
              Für meinen Geschmack ist der ganze Ansatz viel zu sehr UI lastig. Will ich da mal irgendwas in der UI ändern zerlegt es mir die ganze Spiellogik. Das wichtigste wäre doch erstmal das Spielbrett und den Spielzustand abstrakt in einer Codestruktur abzubilden. Irgendwo in Deinem Programm gibt es dann einen Punkt an dem sich das Spielbrett ändert (Idealerweise ein Event auf der Spielfeld Klasse) und dann renderst Du aus den Daten des Spielbretts eine neue Ansicht der UI. Die einzelnen Felder des Spielfelds könnte man dann als Klasse abbilden die verschiedene Eigenschaften hat bzw. ein gemeinsames Interface und unterschiedliche Implementierungen (Das Feld wo man reinsetzt, das Feld wo man ins "Haus" kommt, ganz normale Felder). Diese Felder kannst Du dann in einem Array oder einer Liste speichern. Die Spielfeld Klasse kümmert sich dann darum welche Figur auf welchem Feld landet (ob sie z.B. ins Haus geht oder von einer anderen Figur geworfen wird). Hast Du das mal erreicht lässt sich die UI relativ einfach implementieren und Du hast eine saubere Trennung zwischen der Anzeigelogik und der Spiellogik.

              Comment


              • #8
                So ich hab jetzt erstmal Codeoptimierungen durchgeführt die durch den Einbau der TObjectList möglich wurden. Dabei ist mein Gesamtcode um bestimmt 50% geschrumpft was mich schonmal sehr glücklich macht. Noch eine Stunde werde ich jetzt versuchen deinen Vorschlag umzusetzen Christian und wenn das nichts mehr wird habe ich für morgen meine Tagesaufgabe Hach Azubi sein ist schön :3

                PS: Ja normalerweise trenne ich auch alles in GUI, Logik und Datenhaltung. Wollte es aber rein aus Testzwecken diesmal nicht (wenn der Code zu lang oder unübersichtlich wird soll mich das animieren eine bessere Lösung zu finden und wenn sich an einer Stelle was ändert nunja, hab ich wieder nen Auftrag für den Tag)

                Comment

                Working...
                X