Strona główna » Po Godzinach » Gry » Reversi - Kod źródłowy
 

Reversi - Kod źródłowy

· Gra · Kod źródłowy ·

Wstęp

Gra Reversi została napisana przy wykorzystaniu języka JavaScript. Kod nie wymaga żadnych zewnętrznych bibliotek, aby działać. Widoczna plansza i ustawione na niej pionki są wyświetlane przy pomocy grafiki wektorowej SVG, a nad ułożeniem wszystkiego na stronie czuwa CSS. Kod źródłowy aplikacji zajmuje ponad 300 linijek i składa się z blisko 11 tysięcy znaków. W dalszej części artykułu zostanie przedstawione działanie poszczególnych funkcji oraz wytłumaczenie niektórych rozwiązań.

Inicjalizacja

Skrypt, aby zadziałał potrzebuje umieszczenia na stronie obiektu div o identyfikatorze _game. To właśnie wewnątrz tego obiektu program umieści pole komunikatów oraz planszę gry.

  1. <div id="_game"></div>

Następnie po uruchomieniu strony dodawane są dwa polecenia, które zostaną wywołane po pełnym załadowaniu strony.

  1. document.addEventListener("DOMContentLoaded", function(){
  2.  initialize();
  3.  createBoard(8);
  4. }, false);

(1.) Kiedy strona jest gotowa to (2.) przygotuj znaleziony obiekt div, a następnie (3.) przygotuj planszę do gry.

Inicjzalizacja

Przygotowywanie pola gry

Podczas inicjalizacji funkcja initialize() przygotowuje obiekt _game. Przede wszystkim tworzone jest pole komunikatów (obj_msg), informacje o aktualnym wyniku gry (obj_score), przycisk powiększania do pełnego ekranu (obj_menu), plansza (obj_board). Następnie wszystkie obiekty są odpowiednio dodawane. Ponadto w tym miejscu w kodzie do obiektu planszy (obj_board) są dodawane definicje, które odpowiadają za część graficzną projektu. Są to filtry, które nadaję dowolnej figurze wygląd pola oraz wygląd pionka zwykłemu kołowi.

Przygotowanie planszy

Program jest bardzo elastyczny i pozwala na utworzenie dowolnej, kwadratowej planszy. Drobne zmiany pozwoliłyby nawet na utworzenie prostokątnej planszy. Podczas tworzenia planszy wykonywane są następujące operacje:

  1. function createBoard(size) {
  2.  while(obj_board.children.length != 1){
  3.   obj_board.removeChild(obj_board.children[1]);
  4.  }
  5.  glob_size = size;
  6.  for(var y = 0; y < size; y++) {
  7.   for(var x = 0; x < size; x++) {
  8.    var svg_el = document.createElementNS("http://www.w3.org/2000/svg", "rect");
  9.    svg_el.setAttribute("x", 100 * x);
  10.    svg_el.setAttribute("y", 100 * y);
  11.    svg_el.setAttribute("width", 100);
  12.    svg_el.setAttribute("height", 100);
  13.    svg_el.setAttribute("class", "f");
  14.    svg_el.setAttribute("onclick", "fieldClicked(this);");
  15.    svg_el.setAttribute("filter", "url(#c)");
  16.    var svg_circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
  17.    svg_circle.setAttribute("cx", 50 + 100 * x);
  18.    svg_circle.setAttribute("cy", 50 + 100 * y);
  19.    svg_circle.setAttribute("r", 40);
  20.    svg_circle.setAttribute("id", fieldName(x, y));
  21.    svg_circle.setAttribute("class", "c");
  22.    svg_circle.setAttribute("filter", "url(#a)");
  23.    obj_board.appendChild(svg_el);
  24.    obj_board.appendChild(svg_circle);
  25.   }
  26.  }
  27.  obj_board.setAttribute("viewBox", "0 0 " + 100 * size + " " + 100 * size);
  28.  prepareGame();
  29. }

(2. - 4.) Usunięcie wszystkich obiektów na planszy prócz definicji (obiektu 0). Ta część kodu ma sens jeśli plansza jest tworzona po raz kolejny. (5.) Zapamiętaj w globalnej zmiennej podany rozmiar size. (6. - 26.) Dla każdego pola utwórz (8. - 15.) kwadrat (pole) oraz (16. - 22.) koło (pionek) i (23. - 24.) dodaj je na plansze. Warto zwrócić uwagę na wykorzystanie funkcji createElementNS(), która jest potrzebna, aby element grafiki wektorowej został prawidłowo utworzony. (27.) Zmień wyświetlany zakres płótna planszy i (28.) przejdź do przygotowywania gry.

Przygotowanie gry

Proces przygotowania gry nie tworzy od nowa planszy, ale jedynie resetuje jej ustawienia do początkowych.

  1. function prepareGame() {
  2.  try{
  3.   clearTimeout(timer);
  4.  } catch (ex) {
  5.   
  6.  }
  7.  for(var y = 0; y < glob_size; y++) {
  8.   for(var x = 0; x < glob_size; x++) {
  9.    getField(x, y).className.baseVal = "c";
  10.   }
  11.  }
  12.  setFieldPlayer(glob_size / 2 - 1, glob_size / 2 - 1, 1);
  13.  setFieldPlayer(glob_size / 2, glob_size / 2 - 1, 0);
  14.  setFieldPlayer(glob_size / 2 - 1, glob_size / 2, 0);
  15.  setFieldPlayer(glob_size / 2, glob_size / 2, 1);
  16.  white = 2;
  17.  black = 2;
  18.  nomoves = 0;
  19.  players = [getSelectedOption("player1"), getSelectedOption("player2")];
  20.  player = 0;
  21.  updateScore();
  22.  moveIfAI();
  23. }

(2. - 6.) timer - jest wykorzystywany przez funkcję do opóźniania ruchów AI. Przed zresetowanie planszy należy upewnić się, że wywołana funkcja przez timer nie przerwie wywoływania programu przez nieprawidłową operację. (7. - 11.) Zresetuj ustawianie pól do początkowych. Dokładniejszy opis jakie znaczenie mają klasy CSS dla pionków zostaną opisane dalej. (12. - 15.) Przypisz cztery początkowe pola. (16. - 17.) Zresetuj ile pól ma każdy z graczy. (18.) Pobierz listę graczy z ustawień nad ekranem gry i (19.) ustal kto pierwszy się rusza. (20.) Aktualizuj pole wyników, a następnie (21.) sprawdź czy ruch wykonuje AI.

Pobieranie ustawień

Ustawienia są pobierane z obiektów select. Do każdej opcji dołączony jest kod gracza. Przykładowo gracz jest oznaczany przez kod p. Domyślnie poprawny kod AI zaczyna się od ai, a potem idzie odpowiedni numer, ale właściwie można użyć dowolnego identyfikatora różnego od p. Przykładowo poprawny obiekt select to:

  1. <select id="player2">
  2. <option value="p">Człowiek</option>
  3. <option value="ai0">AI Losowa</option>
  4. <option value="ai1" selected>AI Chciwa</option>
  5. </select>