Cele lekcji
Po zakończeniu tej lekcji…
- Będziesz potrafić generować liczby losowe w prosty i poprawny sposób.
Jak w wielu grach, tak i w naszej potrzebne są liczby losowe.
Za ich pomocą można określać obrażenia zadane przez potwora i rany zadane przez gracza oraz jakie przedmioty z tabeli łupów otrzymamy po zabiciu potwora.
Jednak z liczbami losowymi związana jest jedna kwestia, o której trzeba pamiętać.
Platforma .Net Framework jest wyposażona w klasę „Random” pozwalającą generować liczby losowe, jednak wartości dostarczane przez nią nie są do końca losowe. W naszej prostej grze nie jest to problemem, ale jeśli chcesz stworzyć poważną grę, to zdecydowania musisz zastosować lepszą metodę.
Problem z tą lepszą metodą jest taki, że wymaga ona złożonych obiektów i logiki do wygenerowania potrzebnych liczb, a operacje te są stanowczo zbyt skomplikowane, abym opisywał je w podręczniku dla początkujących. Ba, niektóre z nich są trudne nawet dla doświadczonych programistów.
Więc jeśli chcesz użyć lepszej metody generowania liczb losowych, to musisz uwierzyć mi na słowo, że ona działa.
Poniżej zamieszczam obydwie metody, a Ty wybierz jedną z nich.
Tworzenie generatora liczb losowych
Etap 1: Uruchom aplikację Visual Studio i otwórz swoje rozwiązanie.
Etap 2: Prawym przyciskiem myszy kliknij projekt Engine i dodaj nową klasę RandomNumberGenerator.cs.
Etap 3: Wybierz metodę i wklej poniższy kod do klasy RandomNumberGenerator.
Metoda prosta:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Engine { public static class RandomNumberGenerator { private static Random _generator = new Random(); public static int NumberBetween(int minimumValue, int maximumValue) { return _generator.Next(minimumValue, maximumValue + 1); } } }
W prostej metodzie tworzymy obiekt Random (_generator) i za pomocą metody Next() uzyskujemy wartość losową w przedziale od wartości minimalnej do maksymalnej z zakresu przekazanego do parametru.
Metoda złożona:
using System; using System.Security.Cryptography; namespace Engine { // This is the more complex version public static class RandomNumberGenerator { private static readonly RNGCryptoServiceProvider _generator = new RNGCryptoServiceProvider(); public static int NumberBetween(int minimumValue, int maximumValue) { byte[] randomNumber = new byte[1]; _generator.GetBytes(randomNumber); double asciiValueOfRandomCharacter = Convert.ToDouble(randomNumber[0]); // We are using Math.Max, and substracting 0.00000000001, // to ensure "multiplier" will always be between 0.0 and .99999999999 // Otherwise, it's possible for it to be "1", which causes problems in our rounding. double multiplier = Math.Max(0, (asciiValueOfRandomCharacter / 255d) - 0.00000000001d); // We need to add one to the range, to allow for the rounding done with Math.Floor int range = maximumValue - minimumValue + 1; double randomValueInRange = Math.Floor(multiplier * range); return (int)(minimumValue + randomValueInRange); } } }
W tej metodzie korzystamy z wystąpienia klasy szyfrującej (RNGCryptoServiceProvider). Za pomocą tej klasy łatwiej jest uzyskać niepowtarzające się ciągi liczb losowych, chociaż wymaga ona większej liczby obliczeń do uzyskania wartości w ramach określonego przedziału.
Podsumowanie
Umiesz już tworzyć liczby losowe,
które w naszej prostej grze występują w kilku miejscach. Powyższe informacje mogą być użyteczne, jeśli będziesz chcieć dodać kolejne funkcje.
Łącza do tej lekcji
Kod źródłowy w serwisie GitHub
Kod źródłowy w serwisie Dropbox
UWAGA: Kod zawiera obydwie wersje klasy (prostą i złożoną). Utwórz więc tylko jedną klasę RandomNumberGenerator i skopiuj do niej kod tylko jednej z wersji.