Tworzę grę podobną do Tetris, z dwiema głównymi różnicami: ekran już zaczyna się wypełniać kafelkami (jak w Puzzle Quest na Nintendo DS i PC), a każda płytka ma literę. Celem gracza jest eliminacja płytek, tworząc z nimi prawidłowe słowa. Słowa są tworzone przez umieszczanie liter obok siebie, w dowolnym kierunku, z wyjątkiem ukośnych.
Gracz może przesunąć cały rząd płytek w lewo lub w prawo lub całą kolumnę płytek w górę lub w dół, na tyle pól, ile chce (jeśli ruch rzędu / kolumny przekracza granice planszy, litera przekraczająca limit będzie „cyklować”, pojawiając się na drugim końcu wiersza / kolumny). Po akcji gracza gra powinna sprawdzić całą planszę w celu znalezienia prawidłowych słów i usunąć litery tworzące te słowa z planszy. Litery powyżej tych, które zostały usunięte, spadną w miejsce tych, które zostały usunięte, a nowe litery spadną z góry ekranu, aż tablica zostanie ponownie wypełniona.
Napisałem już algorytm liniowy, który na podstawie sekwencji znaków określa, czy jest to poprawne angielskie słowo. Mam problem: jak mogę sprawdzić poprawność słów na tablicy? Czy brutalna siła jest jedynym sposobem? Testowanie wszystkich możliwych kombinacji z planszy, aby sprawdzić, czy są poprawne, jest bardzo powolne, nawet dla małej (5x5) planszy. Każda pomoc będzie bardzo mile widziana, dzięki!
źródło
Odpowiedzi:
Brutalna siła to nie jedyny sposób.
Układanie planszy jest podobne do układania planszy Boggle , z wyjątkiem prostszych. Chcesz sprawdzić każdy kafelek na planszy, sprawdzając, czy są jakieś słowa, które można ułożyć we właściwych kierunkach.
Nadal chcesz uściślić swoją przestrzeń wyszukiwania, abyś nie zawracał sobie głowy szukaniem kierunku, jeśli wiesz, że nie możesz napisać słowa. Na przykład, jeśli znajdziesz dwa
q
s z rzędu, powinieneś przerwać. W tym celu potrzebujesz struktury danych, która pozwala stwierdzić, czy dany zestaw znaków jest prefiksem prawidłowego słowa. W tym celu możesz użyć drzewa trie lub prefiksu; przydatna struktura danych przy rozwiązywaniu takich problemów.Drzewo prefiksów to hierarchiczna struktura oparta na węzłach, w której każdy węzeł reprezentuje jakiś prefiks swoich elementów podrzędnych, a węzły liści (ogólnie) reprezentują wartości końcowe. Na przykład, jeśli słownik prawidłowych słów zawiera „kot”, „samochód” i „komórka”, trie może wyglądać następująco:
Dlatego zacznij od wypełnienia drzewa przedrostków każdym prawidłowym słowem w grze.
Rzeczywisty proces znajdowania prawidłowych słów na planszy w danym momencie będzie wymagał rozpoczęcia wyszukiwania rekurencyjnego z każdego kafelka na planszy. Ponieważ każde przeszukiwanie przestrzeni planszowej rozpoczynającej się od danego kafelka jest niezależne, w razie potrzeby można je zrównoleglić. Podczas wyszukiwania „podążasz” za drzewem prefiksów na podstawie wartości litery w kierunku, w którym szukasz.
W końcu dojdziesz do punktu, w którym żadna z otaczających liter nie jest potomkami twojego obecnego węzła drzewa prefiksów. Po osiągnięciu tego punktu, jeśli prawdą jest również to, że bieżący węzeł jest liściem, znaleziono prawidłowe słowo. W przeciwnym razie nie znalazłeś prawidłowego słowa i możesz przerwać wyszukiwanie.
Przykładowy kod i omówienie tej techniki (i innych, takich jak rozwiązanie do programowania dynamicznego, które może być jeszcze szybsze poprzez „odwracanie” przestrzeni wyszukiwania po modzie) można znaleźć na blogu tego faceta ; omawia rozwiązywanie problemu Boggle, ale dostosowanie rozwiązań do gry jest mniej więcej kwestią zmiany kierunku, w którym możesz szukać.
źródło
Być może próbowałeś tego, już to zaimplementowałeś, może lepiej dołączyć inną odpowiedź itp. Ale nie widziałem ich (jeszcze) wspomnianych, więc oto:
Możesz odrzucić wiele czeków, śledząc, co się zmieniło, a co nie. Na przykład:
lub w kodzie psudo
I trywialne pytania:
Czy masz ustawione optymalizacje prędkości kompilatorów? (jeśli używasz jednego)
Czy w ogóle można zoptymalizować algorytm wyszukiwania słów? W jakikolwiek sposób?
źródło
IF(rowMoved){ checkColumns(); checkMovedRow(); } IF(columnMoved){ checkRows() checkMovedColumn();}
Jeśli użytkownik może przenieść tylko jeden na raz, to na końcu tego ruchu nie zostały przeniesione żadne równoległe litery, a zatem nie trzeba ich ponownie sprawdzać.Pamiętaj, że każda postać jest wartością. Wykorzystaj to na swoją korzyść. Istnieje kilka funkcji skrótu, które można szybko obliczyć podczas iteracji na podciągach. Na przykład, powiedzmy, że każdemu listowi nadajemy 5-bitowy kod (po prostu zrób
c - 'a' + 1
w C):Następnie możesz szybko przejechać wszystkie podciągi określonego rozmiaru:
W ten sposób możemy sprawdzać podciągi do 12 liter w większości popularnych obecnie architektur.
Jeśli w słowniku znajduje się kod skrótu, możesz go szybko pobrać, ponieważ takie kody skrótu są unikalne. Po osiągnięciu maks. 12 liter możesz dodać kolejne struktury danych dla słów zaczynających się od tych 12 liter. Jeśli znajdziesz słowo, które zaczyna się od 12 liter, po prostu utwórz listę lub inną małą tablicę skrótów dla sufiksów każdego słowa, które zaczyna się od tego prefiksu.
Przechowywanie słownika wszystkich istniejących kodów słownych nie powinno zająć więcej niż kilka megabajtów pamięci.
źródło
Czy przy formowaniu słów ograniczasz się tylko do klasycznych kształtów Tetris, czy zrobi to jakakolwiek formacja? Czy słowa mogą zginać się w nieskończoność lub tylko raz? Czy słowo może być tak długie, jak chce? Jest to dość skomplikowane, jeśli możesz wykonać tyle zakrętów, ile chcesz, tworząc najdłuższe możliwe słowa o długości 25 znaków. Zakładam, że masz listę zaakceptowanych słów. Przy takim założeniu sugeruję wypróbowanie czegoś takiego:
Spowoduje to utworzenie mapy na każdym kafelku z informacją o tym, jak ten kafelek jest połączony ze słowami wokół niego w siatce. Po przesunięciu kolumny lub wiersza sprawdź wszystkie płytki, które były lub sąsiadują z ruchem i ponownie oblicz informacje. Kiedy znajdziesz słowo, a do tego słowa nie będzie można dodać kolejnych kafelków; usunąć to. Nie jestem pewien, czy będzie to szybsze, tak naprawdę sprowadza się do tego, ile słów jest w połowie stworzonych. Zaletą tego jest to, że użytkownik najprawdopodobniej próbuje utworzyć słowo z półpełnego słowa na tablicy. Przechowując wszystkie te słowa w pamięci, łatwo jest sprawdzić, czy słowo zostało uzupełnione.
źródło