Projekt Cube Solver #03 – Generowanie scrambli – testy i pierwszy kod

Projekt Cube Solver #03 – Generowanie scrambli – testy i pierwszy kod

W poprzednim wpisie omówiłem teorie niezbędną do napisania generatora algorytmów mieszających. Teraz najwyższa pora zacząć pisać pierwsze linijki kodu.
Jeśli nie czytałeś wspomnianej teorii najlepiej będzie jeśli się z nią wcześniej zapoznacz aby lepiej zrozumieć kod, który dzisiaj powstanie.

Zmiany, które dzisiaj stworzymy możecie także przejrzeć pod linkiem:
Moje zmiany na githubie

Artykuł dostępny także w wersji angielskiej.

Stworzenie pierwszych niezbędnych klas

Zaczniemy od stworzenia enuma odpowiedzialnego za przechowywanie wszystkich możliwych ruchów na kostce. Są to
R, R2, R', L, L2, L', F, F2, F', B, B2, B', U, U2, U', D, D2, D'

Kod odpowiedzialny za to znajduje sie poniżej:

Następnie stworzymy interfejs dla implementacji scramble’a. Będą nam potrzebne na początek trzy metody.

  • addMove – dodające nowy ruch do scramble’a,
  • getMove – pobierająca ruch o danym id ze scramble’a
  • getLength – pobierająca długość algorytmu mieszającego

A oto i sam kod interfejsu:

Kolejny interfejs który będzie nam potrzebny to ten odpowiedzialny za generator algorytmów mieszających. Będzie on posiadał tylko jedną metodę generate, która dla podanej liczby będzie generowała algorytm mieszający o takiej długości.

Podstawowa funkcjonalność generatora

Kolejnym krokiem jest napisanie prostego testu sprawdzającego czy wygenerowany algorytm jest takiej długości jaka została przekazana do metody generate. Dodatkowo test sprawdza czy obiekt został wypełniony instancjami enuma Move. Wykorzystam tutaj test parametryzowany, który sprawi, że ten sam test uruchomi się wielokrotnie dla różnych danych podanych w metodzie getScrambleLengthProvider.

Teraz odpalając nasz test dostaniemy błędy mówiące, że klasa ScrambleGenerator nie istnieje. Konieczne jest zatem jej utworzenie i zaimplementowanie niezbędnej metody generującej. Robimy to zatem a kod można zobaczyć na listingu poniżej. Nie trzeba go chyba specjalnie tłumaczyć. Tworzy on tylko obiekt klasy Scramble, a następnie wypełnia go losowo używając ruchów dostępnych w enumie Move.

Napisaliśmy własnie podstawową funkcjonalność generatora. Ale to jeszcze nie koniec. Jeśli uważnie czytałes poprzedni wpis wiesz, że musimy także rozpatrzyć kilka przypadków które nie powinny się zdarzyć. W obecnej implementacji możliwe jest kilkukrotne wylosowanie tej samej ścianki pod rząd lub naprzemienne ruszanie równoległymi ściankami.

Usprawnienie algorytmu o unikanie skracających się ruchów

Czas zająć się napisaniem funkcjonalności pozwalającej na unikanie losowania ruchów, które można w prosty sposób skrocic. Zaczynamy więc ponownie od testu. Oto i on:

Testy oczywiście znowu zaczną świecić na czerwono. Trzeba je zatem naprawić. W naszym teście zakładamy istnienie metody isPossibleNextMove dla klasy Scramble, jej interfejsu, a także wsparcia enuma Move dla grup i ścianek. Dopisujemy zatem te funkcjonalności w pierwszej kolejności.

Testy zaczęły znowu przechodzić ale to jeszcze nie koniec ponieważ generator nadal nie działa poprawnie. Tworzymy zatem kolejny test dla generatora sprawdzający czy wygenerowany algorytm jest zgodny z załozeniami:

Metoda assertFaceNotDoubled sprawdza czy ścianka nie została wylosowana ponownie. Natomiast metoda assertGroupNotDoubled sprawdza czy nie ruszamy naprzemiennie ściankami równoległymi.
Testy oczywiście znowu zaczną nie przechodzić, a naszym kolejnym krokiem jest sprawienie aby znowu były zielone.

W pierwszej kolejności dodajemy metodę toString dla klasy Scramble, która będzie wyświetlała wygenerowany algorytm w formie czytelnej i jest wykorzystywana w asercjach w celu zwrócenia gdzie i w jakim algorytmie wystąpił bład.

Następnie zmieniamy implementację metody generate naszego generatora:

Jedyna zmiana to dodanie ifa w linii 21 i 23 korzystającego z naszej nowej metody z klasy Scramble. Teraz uruchamiając nasze testy wszystkie powinny ponownie zaświecić się na zielono, a my wiemy, że generator działa tak jak chcieliśmy.

Podsumowanie

Dzisiaj stworzyliśmy nasz pierwszy kod. Został on wrzucony także na githuba gdzie możecie go w wygodny sposób przegladać. Dostępny jest pod linkiem:
Moje zmiany na githubie

Co dalej?

W kolejnym wpisie znowu zajmiemy się teorią i poznamy metryki mierzenia ruchów na kostce. Będzie nam to niezbędne w celu napisania kolejnych klas liczacych długość zarówno algorytmów mieszających jak i rozwiązań pomieszanej kostki.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *