Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Maszyna losująca źle losuje

Ostatnio zmodyfikowano 2017-05-18 18:11
Autor Wiadomość
Wojteky2000
Temat założony przez niniejszego użytkownika
[C++] Maszyna losująca źle losuje
» 2017-05-17 19:01:34
Witam
Mam zadanie w postaci: "Napisz maszynę losującą do 4 gier lotto, tak żeby wylosowane liczby się nie powtarzały". Oto mój program:
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
bool czywylosowana( int liczba, int tablica[], int ilerazy )
{
    if( ilerazy <= 0 )
    {
        return false;
    }
    int i = 0;
    do
    {
        if( tablica[ i ] == liczba )
        {
            return true;
        }
        i++;
    } while( i < ilerazy );
   
}
int wylosujlotto()
{
    return( rand() % 48 ) + 1;
}
int wylosujminilotto()
{
    return( rand() % 41 ) + 1;
}
int wylosujekstra1()
{
    return( rand() % 35 ) + 1;
}
int wylosujmultimulti()
{
    return( rand() % 80 ) + 1;
}
int main()
{
    int wybor;
    srand( time( NULL ) );
    cout << "Loteria" << endl;
    cout << "1.Lotto" << endl;
    cout << "2.Mini Lotto" << endl;
    cout << "3.Ekstra pensja" << endl;
    cout << "4.Multi multi" << endl;
    cout << "Inna liczba - wyjscie" << endl;
    cout << "wybierz gre: "; cin >> wybor;
    switch( wybor )
    {
    case 1:
        {
            int wylosowane[ 5 ];
            int wylosowanych = 0;
           
            do
            {
                int liczba = wylosujlotto();
                if( czywylosowana( liczba, wylosowane, wylosowanych ) == false )
                {
                    wylosowane[ wylosowanych ] = liczba;
                }
                wylosowanych++;
            } while( wylosowanych < 6 );
           
            wylosowanych = 0;
            cout << "wylosowane liczby: " << endl;
            do
            {
               
                cout << wylosowane[ wylosowanych ] << endl;
                wylosowanych++;
            } while( wylosowanych < 6 );
           
            break;
        }
    case 2:
        {
            int wylosowane[ 4 ];
            int wylosowanych = 0;
           
            do
            {
                int liczba = wylosujminilotto();
                if( czywylosowana( liczba, wylosowane, wylosowanych ) == false )
                {
                    wylosowane[ wylosowanych ] = liczba;
                }
                wylosowanych++;
            } while( wylosowanych < 5 );
           
            wylosowanych = 0;
            cout << "Wylosowane liczby: " << endl;
            do
            {
               
                cout << wylosowane[ wylosowanych ] << endl;
                wylosowanych++;
            } while( wylosowanych < 5 );
           
            break;
        }
    case 3:
        {
            int wylosowane[ 4 ];
            int wylosowanych = 0;
           
            do
            {
                int liczba = wylosujekstra1();
                if( czywylosowana( liczba, wylosowane, wylosowanych ) == false )
                {
                    wylosowane[ wylosowanych ] = liczba;
                }
                wylosowanych++;
            } while( wylosowanych < 4 );
           
            wylosowanych = 0;
            cout << "Wylosowane liczby: " << endl;
            do
            {
               
                cout << wylosowane[ wylosowanych ] << endl;
                wylosowanych++;
            } while( wylosowanych < 4 );
           
            break;
        }
    case 4:
        {
            int wylosowane[ 9 ];
            int wylosowanych = 0;
            int wyborliczb;
            cout << "ile liczb: "; cin >> wyborliczb;
            do
            {
                int liczba = wylosujmultimulti();
                if( czywylosowana( liczba, wylosowane, wylosowanych ) == false )
                {
                    wylosowane[ wylosowanych ] = liczba;
                }
                wylosowanych++;
            } while( wylosowanych < wyborliczb );
           
            wylosowanych = 0;
            cout << "Wylosowane liczby: " << endl;
            do
            {
                cout << wylosowane[ wylosowanych ] << endl;
                wylosowanych++;
            } while( wylosowanych < wyborliczb );
           
            break;
        }
    }
}
Problem jest taki że w przypadku "lotto" czasami dwie z wylosowanych liczb nie mieszczą się w przedziale - jedna zawsze jest zerem a druga to 4199040. W przypadku "Mini lotto" zawsze druga wylosowana liczba to 1968796643. W przypadku "Ekstra pensji" 2 liczba zawsze nie mieści się w przedziale i jest to zazwyczaj 7012076, a ostatnią liczbą bardzo rzadko jest 1968796643. W przypadku "Multi multi" 2 liczba to zawsze 0, przy wyborze 9 liczb ósma czasami losuje się spoza przedziału, a przy 10 liczb program najczęściej kompletnie się wywala i losuje bez końca, czasami losuje tych liczb 20-40 a bardzo rzadko wychodzi tyle liczb ile miało wyjść, ale tylko 3 z nich mieszczą się w przedziale. Czy mógłbym prosić o jakieś nakierowanie co robię źle?
P-161229
karambaHZP
» 2017-05-17 19:20:31
Popracuj z debuggerem.

Ten kod spokojnie można o połowę skrócić.
Funkcje losujące: zamiast czterech, można napisać jedną (a przedział podać w argumentach).
Całą logikę z instrukcji
switch
 też można przenieść do jednej funkcji
i wywoływać ją z odpowiednimi argumentami.
zasada DRY
P-161230
Wojteky2000
Temat założony przez niniejszego użytkownika
» 2017-05-17 22:04:05
Dziękuję bardzo za radę
P-161238
czaffik
» 2017-05-18 12:33:07
1. Funkcja czyWylosowano powinna wyglądać tak:
C/C++
bool czywylosowana( int liczba, int tablica[], int ilerazy )
{
    int i = 0;
    do
    {
        if( tablica[ i ] == liczba ) return true;
       
        i++;
    }
    while( i < ilerazy );
   
    return false;
}

2. Pętla losowania tak:
C/C++
do
{
    int liczba = wylosuj( LOTTO );
    if( czywylosowana( liczba, wylosowane, wylosowanych ) == false )
    {
        wylosowane[ wylosowanych ] = liczba;
        wylosowanych++;
    }
}
while( wylosowanych < 6 );


3. Zeruj tablicę, nigdy nie wiadomo co tam może siedzieć (prawdopodobnie zero, ale jednak dla pewności, stąd te zero kiedy liczba w losowaniu się powtarzała była zastępowana zerem albo bardzo dużą liczbą):
C/C++
for( int i = 0; i < 9; i++ ) wylosowane[ i ] = 0;


4. "Wszystko" można zrobić lepiej, teoretycznie te sprawdzanie czy liczba się nie powtórzyła mogłoby się nigdy nie skończyć, jednak szanse na to są małe, pokazałem tylko gdzie w newralgicznych punktach popełniłeś błąd.
P-161243
maly7
» 2017-05-18 15:19:31
Dodatkowo:
int wylosowane[ 5 ];

wylosowane[ wylosowanych ] = liczba;

} while( wylosowanych < 6 );

Nie możesz odwołać się do nieistniejącego elementu tablicy, w tym wypadku wylosowane[5];
P-161246
mokrowski
» 2017-05-18 18:11:14
A jak wyglądają prawdziwe gry? Ano są sobie kule (przed losowaniem) z numerami z danego zakresu, później "się mieszają" i wybierane są z pomieszanego zbioru. Nawet może to być ostatnia z kul. Sprawdzanie "czy wylosowano" jest tu stratą czasu.
Zadeklaruj kontener np. vector wypełniony danymi liczbami, użyj shuffle z <algorithm> i pobieraj liczby z użyciem back() i pop_back() na vectorze.
P-161251
« 1 »
  Strona 1 z 1