Laden...

Warum mal Hangman-Spiel bei jedem Buchstabendruck oder gar nicht mehr?

Erstellt von axelfxxx vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.016 Views
axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren
Warum mal Hangman-Spiel bei jedem Buchstabendruck oder gar nicht mehr?

Hallo an Alle 😉

Aus lauter Langeweile hab ich mir mal das Spiel Hangman vorgenommen... (Ich weis dies gibts schon tausend mal)

Zum Programm: Ich lese eine Textdatei ein, welche mit Fragen und Antworten gefüllt ist. Der AW kriegt die Frage zu sehen, und in einer Listview ist die Antwort maskiert mit "". Die Antwort wird in Buchstaben zerstückelt und in item.Tag hinterlegt.
Wenn der AW also nun einen falschen Buchstaben drückt (Buttons mit ClickEvent, welche bei jedem Click die Function CheckAufSieg abfragt), soll ein erster Balken gemalt werden. Ich habe nun gedacht: Wenn es keins mehr von den "
" da ist, hat man gewonnen, im anderen Fall wenn ein falscher Buchstabe hinter item.Tag steckt das dann ein Balken konmt.
Aber entweder malt der den Balken jetzt bei jedem Buchstaben, oder gar nicht !? Wo ist der Fehler?

Danke für die Hilfe ...


 private void CheckAufSieg()
        {
             ListViewItem itemx = listView1.FindItemWithText("__");
             if (itemx == null)
             {
                 MessageBox.Show("Gewonnen");
             }
             else if (itemx.Tag.Equals("__"))
             {
                 Galgen(galgenzaehler);
             }
        }

//und dies ist mein Galgen

private void Galgen(int Zustand)
        {
            Graphics g = pictureBox1.CreateGraphics();
            switch (Zustand)
            {
                case 1:
                    //unterster Balken
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 200, 600, 20, 600);
                    break;
                case 2:
                    //LinkerBalken
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 20, 600, 20, 200);
                    break;
                case 3:
                    //1. Balken oben
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 200, 200, 20, 200);
                    break;
                case 4:
                    //Strick
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 200, 200, 200, 250);
                    break;
                case 5:
                    //der Kopf
                    //1.nach rechts
                    //2.Höhe von oben
                    _ = pictureBox1.CreateGraphics();
                    g.DrawEllipse(new Pen(new SolidBrush(Color.Red), 12), new RectangleF(190, 245, 20, 20));
                    break;
                case 6:
                    //Hals
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 200, 300, 200, 270);
                    break;
                case 7:
                    //der Körper
                    //1.nach rechts
                    //2.Höhe von oben
                    _ = pictureBox1.CreateGraphics();
                    g.DrawEllipse(new Pen(new SolidBrush(Color.Red), 12), new RectangleF(190, 300, 20, 50));
                    break;
                case 8:
                    //erster Arm links
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 150, 240, 200, 330);
                    break;
                case 9:
                    //zweiter Arm rechts
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 250, 245, 200, 330);
                    break;
                case 10:
                    //erster Bein links
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 190, 330, 130, 400);
                    break;
                case 11:
                    //zweites Bein rechts
                    _ = pictureBox1.CreateGraphics();
                    g.DrawLine(new Pen(new SolidBrush(Color.Red), 12), 300, 380, 210, 330);
                    break;
            }

        }

//Wenn z.B. der A Buton gedrückt wird ...
private void Btn_A_Click(object sender, EventArgs e)
        {
            galgenzaehler += 1;
            foreach (ListViewItem items in listView1.Items)
            {
                if (!items.Tag.Equals("a") | items.Tag.Equals("A"))
                {   
                    
                    Galgen(galgenzaehler);
                }
                else
                {
                    items.Text = "A";
                    CheckAufSieg();
                }
            }
        }


---- >
Keine Signatur 😉

H
523 Beiträge seit 2008
vor 3 Jahren
axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Hier steht die Lösung:
>

Danke aber das war nicht meine Frage ... Mir fiel bei der Wahl des Titels nichts besseres ein, aber es geht nicht darum, das die PictureBox nicht richtig zeichnet, sondern das ich irgendwie einen Fehler in der Interaktion mit den Funktionen der Buttons und der Zeichnung des Galgens habe.

---- >
Keine Signatur 😉

J
251 Beiträge seit 2012
vor 3 Jahren

Würde meinen, dass Dein If in der Buchstaben-Prüfung nicht so arbeitet, wie gedacht.

Hätte eher folgendes erwartet:


if (!items.Tag.Equals("a") || !items.Tag.Equals("A"))

bzw.


if (!items.Tag.ToLower().Equals("a"))

Aber die Prüfung/den Programmablauf kannst Du einfach via Debugger nach schauen: [Artikel] Debugger: Wie verwende ich den von Visual Studio?

C
2.121 Beiträge seit 2010
vor 3 Jahren

Vermutung rein vom ansehen deines Codes.
Wenn man einen Buchstaben eingibt, prüfst du für JEDE Stelle, ob sie diesen Buchstaben enthält oder nicht. Wenn nicht, zeichnest du den Galgen für JEDE falsche Stelle ein Stück weiter.
Das heißt, ein Wort mit 5 Buchstaben von denen einer der gedrückte ist, zeichnet den Galgen trotzdem um 4 Teile weiter.
Tatsächlich solltest du zuerst prüfen ob es eine Stelle mit dem Buchstaben gibt. Wenn ja, ALLE passenden Buchstaben aufdecken. Wenn nein, den Galgen um EIN Stück erweitern.

Was soll "_ = pictureBox1.CreateGraphics();" sein? Das kann m.M. raus.

axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Vermutung rein vom ansehen deines Codes.
Wenn man einen Buchstaben eingibt, prüfst du für JEDE Stelle, ob sie diesen Buchstaben enthält oder nicht. Wenn nicht, zeichnest du den Galgen für JEDE falsche Stelle ein Stück weiter.
Das heißt, ein Wort mit 5 Buchstaben von denen einer der gedrückte ist, zeichnet den Galgen trotzdem um 4 Teile weiter.
Tatsächlich solltest du zuerst prüfen ob es eine Stelle mit dem Buchstaben gibt. Wenn ja, ALLE passenden Buchstaben aufdecken. Wenn nein, den Galgen um EIN Stück erweitern.

Was soll "_ = pictureBox1.CreateGraphics();" sein? Das kann m.M. raus.

//Danke, für den Tip 😃 Intellisense spuckte mir das aus, hatte auch das Gefühl, das das doppelt gemoppelt ist.

Danke an Alle, wenn ich aber so mache:

private void Btn_A_Click(object sender, EventArgs e)
        {
            galgenzaehler += 1;
            foreach (ListViewItem items in listView1.Items)
            {
                if (items.Tag.Equals("a") || items.Tag.Equals("A"))
                {   
                  items.Text = "A";
                    CheckAufSieg();
                }
            }
        }

Dann weis ich nicht wie ich den Galgen weiter malen soll. Jetzt macht die Abfrage nämlich genau was sie soll: Sie prüft ob der Buchstabe richtig ist, für ALLE und weiter ? Ich glaube das bei CheckAufSieg der Galgen rein muss, aber ich weis gerade nicht wie ...


private void CheckAufSieg()
        {
             ListViewItem itemx = listView1.FindItemWithText("__");
             if (itemx == null)
             {
                 MessageBox.Show("Gewonnen");
             }
             else if (itemx.Tag.Equals("__"))
             {
                 Galgen(galgenzaehler);
             }
        }

---- >
Keine Signatur 😉

309 Beiträge seit 2020
vor 3 Jahren

Es wäre einfacher wenn du das mit Linq machst:
Pseudocode:


// Gibt es in der Liste noch den Buchstaben "A":
if items.Any(c => c.Tag=="A"){
// alle aufdecken
   items.Where(c=>c.Tag=="A").Select(d=>d.Text = "a")
   ...
}else{
// gibt keine in der Liste ==> eins weiter zeichnen
   Galgenzaehler++;
   ...
}

axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Danke werde ich mal trsten 😉

---- >
Keine Signatur 😉

axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Sorry ListViewItems können kein Linq, habs getestet...

---- >
Keine Signatur 😉

309 Beiträge seit 2020
vor 3 Jahren

Ja, war natürlich auch gedacht dass man das in eine eigene Klasse steckt und so die Schichten etwas trennt.

Beispiel:


interface HangmanGame()
{
   void CheckLetter(char eingabe);
   string HiddenWord; // A _ _ _ ...
   int RemainingLetters;
   bool IsGameWon;
   event EventHandler NoLettersLeft;
...
}

// Edit:
und doch, das geht schon, wenn man das denn so machen möchte:
https://stackoverflow.com/questions/6640198/linq-in-selecting-item-from-listviewitemcollections-in-c-sharp

C
2.121 Beiträge seit 2010
vor 3 Jahren

Na endlich auch hier der Hinweis "das geht auch mit Linq" 😉

axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Danke Leute für Eure Hilfe 😃

Mein Problem ist NICHT, das ich die Objekte in der Listview nicht selektieren und dementsprechen verändern /ansprechen kann sondern, das mir der Übergang vom gedrückten Buchstaben zum Sieg fehlt.

Ich denke so:
User drückt Buchstabe -> Hab ich
Code checkt ob Buchstabe vorhanden ist und deckt diesen auf -> Hab ich und nun kommts: Wie frage ich jetzt, in C# ,was passiert wenn der Buchstabe NICHT dem gedrückten entspricht ??? Wenn dann muss ich jetzt den Balken malen.


if (item.Tag.Equals("A")
/alles toll
else if not
{
  ///male den Balken
}

Ich habs mit tausend Varianten probiert )Nach meinen geringen Kenntnisstand) Aber egal wie ich den Code drehe und wende ich komme NIE dahin das er erst dann den Balken malt, wenn der Buchstabe falsch ist...

Ich weis mit Linq könnte man die Sache vereinfachen, aber es geht mir gerade nicht ums vereinfachen, sonder wie ich mit meinem Code eine Lösung hinbekomme

Ich stecke im C# nicht so drin -> leider

---- >
Keine Signatur 😉

C
2.121 Beiträge seit 2010
vor 3 Jahren

was passiert wenn der Buchstabe NICHT dem gedrückten entspricht ???

Dann wird er nicht "aufgedeckt". Ansonsten passiert erst mal nichts.

Gehen wirs mal durch. Man gibt ein A ein.
Du prüfst die erste Stelle. Die ist kein A. Wird jetzt schon der Galgen weiter gezeichnet? Nein!
Du prüfst die zweite Stelle. Die ist auch kein A. Es wird immer noch nicht gezeichnet.
Du prüfst die ... Stelle. Die ist ein A. Gut dass du den Galgen noch nicht weiter gezeichnet hast!

Oder: du hast alle Stellen geprüft und nirgends war ein A dabei. DANN kannst du den Galgen weiter zeichnen.

Während du die einzelnen Stellen durchgehst, musst du dir merken ob mindestens eine davon den eingegebenen Buchstaben enthält. Am besten in einem Bool, den du für jede passende Stelle auf true setzt.
Nach der Schleife über die Stellen weißt du dann ob dieser Buchstabe ein Treffer war.

axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Danke @ chillic

ich gehe diesen Ansatz mal durch ... Danke für die Mühe 😉

---- >
Keine Signatur 😉

axelfxxx Themenstarter:in
139 Beiträge seit 2006
vor 3 Jahren

Danke @ All

hab mir so geholfen ...

mache jetzt bei jedem Buchstaben :


private void Btn_A_Click(object sender, EventArgs e)
        {
            if (!einzelwort.ToLower().Contains(btn_A.Tag.ToString()))
            {
                Galgen(wortindex++);
            }
            else
            {
                foreach (ListViewItem items in listView1.Items)
                {
                    if (items.Tag.Equals("a") || items.Tag.Equals("A"))
                    {
                        items.Text = "A";
                        CheckAufSieg();
                    }
                }
            }
        }

---- >
Keine Signatur 😉