Smart A.I.
I don''t know how everyone else does there A.I. (or can''t understand) anyway, I''ve thought up two different A.I. methods...
One of them is for real AI, and I''m still thinking on this, so I''ll leave it out...
The other is the one I''m going to use for my RPG games... To break it down, It''s very simple...
You create all of the possible actions, and place them in a select case (visual basic, not sure for other languages) statement, or several If''s. The Select, or If''s point to Varaibles, that are set by other conditions...
You then create a random number, and run it throught the statements.... I know I''m not to good at explaining this, but a better type explanation is below...
Possible Actions-
1. Attack
2. Defend
3. Run (Escape)
4. Heal
Now, lets say these are the possible actions a creature can perform...
Now the Varaibles compared to to run these are all like this...
Action Var1 Var2
1 1 25
2 26 50
3 51 75
4 76 100
As you can see each action has two variables, these are going to be used as percents... since with those variables, if a random number from 1 - 100 is generated it has a 25% chance of being within each Action variable Pair...
Now for this specific creature, somewhere in the health code, it checks it''s current Health, and then changes those "percents" to fit...
For example, if the creature''s health is 10 (out of 100) it may set the values to this:
Action Var1 Var2
1 1 1
2 2 2
3 3 50
4 51 100
Now, with these variables, the random number will mroe than likely Heal or Escape... Creating a "smart" A.I. because the actions are not completely based on Reaction, but enough to create the illusion of Intelect
Hope my scattered thoughts help atleast one person...
And that''''s about all I gota say about that...
And that''s about all I gota say about that...
quote: Original post by ObsidianEyes
I don't know how everyone else does there A.I. (or can't understand) anyway, I've thought up two different A.I. methods...
Okay. That's what the forum is for!
quote:
One of them is for real AI, and I'm still thinking on this, so I'll leave it out...
Fair enough, though I'd be interested in your definition of "real AI" and how it's different than "game AI'...
quote:
You create all of the possible actions, and place them in a select case (visual basic, not sure for other languages) statement, or several If's. The Select, or If's point to Varaibles, that are set by other conditions...
You then create a random number, and run it throught the statements.... I know I'm not to good at explaining this, but a better type explanation is below...
Possible Actions-
1. Attack
2. Defend
3. Run (Escape)
4. Heal
Now, lets say these are the possible actions a creature can perform...
Now the Varaibles compared to to run these are all like this...
Action Var1 Var2
1 1 25
2 26 50
3 51 75
4 76 100
As you can see each action has two variables, these are going to be used as percents... since with those variables, if a random number from 1 - 100 is generated it has a 25% chance of being within each Action variable Pair...
Now for this specific creature, somewhere in the health code, it checks it's current Health, and then changes those "percents" to fit...
For example, if the creature's health is 10 (out of 100) it may set the values to this:
Action Var1 Var2
1 1 1
2 2 2
3 3 50
4 51 100
Now, with these variables, the random number will mroe than likely Heal or Escape... Creating a "smart" A.I. because the actions are not completely based on Reaction, but enough to create the illusion of Intelect
This is a very straightforward approach that is (basically) using a form of Finite State Machine to do its thing. Nothing at all wrong with this approach if it's coded very modularly. It can be difficult to add rules as the AI gets more complex, or if something pops up in the design that you hadn't thought of (or your producer goes and promises some new feature without asking you first).
A good reference on FSMs can be found in Game Programming Gems. It was written by Eric Dybsand (a good friend of mine) but that's not why I recommend it--it's just well written.
Ferretman
ferretman@gameai.com
www.gameai.com
From the High Mountains of Colorado
Edited by - Ferretman on September 15, 2001 1:50:02 AM
Ferretman
ferretman@gameai.com
From the High Mountains of Colorado
GameAI.Com
The additional implementation problem with FSMs is the selection process. If you have an integer value represent each possible state, then you need to have a case statement within your switch statement for each of the possible values. If you use comparisons of the form
then you have to redefine your states array whenever you add a new state (and probably alter values to maintain a coherent probability distribution).
It gets more complex the more types of states are included (multiple FSMs) are added. I'm trying to maintain a number of status variables as bitfields in a "register" and use the resulting integer value as a selector, but the number of potential situations (the combination of all the individual variables) is overwhelming. Is there a more efficient selection method? I was thinking of instead writing a responder function that evaluates various portions of the status register and executes specific code based on whether or not the bit is set. This would reduce to n non-mutually exculsive branches as opposed to nCn. Am I on the right track? I think so, but I'd like to know if there are other "better" methods. Thanks.
Edited by - Oluseyi on September 15, 2001 2:17:18 AM
if( (state = rand() % 100) < states[j] )
then you have to redefine your states array whenever you add a new state (and probably alter values to maintain a coherent probability distribution).
It gets more complex the more types of states are included (multiple FSMs) are added. I'm trying to maintain a number of status variables as bitfields in a "register" and use the resulting integer value as a selector, but the number of potential situations (the combination of all the individual variables) is overwhelming. Is there a more efficient selection method? I was thinking of instead writing a responder function that evaluates various portions of the status register and executes specific code based on whether or not the bit is set. This would reduce to n non-mutually exculsive branches as opposed to nCn. Am I on the right track? I think so, but I'd like to know if there are other "better" methods. Thanks.
Edited by - Oluseyi on September 15, 2001 2:17:18 AM
Don't forget that the unit should respond to what happens around it. First, you should know where to escape to. Moreover between units of the same side (say goblins) there should be coordination. If there sevral goblins around our goblin, it would rather attack than run away, a step further would make bad goblins behave as flocks of birds, attack together, run away together.
hope it helps in anyway, probably it does not.
[EDIT]
The mechanism itself: You may want to consider an action matrix, say a matrix with four rows (attack,defend,run,heal) and many columns, each for certain situation you want to consider (say, a column for health<25%). In the cross point of each colum and row, there should be a number, a weight, say in the cross between "health<25%" and the row "heal" there would be 50. Now you sum the numbers along the row, adding the numbers in a certain column if the situation is valid (you add 50 to heal, iff health<25%). The action with the greatest weight at the end would be chosen. It is easier to maintain this way, I think, and you can make the matrix itself a class, for clean programming.
Edited by - rouli on September 15, 2001 2:22:16 AM
hope it helps in anyway, probably it does not.
[EDIT]
The mechanism itself: You may want to consider an action matrix, say a matrix with four rows (attack,defend,run,heal) and many columns, each for certain situation you want to consider (say, a column for health<25%). In the cross point of each colum and row, there should be a number, a weight, say in the cross between "health<25%" and the row "heal" there would be 50. Now you sum the numbers along the row, adding the numbers in a certain column if the situation is valid (you add 50 to heal, iff health<25%). The action with the greatest weight at the end would be chosen. It is easier to maintain this way, I think, and you can make the matrix itself a class, for clean programming.
Edited by - rouli on September 15, 2001 2:22:16 AM
I''ve been implementing the AI in the real-time strategy game I''m working on (in fact, I just posted a version with my first attempt at the AI here). I''ll describe my method for AI, and then you all can go and check out the game and see how it turned out (I was quite impressed, myself )
Basically, the AI has a number of "needs". A need is something like "More factories", "More units", "Attack the enemy", etc. Associated with each need is a weight, between 0 and 1 which represents the probability that the AI will act on that need at any given time. Acting on a need involves two things, first, it may issue orders to various units/buildings (say, "attack this unit", "build this", etc) and it may also adjust the weights of other needs.
A quick example. At the start of the game, the computer starts with one construction unit. One of it''s needs is "More units", which, since there''s only one, starts off pretty high. So it gets acted upon almost straight away. Since there''s no factories for it to build units with, all it can do is adjust the weight of the "More factories" need. So, it won''t be long before that need is acted upon. Since there''s a construction unit doing nothing, it orders it to build a unit factory. Once it''s built, the "More units" need can be acted upon (it''ll still be as high as before). Once a few units are built (and it''s usually built a second factory by this stage as well) the "Attack enemy" need will be quite high, since we''ll have a lot of units standing around doing nothing. When that''s acted upon, a bunch of units are selected to go into the enemy base (that is, your base) and start attacking stuff.
All in all, it''s quite good. Adding new "needs" won''t be much of a problem, I just have to add to a list of classes which have a RecalculateWeight() and an Act() method. The RecalculateWeight() method is called every now and then to adjust the weight of the need (for example, the "Attack Enemy" need''s weight is increased as more units are produced). The Act() method is called whenever the weight of the need is sufficiently high (based on a random number).
For what I''ve implemented so far (and it''s actully quite a tough AI, but that''s really just because it can work a lot faster than a human player. I might cripple it a bit later on to make things fairer) there''s only a couple of pages of code, and it gives quite a good effect...
codeka.com - Just click it.
Basically, the AI has a number of "needs". A need is something like "More factories", "More units", "Attack the enemy", etc. Associated with each need is a weight, between 0 and 1 which represents the probability that the AI will act on that need at any given time. Acting on a need involves two things, first, it may issue orders to various units/buildings (say, "attack this unit", "build this", etc) and it may also adjust the weights of other needs.
A quick example. At the start of the game, the computer starts with one construction unit. One of it''s needs is "More units", which, since there''s only one, starts off pretty high. So it gets acted upon almost straight away. Since there''s no factories for it to build units with, all it can do is adjust the weight of the "More factories" need. So, it won''t be long before that need is acted upon. Since there''s a construction unit doing nothing, it orders it to build a unit factory. Once it''s built, the "More units" need can be acted upon (it''ll still be as high as before). Once a few units are built (and it''s usually built a second factory by this stage as well) the "Attack enemy" need will be quite high, since we''ll have a lot of units standing around doing nothing. When that''s acted upon, a bunch of units are selected to go into the enemy base (that is, your base) and start attacking stuff.
All in all, it''s quite good. Adding new "needs" won''t be much of a problem, I just have to add to a list of classes which have a RecalculateWeight() and an Act() method. The RecalculateWeight() method is called every now and then to adjust the weight of the need (for example, the "Attack Enemy" need''s weight is increased as more units are produced). The Act() method is called whenever the weight of the need is sufficiently high (based on a random number).
For what I''ve implemented so far (and it''s actully quite a tough AI, but that''s really just because it can work a lot faster than a human player. I might cripple it a bit later on to make things fairer) there''s only a couple of pages of code, and it gives quite a good effect...
codeka.com - Just click it.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement