Problem z losowaniem liczb z ustalonego zakresu.

0

Witam. Mam tablicę int Liczby[4], do której losuje liczby z przedziału od 0 do 3, w kolejnym losowaniu losuje liczby z przedziału 0 do lista.Count. Potem program przypisuje wylosowane słowa z listy do labeli. Czasem pojawia się komunikat, że index został przekroczony, ale nie zawsze, pytanie dlaczego tak jest? Treść błędu w załączniku.

       private void wyswietlWyborOdpowiedzi(List<string> slowa, int zmiennaIndex, List<LinkLabel> listaLinkLabeli)
        {
            //losujemy indexy labeli bez powtórzeń
            for (int i = 0; i < 4; ++i)
                Liczby[i] = i;
            for (int i = 3; i > 0; --i)
            {
                int p = losuj.Next(0, i);
                if (i != p)
                {
                    int t = Liczby[i];
                    Liczby[i] = Liczby[p];
                    Liczby[p] = t;
                }
            }
            wylosujWyborOdpowiedzi(slowa, zmiennaIndex, listaLinkLabeli);
        }

        // metoda losowania/wyświetlenia losowych odpowiedzi
        private void wylosujWyborOdpowiedzi(List<string> slowa, int zmiennaIndex, List<LinkLabel> listaLinkLabeli)
        {
            int wylosowana;
            int maxPrzedzial = slowa.Count;
            for (int i = 0; i < 4; i++)
            {
                do
                {
                    wylosowana = losuj.Next(0, maxPrzedzial);
                    if (!indexyOdpowiedzi.Contains(wylosowana))
                        indexyOdpowiedzi[i] = wylosowana;
                }
                while (indexyOdpowiedzi[i] == wylosowana);
            }

            try
            {
                listaLinkLabeli[Liczby[0]].Text = slowa[indexyOdpowiedzi[2]];
                listaLinkLabeli[Liczby[1]].Text = slowa[indexyOdpowiedzi[1]];
                listaLinkLabeli[Liczby[2]].Text = slowa[indexyOdpowiedzi[0]];
                listaLinkLabeli[Liczby[3]].Text = slowa[zmiennaIndex];
            }
            catch (Exception ex)
            {
                MessageBox.Show("Nie udało się wyświetlić listy propozycji. " + ex, "Komunikat");
            }
            for (int i = 0; i < 3; i++)//sprawdzamy aby odpowiedź nie powtórzyła się dwa razy
            {
                if (listaLinkLabeli[Liczby[i]].Text == slowa[zmiennaIndex])
                {
                    listaLinkLabeli[Liczby[i]].Text = "brak odpowiedzi";
                }
            }
        }
 

W załączniku jest też program. Wybieramy jakiś dział, przechodzimy do zakładki Rozumienie ze słuchu i potem zmieniamy cały czas działy (im szybciej tym większa szansa na pojawienie się błędu), pojawi się błąd wyświetli się komunikat, potem wybiorę jeszcze raz ten sam dział i wszystko działa normalnie.

0

jeśli ta funkcja losująca zwraca liczby z zakresu <a,b> (czyli włącznie z wartościami brzegowymi) to maxPrzedzial = slowa.Count-1;

0

Masz rację. Poprawiłem, ale dalej wyświetla się ten sam błąd, tylko, że teraz rzadziej.

 
 private void wyswietlWyborOdpowiedzi(List<string> slowa, int zmiennaIndex, List<LinkLabel> listaLinkLabeli)
        {
            //losujemy indexy labeli bez powtórzeń
            for (int i = 0; i < 4; ++i)
                Liczby[i] = i;
            for (int i = 3; i > 0; --i)
            {
                int p = losuj.Next(0, i);
                if (i != p)
                {
                    int t = Liczby[i];
                    Liczby[i] = Liczby[p];
                    Liczby[p] = t;
                }
            }
            try
            {
                wylosujWyborOdpowiedzi(slowa, zmiennaIndex, listaLinkLabeli);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Nie udało się wylosować wyboru odpowiedzi. Spróbuj ponownie wybrać dział. " + ex, "Komunikat");
            }
        }

        // metoda losowania/wyświetlenia losowych odpowiedzi
        private void wylosujWyborOdpowiedzi(List<string> slowa, int zmiennaIndex, List<LinkLabel> listaLinkLabeli)
        {
            int wylosowana;
            int maxPrzedzial = slowa.Count-1;
            for (int i = 0; i < 4; i++)
            {
                do
                {
                    wylosowana = losuj.Next(0, maxPrzedzial);
                    if (!indexyOdpowiedzi.Contains(wylosowana))
                        indexyOdpowiedzi[i] = wylosowana;
                }
                while (indexyOdpowiedzi[i] == wylosowana);
            }

            try
            {
                listaLinkLabeli[Liczby[0]].Text = slowa[indexyOdpowiedzi[2]];
                listaLinkLabeli[Liczby[1]].Text = slowa[indexyOdpowiedzi[1]];
                listaLinkLabeli[Liczby[2]].Text = slowa[indexyOdpowiedzi[0]];
                listaLinkLabeli[Liczby[3]].Text = slowa[zmiennaIndex];
            }
            catch (Exception ex)
            {
                MessageBox.Show("Nie udało się wyświetlić listy propozycji. " + ex, "Komunikat");
            }
            for (int i = 0; i < 3; i++)//sprawdzamy aby odpowiedź nie powtórzyła się dwa razy
            {
                if (listaLinkLabeli[Liczby[i]].Text == slowa[zmiennaIndex])
                {
                    listaLinkLabeli[Liczby[i]].Text = "brak odpowiedzi";
                }
            }
        }
        //***********KONIEC LOSOWANIA***************************KONIEC LOSOWANIA**********************

Pokazuje, że błąd jest tutaj przy przypisywaniu, ale to raczej wynika z nieodpowiednich wylosowanych liczb.

 
         try
            {
                listaLinkLabeli[Liczby[0]].Text = slowa[indexyOdpowiedzi[2]];
                listaLinkLabeli[Liczby[1]].Text = slowa[indexyOdpowiedzi[1]];
                listaLinkLabeli[Liczby[2]].Text = slowa[indexyOdpowiedzi[0]];
                listaLinkLabeli[Liczby[3]].Text = slowa[zmiennaIndex];
            }
0

coś z tym:

            for (int i = 0; i < 4; ++i)
                Liczby[i] = i;
            for (int i = 3; i > 0; --i) // dziwne te losowanie
            {
                int p = losuj.Next(0, i);
                if (i != p) // niby dlaczego nie moze byc na tej samej pozycji
                {
                    int t = Liczby[i];
                    Liczby[i] = Liczby[p];
                    Liczby[p] = t;
                }
            }

przekombinowałeś. proponuje coś takiego

            for (int i = 0; i < 4; ++i)
                Liczby[i] = i;
            for (int i = 0; i < 30; i++)
            {
                // losuje dwa indeksy
                int p = losuj.Next(0,4-1 /*wiadomo, że wyjdzie 3, ale lepiej widziec skad sie wzielo*/);
                int q = losuj.Next(0,4-1);

                // nie jestem pewien czy jest taka funkcja w C#, ale chodzi o zamienienie dwóch liczb miejscami ze sobą
                swap(Liczby[p],Liczby[q]);
            }

dalej nie sprawdzałem

1 użytkowników online, w tym zalogowanych: 0, gości: 1