Laden...

Veränderung einer Variablen überprüfen

Erstellt von Tyrael vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.029 Views
T
Tyrael Themenstarter:in
5 Beiträge seit 2019
vor 5 Jahren
Veränderung einer Variablen überprüfen

Hallo zusammen,

ich drehe derzeit wirklich durch und hoffe auf Eure Hilfe.

Ich habe Conways Game of life nachprogrammiert. Bei jedem timer tick, werden neue Generationen gebildet, Zellen sterben, Zellen entstehen usw.

Ich hänge echt fest hinsichtlich des Stoppens des Zählers der Generationen. Zum Einen habe ich einen Zähler eingebaut, der bei jedem Tick die neue Generation mitzählt und die Anzahl der lebenden Zellen darstellt. Jeweils in einer separaten Textbox.
Ich habe also eine Variable deklariert und initialisiert, die bei jedem Tick erhöht wird, bzw. die neuen lebenden Zellen anzeigt.

Wenn sich aber keine weiteren Generationen mehr ausbilden, zB weil alle Zellen gestorben sind und einen stabilen Zustand haben, möchte ich, dass der Counter stehen bleibt bzw. das Tick-Ereignis gestoppt wird.

Mein erster Ansatz war, das Textfeld der lebenden Zellen auszulesen und zu sagen, wenn keine Veränderung mehr stattfindet, dann stoppe auch das TickErignis. Leider habe ich keinen TextBox.HasChanged“ gefunden, um das zu überprüfen.

Nächster Gedanke war ein TextBoxChangeEvent zu initialisieren. Solange durch den Zähler die Anzahl der lebenden Zellen verändert wird, ist eine variable im Event auf true gesetzt.

public void TextBox1_TextChanged(object sender, EventArgs e)  
{  
   bool textLäuft = true; 
} 

Innerhalb der Tickfunktion habe ich dann überprüft, ob diese Variable noch true ist, wenn nicht, soll er eben stoppen. Das hat nicht funktioniert. So habe ich auch das verworfen.

Der letzte Ansatz war, den Zähler der Generationen mit get und set zu versehen. Bei jedem Tick wird durch set der Zähler um eins erhöht. Jedoch bin ich dann ebenfalls hier hängen geblieben zu sagen, was passiert, wenn die Variable nicht mehr erhöht wird. Mir ist hierzu keine logische Schreibweise eingefallen.

Schematisch dargestellt sieht mein Problem ja so aus:

int lebendeZellen = 0;

public void Tick…..
{
// diverse Berechnungen + Ausrechnen der Lebenden Zellen
Textbox.Text =„Lebende Zellen :“ + lebendeZellen;
}

Und jetzt soll, wenn sich die variable lebendeZellen nicht mehr ändert, die Funktion tick beendet werden.

Ich brauche eigentlich eine logische Schreibweise für: solange sich lebendeZellen ändert (egal ob + oder -) ist y true (wäre neu zu erstellen).

Bitte helft mir!

Danke Euch!

4.938 Beiträge seit 2008
vor 5 Jahren

Hallo und willkommen im Forum,

merke dir in einer zusätzlichen Membervariablen den letzten Wert der lebenden Zellen und vergleiche dann diesen nach jeder Generierung der nächsten Generation mit dieser:


int lebendeZellen = 0;
int letzte_lebendeZellen = -1;

public void Tick(...)
{
  // Generierung... (Setzen von lebendeZellen)

  if (letzte_lebendeZellen >= 0) // Überspringen der ersten Generation
  {
    bool bChanged = (lebendeZellen != letzte_lebendeZellen);
    if (!bChanged)
    {
      // stop event
    }
  }

  letzte_lebendeZellen = lebendeZellen;
}

Edit: Dies ist aber nicht unbedingt eine hinreichende Bedingung für einen stabilen Zustand (es kann auch Änderungen so geben, daß sich neue Figuren ergeben, sich aber die Anzahl der lebenden Zellen insgesamt dabei nicht ändert).

PS: Bitte verwende C#-Tags für deinen Code hier - du kannst deinen Beitrag nachträglich editieren.

C
2.121 Beiträge seit 2010
vor 5 Jahren

Eine Zahl in einen Text umwandeln und diesen dann aus der Anzeige wieder rauszulesen, zurückzuwandeln und vergleichen ist Unsinn. Nutze dazu direkt die Variable aus der der Text stammt.

Deine TextChanged Methode tut überhaupt nichts. Sie legt einen bool an, setzt den auf true und danach beendet sich die Methode und wirft den bool wieder weg, ohne dass er eine Auswirkung hat.

Und jetzt soll, wenn sich die variable lebendeZellen nicht mehr ändert, die Funktion tick beendet werden.

Zum Verständnis: Tick wird immer wieder aufgerufen und beendet sich nach jedem Durchlauf. Was du in Wirklichkeit willst ist, dass Tick nicht mehr ständig aufgerufen wird. Th69 hat das ja schon angedeutet.

T
Tyrael Themenstarter:in
5 Beiträge seit 2019
vor 5 Jahren

Grüßt Euch und erstmal vielen Dank für Eure Rückmeldung.
Der Code sieht insgesamt so aus.

[ public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            timer.Interval = TimeSpan.FromSeconds(.1);
            timer.Tick += Timer_Tick;
            button1.IsEnabled = false;

        }

        const int anzahlZellenBreit = 7;
        const int anzahlZellenHoch = 7;
        Rectangle[,] felder = new Rectangle[anzahlZellenBreit, anzahlZellenHoch];
        DispatcherTimer timer = new DispatcherTimer();
        int generation = 1;
        int lebendeZellen = 0;
        
        
        private void ButtonStart_Click(object sender, RoutedEventArgs e)
        {

            button1.IsEnabled = true;
            button.IsEnabled = false;
            
            Random würfel = new Random();
          
            for (int i = 0; i < anzahlZellenHoch; i++)
            {
                for (int j = 0; j < anzahlZellenBreit; j++)
                {
                    Rectangle r = new Rectangle();
                    r.Width = Zeichenfläche.ActualWidth / anzahlZellenBreit - 2;
                    r.Height = Zeichenfläche.ActualHeight / anzahlZellenHoch - 2;
                    r.Fill = (würfel.Next(0,2)==1)? Brushes.Cyan : Brushes.Red;
                    Zeichenfläche.Children.Add(r);
                    Canvas.SetLeft(r, i * Zeichenfläche.ActualWidth / anzahlZellenBreit);
                    Canvas.SetTop(r, j * Zeichenfläche.ActualHeight / anzahlZellenHoch);


                    felder[i, j] = r;
                    
                    if (felder[i,j].Fill == Brushes.Red)
                    {

                        textBoxLebend.Text = "Lebende Zellen :\n" + ++lebendeZellen;
                    }

                }
            }
           
        }


        private void Timer_Tick(object sender, EventArgs e)
        {
             textBox.Text = "Generation : " + generation++;

            int[,] anzahlNachbarn = new int[anzahlZellenHoch, anzahlZellenBreit];

            for (int i = 0; i < anzahlZellenHoch; i++)
            {
                for (int j = 0; j < anzahlZellenBreit; j++)
                {
                    int nachbarn = 0;

                    int iDarüber = i - 1;
                    if(iDarüber <0)
                    { iDarüber = anzahlZellenHoch - 1; }

                    int iDarunter = i+ 1;
                    if (iDarunter == anzahlZellenHoch)
                    { iDarunter = 0; }

                    int jRechts = j +1;
                    if (jRechts == anzahlZellenBreit)
                    { jRechts = 0; }

                    int jLinks = j -1;
                    if (jLinks <0)
                    { jLinks = anzahlZellenBreit-1; }

                    if (felder[iDarüber,jLinks].Fill==Brushes.Red)
                    { nachbarn++; }
                    if (felder[iDarüber, j].Fill == Brushes.Red)
                    { nachbarn++; }
                    if (felder[iDarüber, jRechts].Fill == Brushes.Red)
                    { nachbarn++; }
                    if (felder[i, jLinks].Fill == Brushes.Red)
                    { nachbarn++; }
                    if (felder[i, jRechts].Fill == Brushes.Red)
                    { nachbarn++; }
                    if (felder[iDarunter, j].Fill == Brushes.Red)
                    { nachbarn++; }
                    if (felder[iDarunter, jLinks].Fill == Brushes.Red)
                    { nachbarn++; }
                    if (felder[iDarunter, jRechts].Fill == Brushes.Red)
                    { nachbarn++; }

                    anzahlNachbarn[i, j] = nachbarn;
                }
            }

            int lebendeZellen1 = lebendeZellen;
      
            for (int i = 0; i < anzahlZellenHoch; i++)
            {
                for (int j = 0; j < anzahlZellenBreit; j++)
                {
                   
                    if (anzahlNachbarn[i, j] < 2 || anzahlNachbarn[i, j] > 3)
                    {
                        felder[i, j].Fill = Brushes.Cyan;
                    }
                    else
                         if (anzahlNachbarn[i, j] == 3)
                    { felder[i, j].Fill = Brushes.Red; }
                    
                    if (felder[i, j].Fill == Brushes.Red)
                    {
                        ++lebendeZellen;
                      
                        textBoxLebend.Text = "Lebende Zellen :\n"+ (lebendeZellen - lebendeZellen1);
                       
                    }
                    if (lebendeZellen - lebendeZellen1 < 2)
                    {
                        textBoxLebend.Text = "Lebende Zellen :\n0";
                    }

                    
                }
                
            }
       
        }
        
        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            
            if (timer.IsEnabled)
            {
                timer.Stop();
               
                button1.Content = "Starte Animation";
                    }
            else
            {
                timer.Start();
             button1.Content = "Stoppe Animation";
              

            }
        }

       
    }]

Den von Th69 vorgeschlagenen Code setze ich an welche Stelle, sodass die Tick Funktion nicht mehr aufgerufen wird?

16.826 Beiträge seit 2008
vor 5 Jahren

Ziemlich Kraut und Rüben 😉
Aber nicht schlimm, Dir fehlen hier einfach die Basics.
[Artikel] MVVM und DataBinding

Du solltest in WPF unbedingt diese Konzepte befolgen und anwenden.
Ansonsten wirst Du immer in solche Puzzle-Workarounds laufen.