Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Piotr Szawdyński
Kurs C++

Pseudolosowe liczby całkowite

[lekcja] Rozdział 16. W lekcji omówiono w jaki sposób generuje się losowe liczby całkowite.
Kolejny rozdział, kolejne wyzwanie - tym razem dowiemy się w jaki sposób możemy generować pseudolosowe liczby całkowite.

Funkcja losująca liczby całkowite pochodzi ze standardowej biblioteki języka C. Bibliotekę, którą należy dołączyć jest cstdlib. Oznacza to w konsekwencji, że w naszym programie możemy być zmuszeni do dopisania następującej linijki:
C/C++
#include <cstdlib>

Pamiętaj, że wspomniana linijka nie musi koniecznie wystąpić w naszym programie, jeżeli dołączyliśmy inną bibliotekę, która używa biblioteki cstdlib.

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 » standard Crand. Funkcja ta po prostu losuje nam liczbę całkowitą. Liczba ta mieścić się będzie w przedziale od 0 do » standard CRAND_MAX, gdzie » standard CRAND_MAX jest stałą, która jest zależna od posiadanego kompilatora i posiadanych bibliotek. Więcej szczegółów na temat poszczególnych zagadnień możesz doczytać sobie w dokumentacji, jednak na chwilę obecną nie jest to konieczne.

Skupmy się teraz na użyciu funkcji w praktyce. Funkcja » standard Crand jest bardzo prosta w użyciu dlatego też przejdę odrazu do krótkiego przykładu:
C/C++
#include <iostream>
#include <cstdlib>
int main()
{
    std::cout << "Wylosowanie pierwsze: " << std::rand() << std::endl;
    int liczba = std::rand();
    std::cout << "Wylosowanie drugie: " << liczba << std::endl;
    liczba = std::rand();
    std::cout << "Wylosowanie trzecie: " << liczba << std::endl;
    return 0;
}
Jak widać użycie funkcji jest bardzo proste.

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ą » standard Csrand. Funkcja » standard Csrand 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ę » standard Csrand 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ę » standard Ctime, która zwraca obecny czas na komputerze w postaci liczby - więcej szczegółów nie musisz wiedzieć na chwilę obecną. Jeśli jednak chciałbyś wiedzieć więcej to możesz spokojnie przeczytać dokumentację funkcji » standard Ctime. Kończąc ten przydługawy wywód i mam nadzieję zaspokajając Twoją ciekawość co do czego służy przejdźmy do finalnej postaci linijki konfigurującej maszynę losującą:
C/C++
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:
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
    srand( time( NULL ) );
    std::cout << "Wylosowanie pierwsze: " << std::rand() << std::endl;
    int liczba = std::rand();
    std::cout << "Wylosowanie drugie: " << liczba << std::endl;
    liczba = std::rand();
    std::cout << "Wylosowanie trzecie: " << liczba << std::endl;
    return 0;
}

Błąd popełniany przez początkujących programistów

Podstawowym błędem, który popełniają w zasadzie wszyscy programiści dla których źródłem wiedzy są przede wszystkim kursy, a nie dokumentacja, to czytanie kursów bez głębszego zastanowienia. W niniejszym rozdziale kluczową wiedzą, zapewniającą pseudolosowość liczb we własnych programach jest miejsce wywołania funkcji » standard Csrand.

Zapamiętaj!
C/C++
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 » standard Crand rzadko kiedy jest nam potrzebne. Znacznie częściej interesuje nas losowanie liczb z pewnego przedziału. Jeżeli oczekujesz w tym momencie kolejnej funkcji, która załatwi Ci sprawę to jesteś w błędzie. Wystarczy Ci wiedza, którą obecnie posiadasz, choć prawdopodobnnie nie zdajesz nawet sobie z tego sprawy. 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 kupy następującym wzorem:
C/C++
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:
C/C++
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:
C/C++
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
    srand( time( NULL ) );
    std::cout << "Wylosowanie pierwsze: " <<(( std::rand() % 50 ) + 7 ) << std::endl;
    int liczba =( std::rand() % 50 ) + 7;
    std::cout << "Wylosowanie drugie: " << liczba << std::endl;
    liczba =( std::rand() % 50 ) + 7;
    std::cout << "Wylosowanie trzecie: " << liczba << std::endl;
    return 0;
}

Zadanie domowe

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.
Poprzedni dokument Następny dokument
Pętla do ... while Funkcje - pierwsze starcie