Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (476)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (532)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Active Time Battle AI :: Am I doing it right?  (Read 1040 times)
0 Members and 1 Guest are viewing this topic.
Offline Sethir

Senior Newbie


Exp: 3 years



« Posted 2014-01-10 13:41:19 »

My game has a similar battle system like Final Fantasy however in my system the player and the AI will only fight with one character at a time.
I'm fairly new to game developing and AI systems so I followed the advice of this article.
It suggests to use formulas to simulate certain desires instead of hard coded values like
1  
2  
3  
if(ammo == 0) {
  reload();
}


I tried my best and the result does look okay-ish. Could someone help me to improve it?
Here is the code of my behavior class. Each time it's my AI's turn the method getBehavior(Hero target) will be called.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
   private static final String BEHAVIOR_ATTACK = "attack";
   private static final String BEHAVIOR_DEFEND = "defend";
   private static final String BEHAVIOR_REGSTAM = "regstam";
   private static final String BEHAVIOR_SKILL = "skill";
   
   private Enemy host;
   private float attackBias;
   private float skillBias;
   private float defendBias;
   
   private float lastTurnHealth; // currently unused
  private float lastTurnStamina; // currently unused
 
   private Hero target;
   private float lastTurnTargetHealth; // currently unused
 
   public Behavior(Enemy enemy) {
      this.host = enemy;
      this.attackBias = 0.2f;
      this.skillBias = 0.1f;
      this.defendBias = 0.2f;
     
      this.lastTurnHealth = 1;
      this.lastTurnStamina = 1;
      this.lastTurnTargetHealth = 1;
   }
   
   public void reset(){
      this.lastTurnHealth = 1;
      this.lastTurnStamina = 1;
      this.lastTurnTargetHealth = 1;
      this.target = null;
   }
   
   /**
    *  The desire rises as the target has less health.
    *  The basic formula is 1/(0.75 + e^(targetHealthPercent / attackBias))
    * @return the desire to attack the target
    */

   private double desireOfAttack() {
      return 1/(0.75 + Math.pow(Math.E, (target.getHealthPercent() / attackBias)));
   }
   
   /**
    * The desire rises as the target has less health but lowers as the host's stamina gets low.
    * The basic formula is 1 / (0.74 + e^((targetHealthPercent / skillBias) / hostStaminaPercent))
    * @return the desire to attack the target with a skill
    */

   private double desireOfSkillUse(){
      return 1 / (0.74 + Math.pow(Math.E,((host.getHealthPercent() / skillBias) / host.getStaminaPercent())));
   }
   
   /**
    * The desire rises as the host has less health.
    * The basic formula is 1/(1 + e^(10*hostHealthPercent - 10*defendBias)
    * @return the desire to defend against the targets attacks
    */

   private double desireOfDefend() {
      return 1/(1 + Math.pow(Math.E, (10 * host.getHealthPercent()) - (10 * defendBias)));
   }
   
   /**
    * The desire rises as the host has less stamina.
    * The basic formula is 1/(1 + e^(10 * hostStaminaPercent)
    * @return the desire to defend and regenerate stamina
    */

   private double desireOfStaminaRegeneration(){
      return 1/(1 + Math.pow(Math.E, 10*host.getStaminaPercent()));
   }
   
   public CombatAction getBehavior(Hero target) {
     
      TreeMap<Double, String> desireMap = new TreeMap<>();
     
      if(target != this.target) {
         this.target = target;
         this.lastTurnTargetHealth = target.getHealthPercent();
      }
     
      desireMap.put(desireOfAttack(), BEHAVIOR_ATTACK);
      desireMap.put(desireOfDefend(), BEHAVIOR_DEFEND);
      desireMap.put(desireOfStaminaRegeneration(), BEHAVIOR_REGSTAM);
      if(host.getSkills().size() > 0){
         desireMap.put(desireOfSkillUse(), BEHAVIOR_SKILL);
      }
     
      System.out.println("AnxietyMap: "+ desireMap.descendingMap().toString());
     
      this.lastTurnStamina = host.getStaminaPercent();
      this.lastTurnHealth = host.getHealthPercent();
     
      return getBehaviorAction(desireMap.descendingMap().values().toArray()[0].toString());
   }
   
   private CombatAction getBehaviorAction(String behavior){
      CombatAction action = new CombatAction();
     
      switch (behavior) {
      case BEHAVIOR_ATTACK:
         action.skillUse(host, target, SkillBook.Enemy.attack);
         break;

      case BEHAVIOR_REGSTAM:
      case BEHAVIOR_DEFEND:
         host.isDefending(true);
         host.regenerateStamina(true);
         break;
         
      case BEHAVIOR_SKILL:
         action.skillUse(host, target, getRandomSkill());
         break;
         
      default:
         break;
      }
     
     
     
      return action;
   }
   
   private Skill getRandomSkill(){
      return host.getSkills().get(MoreMath.random(0, host.getSkills().size()-1));
   }

I want to extend the methods later to consider the "lastTurnXYZ" variables to simulate hesitation (when the player hits really really hard), euphoria (the player lost a really good chunk of health) and desperation.
Is this approach fine or should I redo it in another way?
Offline zngga
« Reply #1 - Posted 2014-01-10 18:49:12 »

This looks pretty good to me. I would be interested to see the final version.

My code never has bugs... it just develops unexpected features!
Offline actual

JGO Coder


Medals: 23



« Reply #2 - Posted 2014-01-10 20:14:27 »

One idea is to think about how you can turn your Behaviors into separate objects, which will come in handy as they get more numerous and more complex. Something like:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
public interface Behavior {
   
   float getDesirability();

   CombatAction getAction();
}


public class AttackBehavior implements Behavior { ... }

public class DefendBehavior implements Behavior {...}

// etc



This would also make it easier to do things like evaluate the most desirable Behavior:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
Behavior bestChoice = null;
float highestScore = -1;

// Assume a list of behaviors
for (Behavior behavior : behaviors) {
   float score = behavior.getDesirability();
   if  (score > maxScore) {
      bestChoice = behavior;
      maxScore = score;
   }
}


This seems easier than throwing everything in a tree map like you are doing. If there would only be a single instance of each behavior you could look into making them enums.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (16 views)
2014-07-24 01:59:36

Riven (16 views)
2014-07-23 21:16:32

Riven (14 views)
2014-07-23 21:07:15

Riven (16 views)
2014-07-23 20:56:16

ctomni231 (43 views)
2014-07-18 06:55:21

Zero Volt (40 views)
2014-07-17 23:47:54

danieldean (32 views)
2014-07-17 23:41:23

MustardPeter (36 views)
2014-07-16 23:30:00

Cero (51 views)
2014-07-16 00:42:17

Riven (50 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!