Aplikacja 4 wygrywa została napisana przy pomocy JavaScript, które zarządza wyświetlaną treścią zmieniając kod HTML oraz CSS. Użyte funkcje są zgodne z najnowszym standardem HTML5.
W celu umieszczenia na stronie gry wystarczy umieścić obiekt typu DIV, który będzie miał identyfikator _game.
W celu poprawnego działania aplikacji potrzebnych jest kilka zmiennych globalnych, które mają za zadanie przechowywać informacje pomiędzy różnymi funkcjami. Ich znaczenie jest następujące:
(1.) Zmienna data będzie przechowywać ile jest wolnych pól w każdej kolumnie. Przyśpieszy to sprawdzenie czy w kolumnie jest wolne pole - odczytywanie tego z planszy zajęłoby bardzo dużo czasu. (2.) Zmienna player przechowuje, który gracz się rusza (0 to pierwszy, a 1 to drugi). (3.) Z kolei w zmiennej players będzie przechowywane kto porusza się w danej turze. Człowiek jest reprezentowany przez literę p, a AI przez ai0. (4.) Ostatnia zmienna checkPos przechowuje w którym kierunku trzeba przechodzić, aby sprawdzić czy są 4 żetony ustawione w jednej linii.
Zarówno uruchomienie nowej gry czy zrestartowanie obecnej polega na wywołaniu funkcji prepareGame(). Funkcja ta nie przyjmuje żadnych argumentów.
(2.) Znajdź odpowiedni obiekt na stronie i (3.) wyczyść wszystko co się w nim znajduje (przydatne podczas resetowania rozgrywki). (4.) Odczytaj z ustawień kto kim gra. (5.) Wyczyść dane o wolnych polach w każdej kolumnie i (6.) ustal, że pierwszy rusza się gracz 1. (7.) Utwórz 7 kolumn: (8.) po 6 pól i (9.) każde ma być puste. (11.) Po utworzeniu kolumny dopisz ile jest w niej wolnych pól. (13.) Dołącz pole wiadomości i ustal nową zawartość ekranu gry. (14.) Pokaż komunikat, że gra została przygotowana. (15.) Spróbuj wykonać ruch przy pomocy AI.
Tworzenie pola odbywa się przy pomocy funkcji getField(). Polega ona na przekazaniu trzech argumentów: jakiego rodzaju ma być pole oraz pozycję X i Y na planszy. Ze względu na sposób tworzenia pole (0, 0) znajduje się w lewym, górnym rogu, a (6, 5) w prawym, dolny.
(2. - 3.) Na podstawie pozycji wyliczona zostaje pozycja na ekranie gry. (4.) Pole jest reprezentowane przez obiekt div w którym znajduje się obiekt svg tylko z jednym kołem. Do koła jest przypisane zdarzenie onclick - dzięki temu po wciśnięciu pola żeton zostaje dołożony na planszę (o ile ruch jest prawidłowy).
W celu ujednolicenia nazewnictwa pól oraz, aby umożliwić znalezienie pola na podstawie jego pozycji została napisana funkcja getFieldName():
Po kliknięciu koła zostaje wywołana funkcja elClicked(), która przyjmuje argument el - jest to obiekt, który wywołał funkcję. Na podstawie rodzica DIV tego obiektu można określić współrzędne pola.
(2.) Sprawdź czy ruch aktualnie wykonuje gracz. Jeśli nie to (3.) pokaż odpowiedni komunikat i (4.) przerwij dostawienie żetonu. Jeśli jednak ruch wykonuje gracz Człowiek to (6.) przekaż obiekt el funkcji elClickedForced(). W przypadku, gdy ruch wykonuje AI to funkcja elClicked() jest pomijana.
(2.) Pobierz identyfikator obiektu DIV wciśniętego pola i odczytaj z niego odpowiednie wartości. (3.) Jeśli wybrana kolumna nie ma wolnego pola to (4.) pokaż komunikat o niepoprawnym ruchu. (5.) Jednak jeśli dana kolumna ma choć jedno wolne pole to (6.) w najniżej położonym wolnym polu w wybranej kolumnie zmień styl obiektu z pustego na kolor gracza. (7.) Następnie sprawdź czy dzięki temu aktualny gracz wygrał. (8.) Jeśli tak to zakończ rozgrywkę i (9.) pokaż komunikat. (10.) Jednak jeśli rozgrywka nie została zakończona to (11.) zmniejsz ilość wolnych pól w kolumnie i (12. - 16.) sprawdź czy istnieją jeszcze wolne pola. (17.) Jeśli nie istnieje żadne wolne pole to (18.) zakończ rozgrywkę i (19.) pokaż komunikat o remisie. (20.) Jeśli jednak są jeszcze pola to (21.) przekaż kolejkę następnemu graczowi, (22.) pokaż o tym komunikat i (23.) sprawdź czy ruch wykonuje AI.
Lista graczy, a konkretniej informacji kto steruje, którego gracza służy funkcja getSelectedOption(), która z wybranego pola wyboru pobiera informację na temat wybranej opcji przez użytkownika.
W celu zmiany przynależności pola zmieniany jest styl pola. Wcześniej przypisana klasa empty jest zmieniana na p1 lub p2 w zależności od gracza. Funkcja replaceClass() zamienia w podanym obiekcie obj starą klasę oldclass na nową newclass:
W celu sprawdzenia zwycięstwa funkcja checkWin() sprawdza dla każdego przypadku z zmiennej checkPos wszystkie możliwa zakończenia na podstawie klikniętej pozycji.
(1.) Na podstawie pozycji posx i posy: (2.) znajdź kliknięte pole i (3. - 6.) sprawdź wszystkie możliwości podane i zwróć prawde jeśli gracz wygrał, a jeśli nie to (8.) zwróć fałsz.
Funkcję checkWin() wspiera funkcja checkLine(), która na podstawie podanego kierunku szukania zwycięstwa sprawdza wszystkie możliwości:
(1.) Szukaj zwycięstwa dla gracza zapisanego w zmiennej obj_class. Szukaj zwycięstwa wokół pola (nposx, nposy) przesuwając się o (chngx, chngy) szukając czy następne pole należy do tego gracza. (2.) Załóż, że gracz nie odniósł zwycięstwa. (3.) Uwzględnij przypadki, gdy pole jest dodane w środku 4 elementowej linii. (4.) Wtedy oblicz przypuszczalne pierwsze pole w danej czwórce i (5.) przypuść, że linia istnieje. (6. - 11.) Sprawdź czy przeszukiwana linia należy do gracza. (7.) Jeśli przesszukiwane pole nie istnieje, albo nie należy do gracza do (8.) zapisz, że w tym obszarze nie ma czterech żetonów gracza. (9.) Jednak jeśli są 4 żetony w linii to (10.) zwróć prawdę. (12.) Na koniec, o ile nie została zwrócona prawda to zwróć fałsz.
W trakcie przeszukiwania funkcja na podstawie danych nie sprawdza czy wszystkie pola istnieją. Z tego powodu funkcja ifExist() pozwala sprawdzić czy dane pole istnieje. W celu określenia czy pole istnieje wystarczy jego pozycja (posx, posy).
W celu zakończenia rozgrywki należy (2.) pobrać wszystkie pola na ekranie rozgrywki, a następnie (3.) każdemu z pól: (4.) dodać efekt rozmycia i (5.) wyłączyć możliwość kliknięcia.
Na samym początku rozgrywki zostaje przygotowana plansza oraz odczytane kolory ustawione na stronie:
Istnieją dwie funkcje, które wyświetlają komunikaty dla użytkownika. Pierwsza z nich pokazuje dowolny komunikat przekazany w argumencie msg:
Z kolei druga funkcja reportPlayerState() korzysta z reportState(). Różnica polega na tym, że do wiadomości jest dopisywane, którego gracza dotyczy komunikat:
Do wywołania ruchu sztucznej inteligencji służy funkcja moveIfAI(), któa jeśli wykryje, że graczem jest sztuczna inteligencja to po krótkim czasie wykona ruch odpowiednim graczem.
Przykładowo graczem rusza się AI Losowe ruchy. Wtedy (2.) funkcja to wykrywa, która to sztuczna inteligencja, (3.) zgłasza wykonywanie ruchu i (4. - 15.) ustawia wykonanie ruchu na później.
Zmiana koloru drużyny jest możliwa dzięki obiektu input typu color. Przykładowo w celu zmiany koloru gracza 2 obiekt ma dopisane zdarzenie onchange, które zostaje wywołane po zmianie koloru. Wywołuje ona funkcję changeColour(), która zmiena kolor gracza o numerze podanym jako pierwszy argument na kolor, który jest podany jako drugi argument.
Funkcja changeColour() potrafi znaleźć odpowiedni arkusz stylów oraz styl gracza, a następnie zmienić kolor wypełnienia koła.
Elementy gry są częściowo ustalana poprzez kod CSS. Styl ekranu gry:
Styl pola komunikatów:
Ogólny styl pola:
Styl pola na koniec rozgrywki:
Styl pola:
Styl pustego pola (.empty), gracza 1 (.p0) oraz gracza 2 (.p1):