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.