[C++] Maszyna losująca źle losuje
Ostatnio zmodyfikowano 2017-05-18 18:11
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: #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? |
|
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 |
|
Wojteky2000 Temat założony przez niniejszego użytkownika |
» 2017-05-17 22:04:05 Dziękuję bardzo za radę |
|
czaffik |
» 2017-05-18 12:33:07 1. Funkcja czyWylosowano powinna wyglądać tak: 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: 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ą): 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. |
|
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]; |
|
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. |
|
« 1 » |