• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Tutorial Doctor

How would I program grammar rules?

15 posts in this topic

So, I am working on my Senses System (see my journal) and I temporarily typed the following code(LUA):

 

function TriggerEmotionChange()
    if See(box) then
        mood = 10
        setText(state, getName(box) .. "es " .. "make me glad")
    elseif See(monkey) then
        mood = 3
        setText(state, getName(monkey) .. "s " .. "make me sad")
    elseif See(building) then
        mood = 5
        setText(state, getName(building) .. "s " .. "make me turn around in circles")
    end
end

 

This made me want to create a grammar system. I know I need to do some operations on strings, namely checking whether the last letter in a string is a certain letter and then adding the appropriate ending. I know I would do a few if/else statements and then one else statement to check if all other letters of the alphabet. 

 

Just in case someone wanted to know what the code does:

 

In the example above, the getName() function gets the name of the game object and returns a string. 

The "state" variable is just a text game object. 

The value of the mood value determines the emotional state of the character. 

 

Anyone have any tips on how I might go about the grammar system (shouldn't take long to implement it) for "ing" and "es or s" endings?

 

Just a little something to get me started on how I should approach it in an efficient way? 

 

 

0

Share this post


Link to post
Share on other sites

Are you interested in creating your grammar rules in Lua, or can it be in C++?  If the latter, then why not just use an existing parser generator like Boost::Spirit?  Then you can have true support for your own domain specific language without doing the low level string manipulations.

0

Share this post


Link to post
Share on other sites
As far as I can tell, this isn't really a parsing problem (I can't find the Senses System you mentioned, either). From what I can see in this post, you're trying to pick the correct form of a word. What you need is a lexicon with words and what their other form(s) are. If you need to do more than just take a word with the form it needs to be converted to, then you need something else entirely which composes sentences from a grammar, not a parser (which uses the same grammar, but in reverse).

Taking the word endings will work for the regular cases, but English has a LOT of exceptions with commonly used words:

One fish -> Many fish (fishes sometimes acceptable based on context)
One goose -> Many geese

Verbs can be even worse:

I see it
-> I saw it
-> I have seen it


If you want a really comprehensive generative grammar system, you should look at http://en.wikipedia.org/wiki/Head-driven_phrase_structure_grammar to see if it fits your needs. Edited by Nypyren
0

Share this post


Link to post
Share on other sites

If you need a DFA generator, you can try Wombat, It lets you 'paint' the automata using a C++ based Domain Embedded Specific Language.

0

Share this post


Link to post
Share on other sites

What you need is a lexicon with words and what their other form(s) are.

 

^ That is how I would do it.

 

For any string that you want to do this to you could store its singular and plural forms (e.g. monkey stores its name in singular and plural form). Then you can just call getNamePluralised(monkey) to return the plural form.

 

Some examples:

 

(box, boxes)

(monkey, monkeys)

(building, buildings)

(sheep, sheep)

(ability, abilities)

(bacterium, bacteria)

(cactus, cacti)

 

Clearly no amount of "ing", "es, "s" manipulation is going to take you from cactus to cacti.

Edited by dmatter
0

Share this post


Link to post
Share on other sites

This kind of text processing is IMHO best done by text templates with well defined mechanism for text substitutions. There is an article on gamasutra about localizing MMORPGs that explains such an approach to some detail. Although not exactly fitting the OP's problem at first, such processing is better suited than string concatenation as shown in the OP.

 

In the end the plural problem is solved fine in a way similar to what dmatter suggests. Together with templates it may look like (boxes[p],box), perhaps with a default rule of simply appending "s" if no [p] tagged form is found.

0

Share this post


Link to post
Share on other sites

Hmm, good responses. It looks like I could use a table that stores all endings and somehow go from there. I'll try to figure this out ASAP so I can post the results on this same topic, in case someone else later comes along and wants to do the same thing.  

 

I could have the See() function take two arguments, one would be the object being seen, and the latter could be the ending:

See(box,es)
Look(boy,s)
Start(walk,ing)

Indeed going from cactus to cacti would not work in this case. This could be revised somehow. I could do the base of the word like: 

See(cact,us)
See(cact,i)

Then I could check the ending and run either a single collision test or test multiple collisions (see multiple things). 

function Smell(object,ending)
    if isCollisionBetween(Player,object) then
        setText(txt_smelling, "I smell " .. getName(object) .. ending)
    end
end
    

In this case if I did:

Smell(box)

If I wanted it singular, I would have to have an "a" in there for "I smell a box." 

Plural would be:

Smell(box,"es")

I can do a conditional statement based on the ending, but I don't know how I would change to the singular unless I do a conditional statement somewhere (don't know how it would look yet). 

 

Seems I could set all endings explicitly first as variables:

s = "s"
es = "es"
ing = "ing"
us = "us"
i = "i"
-- gotta watch that one as "i" can be a counter too. But I could use "j" instead. 
 
ending = ing
 
print(ending)
--ing
Edited by Tutorial Doctor
0

Share this post


Link to post
Share on other sites

That might sorta work for cacti, but what about geese and G's?  Just store the full word alternatives. Unless you want to teach your grammar to conjugate based on what language the word comes from, but that doesn't seem likely to be worthwile. 

0

Share this post


Link to post
Share on other sites

I like the way that Django (Python web framework) handles plurals. When you create a database table, you create it as a Python class, e.g. "class Reply(models.Model)". When displaying the reply table contents on the admin site, it guesses the plural by just adding an -s (so "replys"), however you change this by overriding it like this:

class Reply(models.Model):
	class Meta:
		verbose_name_plural = "Replies"; 

Android handles this by using quantity strings in resource files; the documentation has a good example of how this works.

 

 

I think for your code, what would work best is a system similar to Django's (assume -s unless overriden). Here's an example of these:

-- Create a class called object
local Object = { };


-- Name is string; pluralName is string or nil
function Object.new(name, pluralName)
	name = tostring(name);
	-- If no plural name was provided, assume it's just add -s       random ' to fix highlighting
	pluralName = pluralName or name.."s";

	local object = { };

	object.name = name;
	object.pluralName = pluralName;

	-- Requires the metatable for the class system to work
	setmetatable(object, {__index = Object});
	return object;
end


-- Methods
function Object:getName()
	return self.name;
end



function Object:getPluralName()
	return self.pluralName;
end



-- Dummy methods for testing
local function isCollisionBetween(objectA, objectB)
	return true;
end



local textSmelling = "SMELLING";
local function setText(type, text)
	print(type, text);
end



-- Using it:
local Player = { };

function Player:smell(object)
	if (isCollisionBetween(self, object)) then
		setText(textSmelling, "I smell "..object:getPluralName());
	end
end



local apple = Object.new("apple");
local cactus = Object.new("cactus", "cacti");

Player:smell(apple);
Player:smell(cactus);

I tested it on the Lua online demo and got:

SMELLING	I smell apples
SMELLING	I smell cacti
Edited by dr01d3k4
0

Share this post


Link to post
Share on other sites

I see the simple kind of text synthesis falling short, even if the plural problem is solved.

 

E.g.: Notice that there is a difference between writing proper names or general thing names, because the article is left out with proper names:

    "I see Jack."  (not: "I see the Jack.")

    "I see the boxes."

 

With text patterns, this can be expressed, because the name of object Jack is marked being a proper name (using tag n)

     NAME ::= "Jack[n]"

while the name of a box is not (there is no tag n)

     NAME ::="box"

so that the text pattern may look like (using the language from the cited article)

     "I see {the[!n]} $NAME$."

 

Similarly, a name of an object may carry both its singular and its plural form, how ever it has to be written, like in

     NAME ::= "geese[p]|goose"

 

I have not really understood what "See(Box,es)" is good for. It seems me being an action that may be performed on an object (possibly an object group). If so, it seems me wrong to provide the object's plural ending at this point. If the object is a single one, then its name being

     NAME ::= "goose"

or, if it is a group, then its name being

     NAME ::= "geese[p]"

is all that is needed. It is further possible to use the combined name as shown above, and have a cardinality attached to the object, where the cardinality value defines the form in the end.
 
 
BTW: The approach in the OP is hard-coded for now. As soon as you go data oriented (and you should do so), things need to be abstracted more anyway.
Edited by haegarr
0

Share this post


Link to post
Share on other sites

Nice haegarr! I am getting closer to a solution. Yes, I am going to make it object oriented. Going to make a Grammar Class. Then I could do:

name.singular
name.plural

I could store all the grammar rules in this class. The above example is oversimplified though. 

Edited by Tutorial Doctor
0

Share this post


Link to post
Share on other sites

Here is a list of rules for inflections (just found this keyword on google):

 

http://esl.fis.edu/grammar/rules/inflections.htm

 

Also I would find some other list for verb tenses

 

Wondering if these rules can be mirrored in any programming language that has good string manipulation functions. 

Edited by Tutorial Doctor
0

Share this post


Link to post
Share on other sites

Thanks TheBlendFactor. I am looking at the link to the article on "Lookup tables." When I saw that they are fast and easy and allow for exceptions I was sprung. haha. 

 

You all have given me and anyone else looking to do this a lot of varied and good information to start from. Thanks. 

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0