390
Rozdział 8.
Metody do rozmieszczania okrętów
Jak rozmieszczać okręty?
Podczas rozmieszczania okrętów na planszy należy uwzględnić dwa czynniki. Pierwszym jest orientacja
okrętu — każdy z okrętów może być rozmieszczony w pionie bądź w poziomie. Drugim czynnikiem jest
to, że poszczególne okręty nie mogą na siebie nachodzić. Znaczna część kodu, który zaraz napiszemy,
jest związana z zagwarantowaniem, że oba te czynniki będą spełnione. Jak już ostrzegaliśmy, nie
będziemy tłumaczyli wszystkich szczegółów działania przedstawianego kodu, jednak dysponujesz już
wszystkim, co jest potrzebne, by go przeanalizować, a jeśli poświęcisz mu dostatecznie dużo czasu,
na pewno zrozumiesz wszystkie jego tajniki. Nie ma w nim nic, czego byś już nie widział w tej książce
(z jedynym wyjątkiem, który za chwilę opiszemy). A zatem do roboty…
Nasz kod zorganizujemy w formie trzech metod, które umieścimy w obiekcie modelu. Oto one.
Q
generateShipLocations
. To jest główna metoda. Tworzy ona tablicę
VKLSV
w obiekcie
modelu, a w niej tyle okrętów, ile wynosi wartość właściwości
QXP6KLSV
.
Q
generateShip
. Metoda ta odpowiada za utworzenie jednego okrętu, umieszczonego gdzieś
na planszy. Jego położenie może, choć nie musi, pokrywać się z położeniem innych okrętów.
Q
collision
. Metoda wymaga przekazania jednego okrętu i sprawdza, czy zajmowane
przez niego pola nie pokrywają się z innymi okrętami.
Funkcja generateShipLocations
Zacznijmy od metody
JHQHUDWH6KLS/RFDWLRQV
. Metoda ta będzie zawierać pętlę, w której będą tworzone
nowe okręty, aż do momentu, gdy w tablicy
VKLSV
znajdzie się ich odpowiednio dużo. Po wygenerowaniu
każdego nowego okrętu (do czego będzie używana metoda
JHQHUDWH6KLS
) zostanie wywołana metoda
FROOLVLRQ
, która upewni się, że nowy okręt nie koliduje z żadnym z okrętów już znajdujących się na
planszy. Jeśli taka kolizja zostanie wykryta, funkcja usunie nowy okręt i spróbuje wygenerować następny.
W poniższym kodzie trzeba zwrócić uwagę na jedną rzecz, na pętlę
do while
. Pętla
GRZKLOH
działa
bardzo podobnie do pętli
ZKLOH
, jednak różni się od niej tym, że najpierw są wykonywane instrukcje
umieszczone wewnątrz pętli, a dopiero
później sprawdzany warunek jej kontynuacji. Przekonasz się,
że niektóre warunki logiczne można wygodniej zaimplementować, używając właśnie pętli
GRZKLOH
niż
ZKLOH
, choć zdarza się to raczej rzadko.
generateShipLocations: function() {
var locations;
for (var i = 0; i < this.numShips; i++) {
do {
locations = this.generateShip();
} while (this.collision(locations));
this.ships[i].locations = locations;
}
},
Dla każdego okrętu musimy
wygenerować zajmowane
przez niego pola planszy.
Generujemy nowy zestaw współrzędnych…
…po czym sprawdzamy, czy nie
pokrywają się one z polami zajmowanymi
przez któryś z już istniejących okrętów.
Jeśli pokrywają się, musimy ponownie
wygenerować nowy zestaw pól. A zatem
generujemy zestawy pól tak długo, jak
długo będą występować kolizje.
Kiedy już wygenerujemy prawidłowy zestaw
pól dla nowego okrętu, zapisujemy je w tablicy
locations obiektu okrętu, w tablicy model.ships.
Używamy
tu pętli do
while!
Tę metodę dodamy do obiektu modelu.
Get Programowanie w JavaScript Rusz głową! now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.