Eingaben in Windows Forms (C#) einrichten

@Raijin
Du meinst das :
C#:
textBox5.Text += "" + zufallszahl.ToString();
nicht orrekt ist?
Ergänzung ()

Sobald ich
Code:
textBox5.Text += "" + eingabe.ToString();
nutze, kommt bei mir der Fehler "Verwendung der nicht zugewiesenen lokalen Variablen "eingabe" "
 
Zuletzt bearbeitet:
Poste bitte den kompletten Code, da ebenfalls erwähnt wurde, dass du dies wohl in den falschen Click-Event eingebaut hast.

Du musst doch selbst wissen was button1 und button2 sind.


Der Button "Spiel starten" wird nur ein einziges Mal angeklickt, beim Start. Für den Rest des Spiels wird sein Click-Event und die Anweisungen darin daher NICHT ausgeführt, sondern erst dann wieder, wenn der Spieler das Spiel erneut startet.

Der Button "raten" wird hingegen jedes Mal betätigt, wenn der Spieler eine Zahl raten möchte. Ergo wird dieser Click-Event jedes Mal ausgeführt, wenn eine neue geratene Zahl eingelesen und bewertet wird. Nur hier existiert die Eingabe. Darüber hinaus soll die Eingabe natürlich auch nur dann in der Historie berücksichtigt werden, wenn sie überhaupt gültig ist. Das heißt, dass das Update von textBox5.Text auch nach erfolgter Eingabe sowie Prüfung gemacht werden sollte. Ansonsten gibt der Spieler ein "h", das Spiel sagt "Ey, das muss ne Zahl zwischen 1 und 10 sein" und trotzdem steht in textBox5 dann "123h".

Code:
Button_Start_Click()
      Lösche Historie
      Setze Versuchszähler auf 0
      Prüfe Grenzen
            OK
                  Setze neue Zufallszahl
            NOK
                  Fehlermeldung = Grenzen falsch



Button_Raten_Click()
      Lese Eingabe
      Prüfe Eingabe auf Gültigkeit (=Zahl)
            OK
                  Erhöhe Versuchszähler
                  Füge Eingabe zu Historie hinzu
                  Prüfe Eingabe auf Zufallszahl
                        OK
                              Gewonnen
                        NOK
                              Schade
            NOK
                  Fehlermeldung = Eingabe keine Zahl

Nach diesem Pseudocode würde der Start-Button das Spiel initialisieren (Historie+Zähler löschen) und nach Prüfung der Grenzen eine neue Lösung generieren - oder einen Fehler melden, wenn die Ober-/Untergrenze fehlerhaft sind.

Während des laufenden Spiels gibt der Spieler eine Zahl ein und klickt auf "Raten". Der Zähler wird nur dann hochgezählt, wenn der Spieler einen gültigen Versuch macht, also gültige Eingabe + Raten-Klick. Die Historie der bisherigen Versuche wird auch nur in diesem Fall um den neuen Versuch ergänzt. Das ist dadurch gewährleistet, dass sowohl Versuchszähler als auch Historie innerhalb der erfolgreichen Prüfung der Eingabe erfolgen. Ist die Eingabe fehlerhaft (= Eingabe ist keine Zahl), kommt nur die Fehlermeldung und sonst passiert nichts, kein Versuch, keine Historie.




ArrorRT schrieb:
der Fehler "Verwendung der nicht zugewiesenen lokalen Variablen "eingabe" "
Das sagt eigentlich schon alles und ist wörtlich zu nehmen. Wenn du eine Variable definierst, ihr aber keinen Wert zuweist, ist ihr Inhalt "unbestimmt". Verwendest du nun diese Variable, willst also ihren Wert auslesen, um ihn beispielsweise in eine Textbox zu schreiben, kommt eine Fehlermeldung.

Die einzige Zuweisung eines Werts für eingabe findet im TryParse in Zeile 54 statt. Da dies aber Teil eines if-Blocks ist und durch das Try eben auch nur dann ein Wert in eingabe geschrieben wird bzw. werden kann, wenn textBox1 eine gültige Zahl enthält, ist nicht sichergestellt, dass Eingabe in allen Fällen einen Wert hat.
Folglich meldet die Entwicklungsumgebung bzw. der Compiler einen Fehler, indem der Programmierer darauf hingewiesen wird, dass nicht sichergestellt ist, dass die Variable eingabe einen definierten Wert enthält.

Beispiel:

Eingabe "5". if (TryParse("5") klappt, eingabe bekommt den Wert 5. Für den folgenden Rest von button2_Click() enthält eingabe nun eine 5 und du könntest die an die Textbox schicken, alles ok.

Eingabe "h". if (TryParse("h") schlägt fehl, eingabe bekommt keinen Wert, da keine Zahl. Im folgenden Teil von button2_Click() hat eingabe nach wie vor einen undefinierten Wert --> Fehler

Da dieser Fehler aber erst zur Laufzeit tatsächlich zum Tragen kommt, der mögliche Fehler jedoch vorhersehbar ist (mehrere if-Pfade, aber nur 1 Zuweisung), meldet die Entwicklungsumgebung bzw. der Compiler einen Fehler.

Deswegen muss man dafür sorgen, dass die Variable in jedem Fall einen Wert zugewiesen bekommt, und wenn es eben auch nur eine Standard 0 ist. Dies kann zB direkt bei der Erzeugung der Variable passieren ( int eingabe = 0; ) oder entsprechend für jeden if-Pfad mit einer separaten Zuweisung.
 
Zuletzt bearbeitet:
@Raijin
Ich habe es jetzt erstmal wider so gemacht das ich die Textboxen umbenannt habe, aber im oder kann ich es nicht ohn Fehelr anpassen (warum auch immer). Auf jeden Fall habe ich den Code wieder herausgenommen also zeigt das Feld in dem de aufgelisteten Zahlen stehen sollen gerade nichts an.
hier der Code:
C#:
using System;
using System.Windows.Forms;

namespace Zahlenratespiel
{
    public partial class Form1 : Form
    {
        int obergrenze;
        int untergrenze;
        int zufallszahl = 0;
        int counter = 0;
        Random r = new Random();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private void button1_Click(object sender, EventArgs e)
        {
            lblversuche.Text = "";
            textBoxEingabe.Text = "";
            textBoxZähler.Text = "";

            if (int.TryParse(textBox3.Text, out untergrenze))
            {
                if (int.TryParse(textBox4.Text, out obergrenze))
                {
                    if (untergrenze < obergrenze)
                    {
                        zufallszahl = r.Next(untergrenze, obergrenze + 1);
                        textBoxAnzeige.Text = "Das spiel läuft";
                    }
                    else
                    {
                        textBoxAnzeige.Text = "Die Untergrenze muss kleiner als die Obergrenze sein";
                    }
                }
                else
                {
                    textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
                }
            }
            else
            {
                textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            int eingabe;
            counter += 1;
            lblversuche.Text = counter.ToString();
            if (int.TryParse(textBoxEingabe.Text, out eingabe))
            {
                if (zufallszahl > eingabe)
                {
                    textBoxAnzeige.Text = "Die Zufallszahl ist größer als die Eingabe";
                }

                else if (zufallszahl < eingabe)
                {
                    textBoxAnzeige.Text = "Die Zufallszahl ist kleiner als die Eingabe";
                }
                else
                {
                    textBoxAnzeige.Text = "Sie haben zwar gewonnen aber werden keinen Preis bekommen";
                }
            }
            else
            {
                textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
            }

        }
        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void lblversuche_Click(object sender, EventArgs e)
        {

        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
         
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
           
        }
    }
}
 
Zuletzt bearbeitet:
Mal unabhängig von den aktuellen Namen, musst du den PseudoCode aus #22 jetzt nur noch auf deinen Code übertragen. Sprich: Identifiziere die Click-Methode deines "Raten"-Buttons, suche die Stelle, an der die Eingabe auf Gültigkeit geprüft wird und füge dort die Aktualisierung der Historie hinzu.


Übrigens: Ich habe eben einen kleinen Fehler in meinem PseudoCode entdeckt, copy&paste. Die Prüfung der Eingabe in Button-Raten-Click() erfolgt ja erst auf Gültigkeit (int.TryParse()) und nicht auf Grenzen. #22 ist daher leicht editiert worden.


Ich habe gelesen, dass du erst seit Montag programmierst, aber aktuell verstehe ich noch nicht ganz wo jetzt noch das Problem liegt. Du hast zahlreiche Antworten bekommen, die die Lösung beschreiben, und ich hab dir sogar PseudoCode gepostet. Allerdings erkenne ich keinen Fortschritt bzw. keine Lösungsversuche deinerseits. Es ist aber wichtig, dass du die Lösung auch verstehst und nicht nur abtippst. Deswegen gibt es hier auch keine fertig ausprogrammierte Lösung, da dies wie bereits erwähnt auch gegen die Regeln verstoßen würde, wenn es sich um eine Hausaufgabe, o.ä. handelt.
 
@Raijin Ich möchte ja auch keine fertige Lösung, die bringt mir ja auf Dauer nichts, aber irgendwie komme ich nicht ganz dahinter.
 
Ok, dann ein paar Eckdaten zum besseren Verständnis:

Code:
Button_Start_Click()                                <- das wird button1_Click() sein.
      Lösche Historie                               <- lblversuche.Text = "";
      Setze Versuchszähler auf 0
      Prüfe Grenzen
            OK
                  Setze neue Zufallszahl
            NOK
                  Fehlermeldung = Grenzen falsch


Button_Raten_Click()                                <- das wird button2_Click() sein.
      Lese Eingabe
      Prüfe Eingabe auf Gültigkeit (=Zahl)          <- if (int.TryParse())
            OK
                  Erhöhe Versuchszähler
                  Füge Eingabe zu Historie hinzu    <- weißt du ja bereits (textBox5.Text und so)
                  Prüfe Eingabe auf Zufallszahl
                        OK
                              Gewonnen
                        NOK
                              Schade
            NOK
                  Fehlermeldung = Eingabe keine Zahl

Damit solltest du eigentlich den Rest auf deinen Code übertragen können. Wenn nicht, beschreibe konkret was du nicht verstehst bzw. woran es noch hapert.



Preisfrage: Was passiert mit counter, wenn der Spieler das nächste Spiel startet? Und noch eins danach und noch eins? Die textBoxZähler setzt du ja zurück, aber reicht das? :D
 
@Raijin stimmt der counter zählt trotzdem immer weiter auch, wenn das spiel neu startet.

Ich verstehe trotzdem irgendwie nicht ganz wo meine Eingaben ausgelesen werden, denn die benötige ich ja für textBoxZähler
 
PseudoCode ist ja kein vollständiger Quellcode, sondern dient der Veranschaulichung jenseits der Syntax einer speziellen Programmiersprache. Mit "Lese Eingabe" ist also nicht zwingend ein aktiver Befehl gemeint, sondern nur ein grundsätzlicher Vorgang.

Indem du in if (int.TryParse(textBoxEingabe.Text, out eingabe)) auf die Texteigenschaft der TextBox zugreifst, liest du ja bereits die Eingabe ein. Deswegen kannst du auch innerhalb dieses if-Blocks im true-case auf eingabe zugreifen, da dort die Textbox ausgelesen und erfolgreich in die Variable eingabe geschrieben wurde. Genau an dieser Stelle hast du also eine gültige Eingabe vorliegen, die auf den Datentyp integer geprüft wurde, also eine gültige Zahl, die du anschließend mit der Lösung vergleichen kannst - und die im selben Atemzug eben an lblversuche angehängt werden kann. Ob das direkt vor der Lösungs-Prüfung passiert oder direkt danach, ist unerheblich - solange es im selben if-true-case passiert, da nur dort ein gültiger Versuch vorliegt!
 
Okay dann versuche ich mal das Umzusetzen und schreibe dann wieder
Ergänzung ()

@Raijin Es hat leider nicht geklappt, jedenfalls nicht so wie ich es mir gedacht habe, aber ich wüsste nicht wie ich das Auslesen sonst hinbekomme (Zeile 78)

C#:
using System;
using System.Windows.Forms;

namespace Zahlenratespiel
{
    public partial class Form1 : Form
    {
        int obergrenze;
        int untergrenze;
        int zufallszahl = 0;
        int counter = 0;
        Random r = new Random();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private void button1_Click(object sender, EventArgs e)
        {
            lblversuche.Text = "";
            textBoxEingabe.Text = "";
            textBoxZähler.Text = "";

            if (int.TryParse(textBox3.Text, out untergrenze))
            {
                if (int.TryParse(textBox4.Text, out obergrenze))
                {
                    if (untergrenze < obergrenze)
                    {
                        zufallszahl = r.Next(untergrenze, obergrenze + 1);
                        textBoxAnzeige.Text = "Das spiel läuft";
                    }
                    else
                    {
                        textBoxAnzeige.Text = "Die Untergrenze muss kleiner als die Obergrenze sein";
                    }
                }
                else
                {
                    textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
                }
            }
            else
            {
                textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            int eingabe = 0;
            counter += 1;
           
            lblversuche.Text = counter.ToString();
            if (int.TryParse(textBoxEingabe.Text, out eingabe))
               
            {
                if (zufallszahl > eingabe)
                {
                    textBoxAnzeige.Text = "Die Zufallszahl ist größer als die Eingabe";
                }

                else if (zufallszahl < eingabe)
                {
                    textBoxAnzeige.Text = "Die Zufallszahl ist kleiner als die Eingabe";
                }
                else
                {
                    textBoxAnzeige.Text = "Sie haben zwar gewonnen aber werden keinen Preis bekommen";
                }
            }
            else
            {
                textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
            }
            int.TryParse(textBoxZähler.Text, in eingabe);
        }
        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void lblversuche_Click(object sender, EventArgs e)
        {

        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
         
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
           
        }
    }
}
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Raijin
Das ist doch auch unnötig. Du denkst zu kompliziert ;)

C#:
private void button2_Click(object sender, EventArgs e)
{
    int eingabe = 0;
    counter += 1;
         
    lblversuche.Text = counter.ToString();
    if (int.TryParse(textBoxEingabe.Text, out eingabe))
    {

        // In diesem { } Block ist der Inhalt von textBoxEingabe.Text erfolgreich
        // in die Variable eingabe geschrieben worden.
        // Warum? Weil int.TryParse mit true einen Erfolg vermeldet und das if
        // somit in den true-case geht.
        // eingabe enthält an dieser Stelle also einen gültige Versuch des Spielers .
        // Es folgt daher die Prüfung des Versuchs, der Vergleich mit der Lösung

        if (zufallszahl > eingabe)
        {
            textBoxAnzeige.Text = "Die Zufallszahl ist größer als die Eingabe";
        }
        else if (zufallszahl < eingabe)
        {
            textBoxAnzeige.Text = "Die Zufallszahl ist kleiner als die Eingabe";
        }
        else
        {
            textBoxAnzeige.Text = "Sie haben zwar gewonnen aber werden keinen Preis bekommen";
        }

        // Hier befinden wir uns immer noch in dem { } Block, in dem die Variable eingabe
        // den gültigen Versuch des Spielers enthält.
        // An dieser Stelle kann man nun lblversuche um den aktuellen Versuch ergänzen.
        // Hänge hier also die aktuelle eingabe hinten an lblversuche dran.
        // Ganz einfach mit lblversuche.Text += ...
    }
    else
    {
        // Dies ist der else-Fall zum if mit TryParse. Hier landen wir, wenn TryParse
        // false zurückgibt, das Parsen also fehlgeschlagen ist, weil zB ein Buchstabe
        // statt einer Zahl eingegeben wurde.
        // Es folgt daher die Fehlermeldung, dass die Eingabe fehlerhaft ist
        // (hier stimmt wohl der Text wegen copy&paste nicht)

        textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
    }
    int.TryParse(textBoxZähler.Text, in eingabe);  // das ist falsch und kann weg
 }
       
}
 
@Raijin ja, das denke ich auch xD.
Zu dem Code, also ich möchte die Zahlen ja nicht in dem Label, sondern in der unteren Textbox (textBoxZähler) anzeigen lassen.
Es sei denn, ich habe deinen Code falsch verstanden.

1645618028486.png

Die Zahlen die schon eingegeben wurden sollen in der unteren Textbox (textBoxZähler) aufgelistet werden.
 
Wohin du das schreibst, ist ja unerheblich. Wenn ich das falsche Label bzw. die falsche Textbox angegeben habe, dann nimmst du eben die, die du da verwenden willst. Wie gesagt, ohne sprechende Namen ist es schwierig, das von außen nachzuvollziehen. Für mich ist ein "Zähler" nämlich ein "Zähler" und der zählt einfach hoch, von 1 - x, und sammelt keine bisherigen Eingaben.

Aber wie gesagt, was du wie wohin schreibst, musst du ja selbst wissen und entsprechende Änderungen solltest du dann auch mit 2 1/2 Tagen Programmiererfahrung hinbekommen ;)
 
Jetzt habe ich die Lösung, sie werden zwar nicht mit einem Komma getrennt, aber immerhin läuft es jetzt.
C#:
textBoxZähler.Text += eingabe.ToString();

@Raijin ich danke dir vielmals
Ergänzung ()

Zum Abschluss nochmal der ganze Code
C#:
using System;
using System.Windows.Forms;

namespace Zahlenratespiel
{
    public partial class Form1 : Form
    {
        int obergrenze;
        int untergrenze;
        int zufallszahl = 0;
        int counter = 0;
        Random r = new Random();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private void button1_Click(object sender, EventArgs e)
        {
            lblversuche.Text = "";
            textBoxEingabe.Text = "";
            textBoxZähler.Text = "";

            if (int.TryParse(textBox3.Text, out untergrenze))
            {
                if (int.TryParse(textBox4.Text, out obergrenze))
                {
                    if (untergrenze < obergrenze)
                    {
                        zufallszahl = r.Next(untergrenze, obergrenze + 1);
                        textBoxAnzeige.Text = "Das spiel läuft";
                    }
                    else
                    {
                        textBoxAnzeige.Text = "Die Untergrenze muss kleiner als die Obergrenze sein";
                    }
                }
                else
                {
                    textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
                }
            }
            else
            {
                textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            int eingabe = 0;
            counter += 1;
          
            lblversuche.Text = counter.ToString();
            if (int.TryParse(textBoxEingabe.Text, out eingabe))
              
            {
                if (zufallszahl > eingabe)
                {
                    textBoxAnzeige.Text = "Die Zufallszahl ist größer als die Eingabe";
                }

                else if (zufallszahl < eingabe)
                {
                    textBoxAnzeige.Text = "Die Zufallszahl ist kleiner als die Eingabe";
                }
                else
                {
                    textBoxAnzeige.Text = "Sie haben zwar gewonnen aber werden keinen Preis bekommen";
                }
                textBoxZähler.Text += eingabe.ToString();
            }
            else
            {
                textBoxAnzeige.Text = "Die Obergrenze muss eine gültige Zahl sein (1 - 10)";
            }
          
        }
        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void lblversuche_Click(object sender, EventArgs e)
        {

        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
        
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
          
        }
    }
}
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Raijin
ArrorRT schrieb:
jetzt funktioniert die Anzeige aber es steht immer nur 1 1 1 1 egal was ich eintippe.
Es wird nach wie vor nirgends der Wert von eingabe irgendwo hingeschrieben, egal in welches Label oder Textbox, nirgends.

*edit
ok, das hast du jetzt schon selbst korrigiert ;)

ArrorRT schrieb:
@Raijin ich danke dir vielmals
Kein Problem, dafür ist das Forum da. Ich hoffe du hast ein wenig daraus gelernt und bist jetzt schlauer als noch am Montag :D
(Und denk daran, den counter beim Spielstart wieder auf 0 zu setzen)
 
  • Gefällt mir
Reaktionen: ArrorRT
Zurück
Oben