Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    11
  • comments
    5
  • views
    1523

Project: 13 RONIN

13 RONIN - DevLog #7 - Fight or flight!

ERASERHEAD STUDIO

827 views

Banner1500x469.thumb.png.6db05758eb7bb86b317181b6c604182f.png

Since I had no previous experience of coding a computer player I turned to our friend google for advice. I found a number of threads on the subject, some talked about AI, but most of them talked about reaction based solutions, but since I’m not interested in AI and rather want to mimic the feeling found in old-school fighting games I decided to go for the reaction based solution. And when I use the phrase “reaction based”, I’m referring to an implementation that selects action-based on one or several conditions e.g. if the opponent hit then block. 

Feeling a bit over-confident, I stopped reading and headed over to Visual Studio just to realize that this was not as easy as I had thought. Soon I had a bunch of if-statement and a code hard to follow. I refactored the code, but still I wasn’t pleased

Along came Halloween and at my workplace, we had an amazing party (I was dressed as the Invisible Man). After dinner, I chatted with a colleague and talking about the computer player he asked if I was using a decision-tree for action selection. Decision trees? What’s this, yet another gap of knowledge.

692647352_Fightorflight.gif.fdf5ad08d287a38863be0845cd8f1d92.gif

The name itself told me that this was something I had to read up on. So, the day after, still recovering from the party, I started reading. And oh yes, this was what I’ve been looking for. (Thanks Mikael for the suggestion)

Decision trees

The full definition is somewhat longer, but simplified, a decision tree is a tree structure describing conditions and results. Every node is a condition deciding upon which branch to follow until reaching the leaf and the result of the path taken. This was exactly the kind of data structure I needed to find a structure around the computer player logic Using a fluent builder I could put all conditions in a tree and let the leaves contain what actions to perform.

1915812756_Computerplayerdecisiontree-Page-2.thumb.png.2390ab118f2f90a6dcc7369360153a19.png

Decision tree for the computer player.

DecisionTreeNode

My implementation of the decision tree is very basic, it consists of a DecisionTreeNode-class that I use for the tree as well as for the nodes and the leaves. 

The Condition-property is only applicable to condition nodes. It’s a delegate that when called will evaluate what child node to step into. It returns the name of the child to step into.

The Result-property is only applicable to leaves. It’s a delegate with actions associated to the leaf.

DecisionTreeNode.png.0608495298985fce76b34a0bc4957ba2.png

The GamePlayState-class contains all data needed when deciding computer action.

DecisionTreeBuilder

I’m quite fond of fluent coding so when building the DecisionTreeBuilder it was a natural pattern to choose. Using this pattern makes classes easy to use and code easy to read.
 
This is how I build the decision tree

var decisionTree =
    DecisionTreeBuilder
        .Begin(
            "Reacting",
            state =>
                state.Player.IsReacting()
                    ? "Elapsed"
                    : "Opp new action")
        .AddNode(
            "Elapsed",
            state =>
                state.Player.IsTimeToReact(state.GameTime.TotalGameTime)
                    ? "Facing"
                    : "Done 1")
        .AddNode(
            "Facing",
            state =>
            {
                return
                    state.Player.IsFacingOpponent()
                        ? "Reachable 1"
                        : "Reachable 2";
            })
        .AddNode(
            "Reachable 1",
            state =>
                state.Player.IsWithinReach(state.Opponent)
                    ? "Opp attacking"
                    : "Opp approaching")
        .AddNode(
            "Opp attacking",
            state =>
                state.Player.ActionToReactUpon is AttackAction
                    ? "Defend"
                    : "Attack 1")
        .AddLeaf(
            "Defend",
            state =>
            {
                state.Player.ResetReaction();
                state.Player.ParryHeadCut();
            })
        .AddLeaf(
            "Attack 1",
            state =>
            {
                state.Player.ResetReaction();
                state.Player.HeadCut();
            })
        .Parent()
        .AddNode(
            "Opp approaching",
            state =>
                state.Opponent.IsAdvancing() &&
                state.Opponent.IsFacingOpponent()
                    ? "Idle 1"
                    : "Advance 1")
        .
        .
        .
        .Build();

AddNode will create and append a new node to the current nodes’ children and then go into the newly created node and make it current. AddLeaf will create and append a new leaf, but not go into it. Parent will go to the parent node and make it current. Build will return the newly composed tree. 

1915812756_Computerplayerdecisiontree-Page-2.thumb.png.2390ab118f2f90a6dcc7369360153a19.png

The choice to use strings for names makes it easy to follow the code but also makes it easy switching between the diagram and the code. The Parent-, and Name-properties together with the GetFullName method make nice tools while debugging.

Player

In my game I have a HumanPlayer-class and a ComputerPlayer-class, both implementing an abstract class Player. The main difference between the Human- and the ComputerPlayer-class is how the Update-method is implemented. The HumanPlayer-class is using input from keyboard and gamepad to control the player character while the ComputerPlayer is using the decision tree. 

Player.thumb.png.f5cef3c1c98046482168eb2a982ed1f8.png

The code for using the tree looks like this:

    var leaf = _decisionTree.Evaluate(state);
    leaf.Action(state);

Nice, isn’t it?


Happy coding!
jan.

 

DecisionTreeBuilder.png




0 Comments


Recommended Comments

There are no comments to display.

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
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By XenahE
      Hi there, 
      I am new to this forum and wanted to say hi first of all. 
      Secondly, I am in the process of creating a vertical 2d shooter using the assets I am creating on photoshop and illustrator. I want to put a scrolling parallax in the background to give the illusion that the player is moving forward (similar to Skyforce Anniversary) but I am not sure how best to create the graphics in terms of the document size etc. I have used a scrolling parallax before using a 3D game object in unity and wrapping a background to it. This works fine for a repeating background but I would like mine to change throughout the level. 
      Has anyone got any experience with doing something like this?
      Thanks in advance 
      Xe
    • By keki123
      Hi there,
      I need help! Based on my own experiences, I have a theory that if we (game designers/builders/creators of awesomeness) were to have a simple method for collecting and analyzing feedback about our games we could:
      significantly improve the early game-play and feel of the game,
      reduce the time it takes to keep or kill our ideas,
      improve the time it takes to go from thinking to world building (idea to production),
      stay engaged whilst on the journey to full production.
      So before I go any further with my theory, I’d love to get your thoughts and opinions. Are the problems I face just mine or are you experiencing them too?
      Please help me by completing this quick questionnaire:
      https://www.surveymonkey.com/r/9SFXKHD (it should only take 2-3 mins) 
      or providing any comments you feel might help (please be constructive ;)).
       
      Thanks in advance!
    • By Pepsidog
      I'm wanting to create a hybrid game between turn based and action.  I'm looking to create a system where the player has a list of attack or move options on their turn, but I want to add a skill minigame in order to make the game more engaging for non-strategists.  I figured some sort of minigame or something.  Any ideas are welcome.  Thanks in advance!
    • By RoKabium Games
      The red hued resources you can find in SAMA is mostly on the pink and brown side of red, but the Quarky is as bright and deep red as it comes!
    • By phil67rpg
      I have a very simple question, I am trying to rotate some vertex's around an arbitrary axis. basically I want to use glRotatef and glTranslatef to rotate a space ship I have drawn on the screen. here is my code of my  ship. what it does do is rotate around the origin when I  use the arrow keys left and right.
      void drawShip() { glPushMatrix(); glColor3f(255.0f, 0.0f, 0.0f); glTranslatef(-50.0f, 0.0f, 0.0f); glRotatef(rotateship, 0.0f, 0.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex3f(50.0f, 0.0f, 0.0f); glVertex3f(45.0f, -5.0f, 0.0f); glVertex3f(50.0f, 10.0f, 0.0f); glVertex3f(55.0f, -5.0f, 0.0f); glEnd(); glTranslatef(50.0f, 0.0f, 0.0f); glPopMatrix(); }  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!