Format zapisu danych
Jeśli na serwerze zapisywana jest niewielka ilość danych, to troska o ich porządek nie jest zbyt konieczna. Przykładowo jeśli plik gracza zawierałby tylko 2 krótkie linijki tekstu, to odwoływanie się do nich byłoby proste. Problem zaczyna się wtedy, gdy plik tekstowy zawiera wiele linijek kodu i dodatkowo wielkość tego pliku nie jest znana. Wtedy trzeba starać się zapisywać dane w taki sposób, aby program mógł łatwo znaleźć potrzebne jemu dane.
W mojej grze w profilu gracza będzie można zapisać wiele zestawów żetonów, a każdy żeton będzie się składał z 4 stosów żetonów, przy czym każdy stos musi się składać z co najmniej 2 kart żetonów, o numerze będącym liczbą całkowitą. Program potrzebuje więc informacje o tym, z którego zestawu chce korzystać gracz, oraz jaka jest zawartość poszczególnych zestawów żetonów.
W pliku tekstowym gracza umieszczam więc następujący tekst:
Handset
1
set 0
0 1
1 2
3 4
5 6
set 1
0 2
1 3 4
81 32
45 16 35 134
Linia "Handset" będzie dla mojego programu punktem orientacyjnym, dzięki któremu program będzie wiedział, że linijkę niżej znajduje się numer zestawu żetonów z którego korzysta użytkownik. Niżej zaś znajdują się informacje o zestawach żetonów, gdzie pojedyncza linia oznacza jeden stos kart, a numery kart są oddzielone spacjami.
Wczytywanie informacji z pliku
Gdy użytkownik dołączy się do gry, serwer będzie musiał wczytać jego dane. Całą zawartość pliku łatwo można skopiować do tablicy stringów (ciągów znaków) za pomocą jednej linijki kodu:
string
[] Lines = File.ReadAllLines
(@"C:/TokenBattle/"
+ Nickname + ".txt");
Jednak wczytanie tych danych do programu to nie wszystko, trzeba je jeszcze zinterpretować. Nasz skrypt musi teraz znaleźć linię "Handset", aby odczytać z niższej linii numer zestawu, z którego trzeba skorzystać. Wykorzystamy do tego następujący fragment kodu:
Array.FindIndex
(Lines, s => s.Equals ("Handset"))
Funkcja Array.FindIndex jest funkcją znajdującą się w bibliotece System, więc aby z niej skorzystać trzeba zadeklarować tą bibliotekę, lub poprzedzić tą funkcję nazwą tej biblioteki. Funkcja korzysta z 2 argumentów: pierwszym argumentem jest tablica, którą chcemy przeszukać, zaś drugi argument ma typ Predicate, który składa się z argumentu będącym aktualnie sprawdzanym elementem tablicy, oraz warunku który określa, czy ten element tablicy spełnia nasze kryteria. Jeśli Predicate zwróci wartość true, to funkcja zwraca numer indeksu tablicy, który spełnił nasze kryteria. W naszym przypadku Funkcja FindIndex wyszukuje w tablicy ciąg znaków, który brzmi "Handset". Teraz nasz program wie, gdzie znajduje się informacja o wykorzystywanym zestawie żetonów, ale musi tą informację przetworzyć, do czego posłuży nam taka linia kodu:
int
HandsetNumber = int.Parse
(Lines [Array.FindIndex
(Lines, s => s.Equals ("Handset"))
+ 1]);
Tworzy ona zmienną typu int, do której chce przypisać wartość typu string (ponieważ jest to linijka tekstu z tablicy stringów), więc musimy zmienić typ zmiennej za pomocą funkcji int.Parse. Dodatkowo nie chcemy się odwołać do linii "Handset", tylko do linii następnej, więc do numeru indeksu dodajemy 1.
Następnie w podobny sposób chcemy znaleźć indeks linijki tablicy, która rozpoczyna informację o szukanym zestawie żetonów:
int
LineNumber = Array.FindIndex
(Lines, s => s.Equals ("set
"
+ HandsetNumber.ToString ()));
Teraz chcemy przepisać dane do zmiennych innego skryptu:
for
(int
x = 0; x < 4; x++) {
string
[] Stack = Lines [++LineNumber].Split ('
');
SScript
().Player [p].CardQueue [x].NumberOfCards = Stack.Length;
SScript
().Player [p].CardQueue [x].CardNumbers = new
int
[Stack.Length];
int
y = 0;
foreach
(string
number in
Stack) {
SScript
().Player [p].CardQueue [x].CardNumbers [y] = int.Parse
(number);
y++;
}
}
Korzystam tutaj z pętli for, żeby przepisane były 4 linijki tekstu. Chcę jednak, aby były one rozpisane w formie zmiennych typu int, a nie dość, że linie są typu string, to jeszcze sam string składa się z kilku liczb, które trzeba rozdzielić. Robimy to za pomocą funkcji Split(), która rozdziela string wszędzie tam, gdzie spotka char (zmienną typu znak) podany w argumencie tej funkcji. Rozdzielanym stringiem jest string z tablicy Lines, gdzie numerem indeksu jest int LineNumber. Dwa plusy poprzedzające zmienną LineNumber oznaczają, że zostaje ona zwiększona o 1 zanim zostanie wykorzystana (dla porównania postawienie dwóch plusów po tej zmiennej sprawiłoby, że zostałaby zwiększana o 1 dopiero po jej wykorzystaniu). Nowo powstałe stringi przypisuję do tablicy stringów Stack.
Fragment SScript ().Player [p].CardQueue [x] określa miejsce w którym chcę zapisać informację, ogólnie to struktura w strukturze w skrypcie. W tamtym miejscu znajduje się zmienna NumberOfCards, która ma zawierać informację o ilości kart żetonów na stosie, a informację tę można zdobyć sprawdzając liczbę elementów tablicy Stack, co można dokonać funkcją Length. Parę linijek niżej korzystam z pętli foreach, która wykonuje pętlę dla każdego elementu tablicy, którą podajemy jako argument (w moim przypadku jest to tablica Stack). Nazwę tego elementu podajemy w nawiasie tej pętli.
Tym sposobem program wczytał z pliku tekstowego potrzebne mu informacje.
Brak komentarzy:
Prześlij komentarz