Liczby losowe
Funkcja losująca liczby całkowite pochodzi ze standardowej biblioteki języka C. Bibliotekę, którą należy dołączyć jest cstdlib oraz ctime. Oznacza to w konsekwencji, że w naszym programie możemy być zmuszeni do dopisania następujących linii kodu:
C/C++
#include <cstdlib>
#include <ctime>
Funkcja losująca
Jeżeli mamy już dołączoną bibliotekę cstdlib do naszego programu to posiadamy również już dostęp do funkcji losującej. Funkcja ta po prostu losuje nam liczbę całkowitą. Liczba ta mieścić się będzie w przedziale od 0 do RAND_MAX, gdzie RAND_MAX jest stałą, która jest zależna od posiadanego kompilatora i posiadanych bibliotek.
Funkcja rand jest bardzo prosta w użyciu:
#include <cstdlib.h>
#include <ctime.h>
#include <iostream>
use namespace std;
int main()
{
cout << "Wylosowanie pierwsze: " << rand() << endl;
int liczba = rand();
cout << "Wylosowanie drugie: " << liczba << endl;
liczba = rand();
cout << "Wylosowanie trzecie: " << liczba << endl;
return 0;
}
Konfiguracja maszyny losującej
Jeżeli uruchomimy kilka razy powyższy program to zauważymy, że komputer wylosował nam za każdym razem te same liczby. Takie zachowanie oczywiście nie jest pożądane dlatego też wymagane jest skonfigurowanie generatora liczb losowych. Z pomocą przychodzi nam kolejna funkcja i jest nią srand. Funkcja srand ustawia punkt startowy dla mechanizmu generowania kolejnych liczb całkowitych. W dużym uproszczeniu napisanie: srand( 123 ); ustawi punkt startowy 123, a zapis srand( 543 ); ustawi punkt startowy 543. Co to daje? W sumie tyle, że losowane są inne liczby. Jednak aby uzyskać każdorazowo inne wylosowane wartości w raz skompilowanym programie należy powiązać funkcję srand z czasem rzeczywistym, ustawionym obecnie w komputerze. Tu będziemy zmuszeni dołączyć kolejny plik nagłówkowy i jest nim
ctime. Biblioteka ctime dostarczy nam między innymi funkcję time, która zwraca obecny czas na komputerze w postaci liczby.
Wywołanie funkcji losującej z powiązaniem z czasem rzeczywistym:
srand( time( NULL ) );
Na koniec warto dodać, że powyższą linijkę wystarczy wywołać tylko raz na samym początku programu i od tego momentu możemy cieszyć się pseudolosowością liczb całkowitych w naszym programie. Poprawiony kod wygląda teraz tak:
Zapamiętaj!
srand( time( NULL ) );
Powyższą linijkę należy wywołać tylko raz na samym początku programu i od tego momentu możemy cieszyć się pseudolosowością liczb całkowitych w naszym programie.
Od powyższej reguły można stosować wyjątki, jednak wymagana jest świadomość co ta funkcja tak na prawdę robi.
Losowanie liczb z określonego zakresu
Losowanie liczb z tak dużego zakresu jaki dostarcza nam funkcja rand rzadko kiedy jest nam potrzebne. Znacznie częściej interesuje nas losowanie liczb z pewnego przedziału. Jedyne co do tego potrzebujemy to wykorzystać dzielenie z resztą i dodawanie. Najpierw ustalamy ile liczb mieści się w przedziale z którego chcemy losować, np. będzie to 50 liczb. Następnie ustalamy pierwszą losowaną liczbę - załóżmy 7. Teraz składamy to do wzoru:
int wylosowana_liczba =( std::rand() % ile_liczb_w_przedziale ) + startowa_liczba;
Konkretyzując powyższy zapis do wyżej przytoczonego przykładu, zapis powyższy będzie wyglądał tak:
int wylosowana_liczba =( std::rand() % 50 ) + 7;
Ostatecznie program losujący liczby z przedziału od 7 do 56 będzie więc wyglądał tak:
//*********************************************************
//** Program losujący **
//*********************************************************
#include <iostream>
#include <cstdlib>
#include <ctime>
use namespace std;
int main()
{
srand( time( NULL ) );
cout << "Wylosowanie pierwsze: " <<(( rand() % 50 ) + 7 ) << endl;
int liczba =( rand() % 50 ) + 7;
cout << "Wylosowanie drugie: " << liczba << endl;
liczba =( rand() % 50 ) + 7;
cout << "Wylosowanie trzecie: " << liczba << endl;
return 0;
}
Przykład - losowanie liczb bez powtórzeń
Na początek sformułujmy nasz problem: Program ma nam wylosować 5 liczb bez powtórzeń. Liczby wylosowane mają być z przedziału od 1 do 10.
Analiza problemu losowania liczb bez powtórzeń
- 1. Losuję liczbę z przedziału od 1 do 10;
- 2. Sprawdzam, czy wylosowana liczba przypadkiem wcześniej już nie padła;
- 3. Jeżeli wylosowana liczba nie padła zapisuję ją do puli liczb wylosowanych i zwiększam liczbę wylosowanych liczb.
- 4. Jeżeli wylosowana liczba padła wracam do kroku 1.
- 5. Sprawdzam, czy wylosowałem już 5 liczb. Jeżeli nie - przechodzę do punktu 1.
Zadanie 1
Twoim zadaniem domowym jest napisanie prostej gry, która ma działać następująco:
1. Program losuje liczbę z przedziału od 1 do 1000.
2. Użytkownik zgaduje liczbę, która została wylosowana.
3. Jeżeli podana liczba jest za duża (za mała) gra wypisuje stosowny komunikat i powraca do kroku 2.
4. Jeżeli gracz trafi liczbę wylosowaną to progam kończy działanie, wypisując na ekran wylosowaną liczbę oraz liczbę 'strzałów', które oddał gracz.
Gra ma być zabezpieczona przed możliwością wprowadzenia błędnych wartości liczbowych.
Zadanie 2
Napisz program realizujący następujące operacje:
a) losowanie liczby całkowitej z przedziału [-15; 15];
b) losowanie liczby całkowitej z przedziału [3; 25];
c) losowanie liczby rzeczywistej z przedziału [1,5; 2,25];
d) losowanie liczby rzeczywistej z przedziału [0; 1];
e) losowanie liczby rzeczywistej z przedziału [0; 64,5];