Nick’s Code

Search

XNA MVP

Contact

Donate

Categories

Latest News

Twitter


follow nickgravelyn at http://twitter.com



RSS Feed

Steve Has Life… Sort Of

Posted in Artificial Intelligence on October 01, 2007 at 12:36am.
There are no comments.

So my ongoing AI program is called Steve. A long conversation about it with my brother is where the name came from. My first AI I taught a name to and it was Steve. So now Steve is the name of the AI itself. Go figure.

Anyway I went back to working on my script parser. The parser now scans through the script and records all the types of local variables used, then uses an ILGenerator to declare all those local variables in a DynamicMethod. I’ve now begun the work of parsing the actual commands into OpCodes and emitting them. So far the script can generate code to store and recall local variables as well as constants. The script parser can also handle basic mathematic operations (+, -, /, *, and %) so those can be used. So using my AI library, I can run this code and it will successfully print out 50:

Script testScript = new Script(
	typeof(int),
	null,
	"testScript",
	"save 15 in a; save 35 in b; return operator + with parameters (a, b);");

DynamicMethod meth = ScriptParser.ParseScript(testScript, typeof(Program));

int result = (int)meth.Invoke(null, Type.EmptyTypes);
Console.WriteLine(result.ToString());

Pretty cool, huh? Now I have to move on to all the more complicated things. I think next will be calling methods. Then conditionals. That will probably keep me busy for a while. I definitely underestimated the challenges of this, but as I go I’m finding all the shortcuts to doing things so hopefully the rest of the process will be fairly straightforward. But now that I said that… :)



EvoLib and EvoScript

Posted in .NET, Artificial Intelligence on August 12, 2007 at 2:53am.
There is one comment.

By now it’s no surprise that I like dynamic content. My current venture is such a huge step, in my opinion, for simulations and AI that I hope things work out as well as they have been going.

So I have a class that is able to derive new types using itself as the parent class. The class can add fields to these new classes and even add an Inherited attribute to them so that values get passed down generation to generation. But what about methods?

I pondered this for days. I knew I had to use the ILGenerator class to emit the OpCodes for the IL, but the question was how to set this up. I could attempt to create a structure to represent the OpCodes and their potential parameters, but there are about 23 or 24 (I never did count) different methods of Emit in the ILGenerator class. So that’s at least 23 or 24 different OpCodes/parameters combinations to account for. On top of that, that method would be sloppy and hard to create dynamically.

I wanted an easier way. I wanted a way that allowed pretty much anyone to script the evolutionary process of my classes. I wanted a way that would be easy to have the classes themselves write up new methods using existing data. This idea was born into EvoScript.

EvoScript is my first “language” I’ve ever attempted to write. The goal is a simple, English-like syntax that represents the functionality of C#. I will then write a parser for this code that will emit the proper OpCodes for dynamic method generation. By going this route, I pay the price all in design and implementation time, but then get to reap the benefits throughout its use by not having to continually type in the OpCodes by hand. Instead I get to use a simple scripting language to command my method generations.

So what does EvoScript look like? Well the current standard isn’t set in stone, but I have the rough draft version of the language completed. You can read my (basic) design doc here: EvoScript Description. Note that I haven’t started writing the parser, so any gotchas in my constructs haven’t been picked out yet. But just from looking it over, I don’t think I’ll have any conflicts of names with keywords or anything like that.

So I’ll take the next few days to finalize EvoScript version 1 and then I’ll begin work on the parsing system. My current goal is to have the version 1 parser completed by the 25th. That gives me about two weeks. With any luck I’ll accomplish this. Once EvoScript is done, my EvoLib library will quickly flourish into some amazing tech demos displaying the power of Reflection and dynamic type and method generation.



Behold The Future Demise of Mankind

Posted in .NET, Artificial Intelligence on August 09, 2007 at 11:18pm.
There are no comments.

So I’ve completed the first version of my AI. I have a class that can derive itself to create a new AI that has new fields inside of it. The AI itself is a very basic shell. Only about 160 lines of code with comments. I then have the interface program which is about 270 lines of code. So in 430 lines of code I have a system for teaching my computer how to store integers, floats, doubles, and strings as well as being able to later update them or display them.

While making this I debated whether this was worth it. Is it worth it to derive a new class for each field? Why not simply store a Dictionary<string, object> for all the knowledge and go with that? Admittedly that would work for what I’m currently doing. In fact that would probably work faster for what I currently do because I rely on Reflection to get the fields and then set or return them. But the main question became, how much can you extend that solution? Can you extend the interface?

Part of my quest was to create a new AI. AI doesn’t just involve retaining and regurgitating information. The AI must be able to do things with the information it has. It has to be able to perform tasks and, eventually, be able to make correlations, assumptions, and associations. That is why I chose to derive the classes. With this framework in place, later versions of the AI are completely able to add new methods to their derived classes; thus extending the functionality of the class.

Currently my BaseAI class exposes just a few methods:

bool ContainsKnowledge(string name);
Returns whether or not the AI has a field with the given name

object GetValue(string name);
Returns the value of the field with the given name

void SetValue(string name, object value);
Sets the value of the field with the given name

Dictionary<string, object> GetAllKnowledge();
Returns all the fields in the class using the names for keys

BaseAI DeriveAI(string newKnowledgeName, Type newKnowledgeType, object newKnowledge);
Derives the AI adding the new information in there.

You can see it’s a fairly simple set up. But there is nothing stopping the AI class from storing more information or exposing more methods. For instance the AI might eventually want to start figuring out if two things are equal. So it would be able to derive itself, add a new list of strings that are equal, and then start checking if values are the same.

For example if my AI has these two fields:

string Maker = “Nick;
string God = “Nick”;

Then it could derive itself, and the next generation would know that Maker == God. This could turn useful as many things in the world are referred to by different names (soda and pop for instance).

My AI would also be able to learn new methods. You could teach how to associate sentences and words with objects and classes. Thus the AI would know that an int was an int. So if it had this field:

int MyAge = 20;

And you asked it, what is MyAge? It would not only tell you that MyAge is 20, but also that MyAge is an integer. You could go beyond this to associating with it that any class derived from BaseAI is a friend and anything else should be feared as an enemy. :)
The possibilities at this point truly are limitless. The honest hardest part is creating the interface for the AI to be programmed. I will hopefully be able to refine the AI’s learning techniques a bit and then be able to stick him inside of some 3D environment and then let the fun begin. My AI could learn about itself and its surroundings, followed by learning about objects in the world. Imaging trying to explain gravity to the AI. :)



Dynamic Types And AI

Posted in .NET, Artificial Intelligence on August 09, 2007 at 9:39pm.
There are no comments.

I’ve recently been reading about System.Reflection and System.Reflection.Emit. I’ve been thrilled using System.Reflection for some of my classes so that I can call the proper constructors in generic classes of mine. This ability was one of the major points at which I decided that C# and the .NET runtime were officially the best programming environment.

But then I discovered System.Reflection.Emit. The idea that I can generate new types and methods at runtime was, at first, mind blowing. I had no idea how that could even be possible. But after reading, it involves learning a bit of MSIL code and having a bit of patience (the exceptions that get thrown usually aren’t very helpful). I started with a few basic methods to add numbers together and ran with it.

For instance, to make a new method at runtime that will add two numbers you would do so like this:

DynamicMethod dm = new DynamicMethod(
“add”,
typeof(int),
new Type[] { typeof(int), typeof(int) },
typeof(Program).Module);

ILGenerator gen = dm.GetILGenerator();

//push the arguments onto the stack
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);

//add the last two objects on the stack
gen.Emit(OpCodes.Add);

//return the top object on the stack
gen.Emit(OpCodes.Ret);

object[] args = new object[] { (object)5, (object)7 };
Console.WriteLine(
args[0].ToString() + ” + ” + args[1].ToString() + ” = ” + dm.Invoke(null, args).ToString());

I’m certainly not going to even attempt to explain this code as it would take pages, but needless to say you can imagine that this is a little difficult when you think about scaling up to harder operations. Most of what you deal with is writing all the IL commands to modify the stack. It’s really interesting and fun for me as I’ve never done anything like assembly or IL code before.

So I began to think: if I can generate new types and methods at runtime, can I apply this to artificial intelligence? I discussed it for a bit with some other big thinkers (i.e. my brothers) and I came to the conclusion that I could procedurally derive classes from a base AI class and create a system where the AI can actually learn new things. How you ask? Let’s explain.

When most people think of AI, they think in the realm of one particular application. Perhaps a racing game AI. So in that mindset, an AI only has to “learn” about it’s track, the competitors, and similar things. Basically this means that the AI has a finite list of things it needs to know and the programmers know at design time what these things are. Same applies to, say, first person shooter AI. It’s all the same. Programmers strictly define a finite amount of information for the AI at design time and therefore can leverage that when “teaching” their AI.

So what I thought about was creating an AI that truly could learn. An AI that, at it’s “birth,” had no knowledge whatsoever. In coding terms my base class is one with no fields at all. The idea being that the AI would dynamically derive a new class whenever it learned something new, adding a new field in the process. My AI would then replace itself with this new AI. This would allow my system to continually learn more and more almost without limit.

So the first challenge I had was to figure out how my AI would be able to access these new fields being that the base class would have no knowledge of them at design time. In comes System.Reflection. I designed a couple of generic methods in my base class for getting and setting fields based on name. I use Reflection to look up the field by name and get or set the value. It may not be the most efficient way, but it does get the job done and it works well enough for now.

With that taken care of I created a few methods in my program to easily derive classes and add new fields and thus my AI was born. My current goal is to create a command-line interface where you can actually teach the AI new things and have it recall things it knows. I’ll probably have that done later tonight and I will certainly post back when I do.

Oh the wonders of .NET and Reflection.