Generowanie poprawnych gramatycznie opisów ataków typu MUD

13

Obecnie pracuję nad grą tekstową, w której wynik rundy walki wygląda mniej więcej tak

%attacker% inflicts a serious wound (12 points damage) on %defender%

W tej chwili właśnie zamieniłem% atakującego% na nazwę atakującego, a% defender% na imię obrońcy. Jednak opis działa, ale nie czyta się poprawnie. Ponieważ gra składa się tylko z samego tekstu, nie chcę uciekać się do ogólnych opisów (takich jak „Używasz ataku na goblina za 5 obrażeń”, co prawdopodobnie rozwiązuje problem)

Jak wygenerować prawidłowe opisy dla przypadków, do których odnosi się% attacker%

  • „Ty”, gracz? „Zadajesz ...” jest błędne
  • „Pszczoły” lub inna liczba mnoga? Muszę jakoś wiedzieć, że powinienem poprzedzić nazwę „The”
  • Jeśli% attacker% jest rzeczownikiem rodzajowym, takim jak „Goblin”, będzie on czytał dziwnie, w przeciwieństwie do% attacker% będącego nazwą. Porównaj „Goblin zadaje ...” kontra „Aldraiczny Miecznik zadaje ...”

W jaki sposób gry tekstowe zazwyczaj rozwiązują takie problemy?

Extrakun
źródło

Odpowiedzi:

15

Podejście% atakujący% można rozszerzyć, aby zawierało pewne informacje inne niż tylko nazwy obiektów:

  1. Czasownik może być w liczbie pojedynczej lub mnogiej. To zależy od tematu. „Ty zaatakować X” (liczba pojedyncza 2. osoba podlega) vs. „Extrakun ataki X” (liczba pojedyncza 3 osoba podlega) vs. „Gobliny atakują X” (liczba mnoga 3 osoba podlega). Większość czasowników wymaga tylko -sdodania, ale jest kilka wyjątków.
  2. Rzeczownik może być rzeczownikiem właściwym („ Goblin atakuje X”) lub rzeczownikiem zwyczajnym („ Goblin atakuje X”). Typowe rzeczowniki zaczynające się od dźwięku samogłoskowego powinny używać „an” zamiast „a”. Może to być rzeczownik pospolity, ale w obecnym kontekście ma tylko jedną instancję („ Goblin atakuje X”).
  3. Rzeczownik może mieć różną liczbę, od zera („Nie trafiłeś goblinów ”) do jednego („ Uderzyłeś jednego goblina ”) do wielu („ Uderzyłeś w trzy gobliny ”). Wiele rzeczowników potrzebuje -slub -esdodaje, ale istnieje wiele wyjątków.
  4. Podmioty i przedmioty mogą być proste („ Goblin ”) lub złożone („ Goblin i jej brat ”).
  5. Rzeczowniki pospolite na początku zdania muszą być pisane wielkimi literami, ale jeśli rzeczownik ma artykuł lub jest złożonym, chcesz używać tylko pierwszego słowa. Właściwe rzeczowniki są zawsze pisane wielką literą.
  6. Stanowisko przedmiotem ( „ She hit goblin«) i położenie obiektu (»Goblin uderzył ”) stosują różne zaimki.
  7. Własności można generować, dodając, 'sjeśli liczba pojedyncza („ Siekiera goblina ”), 'jeśli liczba mnoga („Dwie osie goblinów ”), ale zaimki mają swoje własne reguły („ Twoja siekiera”).

W języku angielskim napisałem w Pythonie bibliotekę do generowania tekstu pochodzącą z MUD o ​​nazwie JaysHouseMOO. Zachęcamy do przestudiowania lub skopiowania kodu . Nie ma dobrej biblioteki wyjątkowych przypadków; musisz dodać to do słów użytych w grze. Obawiam się, że mój przeniesiony kod nie został dokładnie przetestowany. Może także wymagać dodania większej liczby skrzynek do gier (został zaprojektowany dla MUD społecznościowego, a nie MUD do gier).

Twój przykład zostałby zapisany jako "%1I %1:(inflicts) a serious wound (%2n damage) on %3i". Liczby %1, %2, %3powiedzieć to obiekt, który ma być podstawione; I/ ipowiedz mu, aby w razie potrzeby dodał pośredni artykuł („a”, „an”); nkaże wyświetlać rzeczownik bez artykułów; :(inflicts)każe skoniugować czasownik dla tego obiektu.

Oto wyniki, które można pokazać atakującemu, obrońcy i wszystkim innym:

$ python
>>> import msg
>>> m = "%1I %1:(inflicts) a serious wound (%2n damage) on %3i."
>>> attacker = msg.GenderedObject('Amit', 'm', 'proper')
>>> defender = msg.GenderedObject('goblin', 'm', 'unique')
>>> points = (12, 'point')
>>> msg.Msg().sub_parties({1: attacker, 2: points, 3: defender}, 
                          m, [attacker, defender])
(['You inflict a serious wound (12 points damage) on the goblin.', 
  'Amit inflicts a serious wound (12 points damage) on you.'], 
 'Amit inflicts a serious wound (12 points damage) on the goblin.')

Zauważ, że jeśli go podałeś, (1, 'point')wydrukowałby „1 punkt” zamiast „1 punktu”. Jest to coś, co wkurza mnie w tekście gry, więc zadbałem o to, aby ułatwić sobie prawidłowe drukowanie.

Oto inny przykład z rzeczownikami złożonymi i „a” vs. „an”:

>>> m = "%1I %1:(hits) %2'n %2'(head)."
>>> a1 = msg.GenderedObject('goblin', 'm', 'normal')
>>> a2 = msg.GenderedObject('orc', 'm', 'normal')
>>> d1 = msg.GenderedObject('Amit', 'm', 'proper')
>>> d2 = msg.GenderedObject('Extrakun', 'm', 'proper')
>>> msg.Msg().sub_parties({1: [a1, a2], 2: [d1, d2]}, m, [d1, d2])
(["A goblin and an orc hit your and Extrakun's heads.", 
  "A goblin and an orc hit Amit's and your heads."], 
 "A goblin and an orc hit Amit's and Extrakun's heads.")

Przykłady te są w języku angielskim i obejmują tylko męskie / żeńskie, zaimki, czasowniki / rzeczowniki w liczbie pojedynczej / mnogiej oraz rzeczowniki właściwe / pospolite. To, co musisz śledzić, będzie się różnić w zależności od języka i rodzaju tekstu w grze. W języku hiszpańskim istnieją zaimki formalne i nieformalne. Kilka języków ma męskie i żeńskie formy czasowników. Zaimki japońskie zależą od statusu podmiotu w stosunku do obiektu. W niektórych językach koniugacja czasownika może domyślnie obejmować temat. Określ wszystkie rodzaje tekstu, który chcesz wygenerować, oraz języki, na które chcesz tłumaczyć, a to powie ci, co musisz śledzić w obiektach gry. Podczas tworzenia treści możesz dołączyć niezbędne adnotacje i wyjątkowe przypadki.

amitp
źródło
1
+1, świetne podsumowanie problemów. Jedną rzeczą, którą dodam, jest to, że gracze wybaczają niewielkie błędy gramatyczne w generowanym tekście, o ile reszta informacji (wielkość obrażeń, źródło, cel, procs) jest dokładna - strzelaj z 95% poprawną gramatyką , ponieważ ostatnie 5% jest absurdalnie trudne.
6

Zamiast mieć pojedynczy ciąg i starać się odpowiednio go podstawić, możesz mieć cały zestaw. Zacznij od obiektów. Wiesz, tworząc mob, jak go nazwać. Możesz nadać mu określoną właściwość, oddzielną od nazwy, do zastępowania ciągów ataku. Broń może mieć wiele łańcuchów dla różnorodności i może zastąpić bardziej szczegółowo. Zamiast „atakujący” mogą poprosić o „zaimek atakujący” lub „nazwa atakującego”. Moby mogą mieć również wiele wersji tych identyfikatorów, jeśli twoje „pszczoły” są reprezentowane przez wiele mobów, a nie tylko jeden mob, który nazywa się „pszczołami”.

Więc miałbyś taki tłum

name = goblin
pronoun = he
plural = goblins
proper = goblin
common = a goblin
specific_common = the goblin
possessive = the goblin's
possessive_pronoun = his

Następnie łańcuch ataku prosi o określone przedmioty, takie jak ..

% zaatakujący zaimek% hit% defender-specific_common% za% obrażeń%! % zaimek-obrońca% naprawdę to poczuł!

Blecki
źródło
5

Istnieje zestaw modułów dla Perla zaczynających się od Lingua :: EN :: Inflect, który zajmuje się tymi problemami. Nawet jeśli używasz innego języka, dokonane wybory API mogą pomóc w sformułowaniu własnego projektu.

mickicks
źródło
Sprytne! W tej bibliotece znajduje się również port Python: pypi.python.org/pypi/inflect/0.2.1
amitp
3

Sposób, w jaki sobie z tym radzę, polega na dużym zestawie systematyki, który między innymi polega na modelowaniu wiadomości jako struktury danych, a nie ciągu. Wartości dla atakującego i obrońcy są ich faktycznymi obiektami; czasownik („zadaj” w Twojej wiadomości) jest oznaczony jako taki i zna obiekt dla osoby, która go wykonuje, dzięki czemu mechanizm renderujący wie, że musi być wyświetlany w pierwszej osobie dla aktora i drugiej osobie dla wszystkich innych. Obiekty wiedzą również, czy ich rzeczowniki są poprawne, czy też nie (i dlatego, czy „lub” należy do nich kiedykolwiek zastosować), istnieją modele danych, które pozwalają mi określić, że „lub” „normalnie oczekuje się, że zostanie zastosowane do niewłaściwego rzeczownika na tej pozycji i wiele więcej.

Wątek na temat Mudconnectora jest bardzo podobny do twojego pytania, i szczegółowo tam wchodzę w szczegóły mojego systemu. Zasadniczo sposób, w jaki to robię, jest tym, czego chciałbyś, jeśli chcesz być całkowicie nieograniczony przez podstawowe możliwości swojego systemu przesyłania wiadomości i jesteś gotów zapłacić za to krzywą uczenia się. (Podobnie jak vi vs. nano.)

chaos
źródło
0

Radzę KISS (utrzymuj to głupio proste) i wykorzystaj zalety interfejsu tekstowego.

Uproszczenie, uproszczenie, uproszczenie w jak największym stopniu. Usuń złożoność, zanim zaczniesz myśleć o kodowaniu. Zamiast jednego zdania użyj dwóch zdań, aby opisać zdarzenie, tak jak wiele gier. Czy pamiętasz bramę Baldura ? To nie jest gra tekstowa, ale obrażenia są opisywane tekstem;)


Podziel informacje między źródłem zdarzenia i jego konsekwencją.

Na przykład :

  • Merlin rzucił zaklęcie ognistej kuli.
  • Madmax zostaje trafiony 3 obrażeniami ognia.
  • Goblin zostaje trafiony 2 obrażeniami ognia.
  • Goblin zostaje trafiony 10 obrażeniami ognia.
  • itp...

Radziłbym również zawsze używać trzeciej osoby liczby pojedynczej, czy byłby to rzeczownik właściwy czy pospolity.

Ponadto, chociaż angielski jest ważnym językiem międzynarodowym, jeśli chcesz mieć większy wpływ emocjonalny i dotknąć większy rynek, być może będziesz musiał przetłumaczyć swoją grę na inne języki.

Jeśli zamierzasz to zrobić, pamiętaj, że struktura zdań może być inna w innych językach. Według Wikipedii 45% dostępnych języków buduje zdanie w kolejności SOV (czasownik-przedmiot-przedmiot), a 42% (jak angielski) buduje zdanie w kolejności SVO; jak angielski.

Douglas
źródło
Baldur's Gate ma w pełni graficzny silnik, aby pokazać wynik, ale dla interaktywnej fikcji tekst jest interfejsem i sprzężeniem zwrotnym. W tym przypadku powinno być bardziej dopracowane, IMHO.
Extrakun