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 😉
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 😉
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?
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.
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 😉
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++;
...
}
Sorry ListViewItems können kein Linq, habs getestet...
---- >
Keine Signatur 😉
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
Na endlich auch hier der Hinweis "das geht auch mit Linq" 😉
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 😉
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.
Danke @ chillic
ich gehe diesen Ansatz mal durch ... Danke für die Mühe 😉
---- >
Keine Signatur 😉
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 😉