예제 #1
0
        public GeneralNPC(CharacterNPC character, Vector3 position, IWalkable terrain, IControlable entity)
        {
            this.character  = character;
            this.terrain    = terrain;
            this.entity     = entity;
            this.position3D = position;
            this.position2D = terrain.Get2DMapPosition(this.position3D);
            this.taskStack  = new Stack <NpcTask>();
            this.taskMove   = new Traveling(new Astar());
            this.fightMove  = new Traveling(new Astar());

            //init start status
            this.currentStatus             = new Status();
            this.currentStatus.hp          = character.hp;
            this.currentStatus.mana        = character.mana;
            this.currentStatus.energy      = 100;
            this.currentStatus.position    = this.position2D;
            this.currentStatus.enemySeen   = 0;
            this.currentStatus.alive       = true;
            this.currentStatus.nearEnemies = new List <IActing>();

            this.targetCell = this.position2D;
            aiMap           = Map.GetInstance();
            this.npcMap     = aiMap.getRelatedMap(this.position2D, this.visualRange);
        }
        private void Recurse(ConflictState state, CharacterNPC character, CharacterNPC enemyChar, ActionType actinType, int step)
        {
            List <ConflictState> nextStates = GetSuccessors(state, character, enemyChar, actinType);
            DPItem item = new DPItem();

            item.Probability = state.probability;
            item.State       = state;
            item.Children    = nextStates;
            if (!space.ContainsKey(item.GetHashCode()))
            {
                this.space.Add(item.GetHashCode(), item);
            }

            step++;
            if (step < this.stateSpaceDeep)
            {
                ConflictState successor;
                for (int i = 0; i < nextStates.Count; i++)
                {
                    successor = nextStates[i];

                    if (this.stateSpace.Contains(successor))
                    {
                        //Logger.AddInfo("DP: nalezena duplicita. " + successor.ToString());
                        continue;
                    }
                    if (successor.enemyHP <= 0)
                    {
                        Logger.AddInfo("DP:Nalezen cilovy stav " + successor.ToString());
                        successor.cost = 0;
                        //step = this.stateSpaceDeep;
                        nextStates[i] = successor;
                        break;
                    }
                    else if (successor.myHP < character.hp / 4)
                    {
                        successor.cost = 100;
                        nextStates[i]  = successor;
                    }
                    this.stateSpace.Add(successor);
                    //try
                    //{
                    //    if (!space.ContainsKey(successor.GetHashCode()))
                    //    {
                    //        space.Add(successor.GetHashCode(), successor);
                    //    }
                    //    else
                    //    {
                    //        //Logger.AddWarning("DP: chyba pri pridavani do hash tabulky..." + successor.ToString());
                    //    }
                    //}
                    //catch (Exception)
                    //{
                    //    Logger.AddWarning("DP: chyba pri pridavani do hash tabulky..." + successor.ToString());
                    //}
                    Recurse(successor, character, enemyChar, actinType, step);
                }
                //this.stateSpace.AddRange(nextStates);
            }
        }
 private bool CheckStats(CharacterNPC character, ref ConflictState exploringState)
 {
     if (exploringState.myMana < 0)
     {
         //not enaugh mana
         return(false);
     }
     else if (exploringState.myMana > character.mana)
     {
         return(false);
     }
     if (exploringState.enemyMana < 0)
     {
         exploringState.enemyMana = 0;
     }
     if (exploringState.enemyHP < 0)
     {
         exploringState.enemyHP = 0;
     }
     if (exploringState.myHP < 0)
     {
         exploringState.myHP = 0;
     }
     else if (exploringState.myHP > character.hp)
     {
         //heal over max hp
         return(false);
     }
     //else if (exploringState.myHP - character.hp < 50
     //    && exploringState.myHP - character.hp > 0)
     //{
     //    exploringState.myHP = character.hp;
     //}
     return(true);
 }
예제 #4
0
        /// <summary>
        /// ctor, initialize ai structures
        /// </summary>
        /// <param name="character">character of npc</param>
        /// <param name="position">position on which npc stands</param>
        /// <param name="terrain">terrain, where npc moves</param>
        /// <param name="entity">pointer on graphical representation of npc, used for changing position, making effects, ...</param>
        public NPC(CharacterNPC character, Vector3 position, IWalkable terrain, IControlable entity)
        {
            this.position3D = position;
            System.Drawing.Point xy = terrain.Get2DMapPosition(position);
            this.x         = xy.X;
            this.y         = xy.Y;
            this.character = character;

            this.visualRange = this.character.visualRange;

            this.currentStatus             = new Status();
            this.currentStatus.hp          = character.hp;
            this.currentStatus.mana        = character.mana;
            this.currentStatus.energy      = 100;
            this.currentStatus.position    = this.GetPosition2D();
            this.currentStatus.enemySeen   = 0;
            this.currentStatus.alive       = true;
            this.currentStatus.nearEnemies = new List <IActing>();

            this.entity    = entity;
            this.terrain   = terrain;
            this.taskStack = new Stack <NpcTask>();

            this.taskMove  = new Traveling(new Astar());
            this.fightMove = new Traveling(new Astar());

            this.targetCell = new System.Drawing.Point(x, y);
            this.aiMap      = Map.GetInstance();

            pathFinding = new Astar();

            this.entity.ChangePosition(position);
        }
예제 #5
0
        private void Init()
        {
            Bitmap bmp = new Bitmap(this.mapName);

            grid = new Grid(bmp, this.gridPanel);
            Logger.AddInfo("Map loaded: " + bmp.Width.ToString() + "; " + bmp.Height.ToString());
            ai = new AICore(grid);
            string[] npcList = File.ReadAllLines(Directory.GetCurrentDirectory() + "\\Settings\\level1npc.ini");
            characters = new WiccanRede.AI.CharacterNPC[npcList.Length];
            Entity[] entities = new Entity[npcList.Length];

            for (int i = 0; i < npcList.Length; i++)
            {
                try
                {
                    characters[i] = new WiccanRede.AI.CharacterNPC("Settings\\" + npcList[i] + ".xml");
                    //ai.AddPlayer(characters[i], new Microsoft.DirectX.Vector3(i, i, i), new Entity(), "BasicFSM");
                    entities[i] = new Entity(characters[i], ai, "BasicFSM");
                }
                catch (Exception ex)
                {
                    Logging.Logger.AddWarning("Chyba pri nacitani NPC: " + npcList[i] + " - " + ex.ToString());
                }
            }
        }
예제 #6
0
        /// <summary>
        /// update for story line
        /// </summary>
        /// <param name="gameState">name of new game state</param>
        public void Update(string gameState)
        {
            control.Update(npcs, step, gameState);

            CharacterNPC playerChar = this.player.GetCharacter();

            playerChar.level++;
            this.player.UpdateCharacter(playerChar);
        }
        /// <summary>
        /// evaluate given state-prob pair
        /// </summary>
        /// <param name="current">current confict state, without any applied actions</param>
        /// <param name="pairs">pairs to evaluate</param>
        /// <param name="character">npc character</param>
        /// <returns>calculated cost of given pairs</returns>
        private int ComputeCost(ConflictState current, StateProbPairs pairs, CharacterNPC character)
        {
            int           cost = 0;
            ConflictState state;

            for (int i = 0; i < pairs.states.Count; i++)
            {
                state = pairs.states[i];
                if (state.myHP > character.hp)
                {
                    state.myHP = character.hp;
                }
                if (state.myMana > character.mana)
                {
                    state.myMana = character.mana;
                }

                int myHpRating = 0, enemyHpRating = 0, boostRating = 0, manaRating = 0;

                if (state.myHP > current.myHP)
                {
                    myHpRating = current.myHP;
                }
                else if (state.myHP < current.myHP)
                {
                    myHpRating = current.myHP - state.myHP; //self harm
                }

                if (state.myMana - current.myMana >= 80)
                {
                    manaRating = current.myMana;
                }
                else if (state.myMana < current.myMana)
                {
                    manaRating = state.myMana - current.myMana;
                }

                if (state.enemyHP < current.enemyHP)
                {
                    enemyHpRating = state.enemyHP;
                }
                boostRating = 0;// character.mana - state.myMana;

                int energyRating = (current.myEnergy - state.myEnergy) * 10;
                int timeRating   = pairs.action.time / 10;

                int sum = myHpRating + enemyHpRating + boostRating + energyRating + manaRating + timeRating;
                sum *= (pairs.probabilities[i]);
                sum /= 100;

                cost += sum;
            }
            cost /= pairs.states.Count;
            return(cost);
        }
        public void CreateStateSpace(ConflictState currentState, CharacterNPC character, CharacterNPC enemyChar, ActionType actinType)
        {
            Logging.Logger.StartTimer("Vytvareni statespace");
            int step = 0;

            Recurse(currentState, character, enemyChar, actinType, step);
            Logging.Logger.StopTimer("Vytvareni statespace");
            Logger.AddInfo("Velikost State space: " + this.stateSpace.Count.ToString());
            Logger.AddInfo("Velikost space: " + this.space.Count.ToString());
            this.bestActions.Capacity = this.stateSpace.Count;
        }
        private bool CheckStats(CharacterNPC character, CharacterNPC enemyChar, ref ConflictState exploringState)
        {
            if (exploringState.enemyHP > enemyChar.hp)
            {
                return(false);
            }
            else if (exploringState.enemyHP < 0)
            {
                exploringState.enemyHP = 0;
            }

            return(CheckStats(character, ref exploringState));
        }
예제 #10
0
 /// <summary>
 /// private ctor - singleton
 /// </summary>
 public GamePlayer(IControlable entity, CharacterNPC character)
 {
     //character = new CharacterNPC("Settings//NPC//Player.xml");
     this.character               = character;
     this.entity                  = entity;
     currentStatus                = new Status();
     this.currentStatus.hp        = character.hp;
     this.currentStatus.mana      = character.mana;
     this.currentStatus.energy    = 100;
     this.currentStatus.position  = AI.Map.GetInstance().GetTerrain().GetPlayerPosition();
     this.currentStatus.enemySeen = 0;
     this.currentStatus.alive     = true;
     instance = this;
 }
예제 #11
0
        static void Main(string[] args)
        {
            Console.WriteLine("Testovaci konzole pro knihovnu AI.");
            Logger.InitLogger();
            Logger.bWriteToOutput = true;
            dynamic   = new DynamicProgramming();
            mikelChar = new CharacterNPC("Settings/Mikel.xml");
            TestDP();

            Console.WriteLine("Stisknete libovolnou klavesu pro ukonceni... ");
            string end = Console.ReadLine();

            Logger.Save();
        }
예제 #12
0
        /// <summary>
        /// register new ai controled player
        /// </summary>
        /// <param name="charakter">character of added npc</param>
        /// <param name="position">position where npc starts</param>
        /// <param name="entity">pointer to the graphical representation</param>
        /// <param name="fsmName">Name of finite state machine</param>
        /// <see cref="FSM"/>
        public void AddPlayer(CharacterNPC charakter, Vector3 position, IControlable entity, string controlMechanism, string actionDefinition)
        {
            NPC npc = new NPC(charakter, position, this.terrain, entity);

            npc.AttachActions(actionDefinition);

            if (controlMechanism.EndsWith(".lua"))
            {
                npc.AttachScript(controlMechanism);
                npcs.Add(npc);
            }
            else
            {
                AddNpcWithFsm(charakter, entity, controlMechanism, npc);
            }
        }
        /// <summary>
        /// from generated state-prob pairs choose the best one and returns new Confict state
        /// </summary>
        /// <param name="myself">npc, which is choosing from actions</param>
        /// <param name="enemy">enemy npc on which is the target</param>
        /// <param name="priors">priors from npc character, useless for now</param>
        /// <param name="actionType">type of action</param>
        /// <returns>new confict state</returns>
        public ConflictState GetNextAction(IActing myself, IActing enemy, Priorities priors, out Action selectedAction)
        {
            ConflictState currentState = new ConflictState(myself.GetStatus(), enemy.GetStatus());
            Priorities    priorities   = priors;
            CharacterNPC  myChar       = myself.GetCharacter();

            //if (this.stateSpace.Count == 0)
            //{
            //    CreateStateSpace(currentState, myChar);
            //}

            List <StateProbPairs> expanders = Expand(currentState, myChar);

            StateProbPairs result = new StateProbPairs();

            int lowestCost = int.MaxValue;
            int actionCost = int.MaxValue;

            foreach (StateProbPairs pairs in expanders)
            {
                //if (this.stateSpace.Contains(pairs))
                //{
                //    Logging.Logger.AddInfo(pairs.ToString() + " je obsazeno");
                //}
                actionCost = ComputeCost(currentState, pairs, myChar);

                if (actionCost < lowestCost && actionCost >= 0)
                {
                    result     = pairs;
                    lowestCost = actionCost;
                }
            }
            if (result.states == null)
            {
                result.states.Add(currentState);
                Action empty = new Action();
                empty.name    = "empty";
                empty.time    = 5000;
                result.action = empty;
                result.probabilities.Add(100);
            }

            int index = 0;

            if (result.probabilities.Count > 1)
            {
                int randChoose = rand.Next(100);
                if (randChoose < result.probabilities[0])
                {
                    index = 0;
                }
                else if (randChoose < result.probabilities[0] + result.probabilities[1])
                {
                    index = 1;
                }
                else
                {
                    if (result.states.Count > 2)
                    {
                        index = 2;
                    }
                }
            }

            if (index >= result.states.Count)
            {
                index = 0;
            }

            Logging.Logger.AddInfo(myChar.name + ": " + result.action.ToString() + " proti " + enemy.GetCharacter().name + ", cost=" + lowestCost + ", efekt: " + index);
            myself.SetCoolDown(result.action.time);

            selectedAction  = result.action;
            this.lastAction = selectedAction;
            //return result.states[index];
            return(result.states[0]);
        }
        /// <summary>
        /// apply actions on conflict state and by this generate followers of current confict state
        /// </summary>
        /// <param name="state"> current conflict state </param>
        /// <param name="character">character of npc, used for checking stats</param>
        /// <param name="actionType">action type, which says, what actions are available</param>
        /// <returns>List of state-probability pairs</returns>
        private List <StateProbPairs> Expand(ConflictState state, CharacterNPC character)
        {
            List <StateProbPairs> expanders = new List <StateProbPairs>();

            //List<Action> actions = null;
            //switch (actionType)
            //{
            //    case ActionType.Attack:
            //        actions = this.attackActions;
            //        break;
            //    case ActionType.Defense:
            //        actions = this.defenseActions;
            //        break;
            //    default:
            //        Logging.Logger.AddWarning("Spatny typ akce");
            //        return expanders;
            //    //break;
            //}

            foreach (Action action in this.actions)
            {
                if (action.name == lastAction.name && action.name.StartsWith("Heal"))
                {
                    break;
                }
                //TODO - spravit cooldownama

                StateProbPairs pairs = new StateProbPairs();
                pairs.states        = new List <ConflictState>();
                pairs.probabilities = new List <int>();

                ConflictState succesState;        // = new ConflictState();
                ConflictState noEffectState;      // = new ConflictState();
                ConflictState failState;          // = new ConflictState();

                succesState     = state + action; //spell casted succesfull
                noEffectState   = state;          //casting has no effect,
                failState       = state;          // -action;                 //casting fail and harm caster
                failState.myHP -= action.enemyHpTaken;
                failState.myHP -= action.hpGot;


                int prob     = action.probability;
                int noneProb = 100 - prob - failProb;
                int fail     = failProb;

                //check and add to expanders
                if (CheckStats(character, ref succesState))
                {
                    pairs.states.Add(succesState);
                    pairs.probabilities.Add(prob);

                    if (action.probability != 100)
                    {
                        if (CheckStats(character, ref failState))
                        {
                            pairs.states.Add(failState);
                            pairs.probabilities.Add(fail);
                        }
                        //pairs.states.Add(noEffectState);
                        //pairs.probabilities.Add(noneProb);
                    }
                }


                pairs.action = action;
                if (pairs.states.Count > 0)
                {
                    expanders.Add(pairs);
                }
            }

            return(expanders);
        }
예제 #15
0
        /// <summary>
        /// register new ai controled player with script
        /// </summary>
        /// <param name="charakter">character of NPC</param>
        /// <param name="position">starting position</param>
        /// <param name="entity">pointer to the graphical representation</param>
        /// <param name="scriptPath">path to the script</param>
        public void AddPlayer(CharacterNPC charakter, Vector3 position, IControlable entity, string scriptPath)
        {
            NPC npc = new NPC(charakter, position, this.terrain, entity);

            npc.AttachScript(scriptPath);
        }
예제 #16
0
        /// <summary>
        /// Adds the NPC with FSM.
        /// </summary>
        /// <param name="charakter">The charakter.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="fsmName">Name of the FSM.</param>
        /// <param name="npc">The NPC.</param>
        private void AddNpcWithFsm(CharacterNPC charakter, IControlable entity, string fsmName, NPC npc)
        {
            FSM fsm = null;

            try
            {
                if (this.fsms != null && fsms.Count > 0)
                {
                    Type type = fsms[0];
                    foreach (Type t in fsms)
                    {
                        if (t.Name == fsmName)
                        {
                            type = t;
                            break;
                        }
                    }
                    //ConstructorInfo ci = type.GetConstructor(new Type[] { type });
                    ConstructorInfo ci = type.GetConstructors()[0];
                    List <Object>   constructorPars = new List <object>();
                    foreach (ParameterInfo pi in ci.GetParameters())
                    {
                        if (pi.ParameterType.Name == "NPC")
                        {
                            constructorPars.Add(npc);
                        }
                        else if (pi.ParameterType.Name == "CharacterNPC")
                        {
                            constructorPars.Add(charakter);
                        }
                        else if (pi.ParameterType.Name == "IControlable")
                        {
                            constructorPars.Add(entity);
                        }
                        else if (pi.ParameterType.Name == "Map")
                        {
                            constructorPars.Add(this.map);
                        }
                    }
                    fsm = (FSM)Activator.CreateInstance(type, constructorPars.ToArray());
                    //FSM fsm = (FSM)ci.Invoke(constructorPars.ToArray());
                }
            }
            catch (Exception ex)
            {
                Logging.Logger.AddError("Chyba pri nacitani FSM: " + ex.ToString());
            }

            if (fsm != null)
            {
                //Logging.Logger.AddInfo("pridavam npc na pozici: " + position.ToString());
                npc.AttachFSM(fsm);
                //lock (this.npcs)
                {
                    npcs.Add(npc);
                }
            }
            else
            {
                Logging.Logger.AddWarning("Nemohu pridat NPC " + charakter.name + ". Nenalezen zadny fsm");
            }
        }
예제 #17
0
 /// <summary>
 /// register human player
 /// </summary>
 /// <param name="entity">object for graphical representation</param>
 /// <param name="character">player's character</param>
 public void AddPlayer(IControlable entity, CharacterNPC character)
 {
     this.player = new GamePlayer(entity, character);
 }
예제 #18
0
 public void UpdateCharacter(CharacterNPC character)
 {
     this.character = character;
 }
예제 #19
0
 public Entity(CharacterNPC character, AICore ai, string fsmName)
 {
     ai.AddPlayer(character, new Vector3(), this, fsmName, "");
 }
        private List <ConflictState> GetSuccessors(ConflictState state, CharacterNPC character, CharacterNPC enemyChar, ActionType actionType)
        {
            List <ConflictState> successors = new List <ConflictState>();
            List <Action>        actions    = null;

            switch (actionType)
            {
            case ActionType.Attack:
                actions = this.attackActions;
                break;

            case ActionType.Defense:
                actions = this.defenseActions;
                break;

            default:
                Logging.Logger.AddWarning("DP: Spatny typ akce");
                return(successors);
                //break;
            }

            ConflictState succesState = new ConflictState();
            //ConflictState noEffectState = new ConflictState();
            ConflictState failState = new ConflictState();

            ConflictState enemySuccesState = new ConflictState();
            ConflictState enemyFailState   = new ConflictState();

            foreach (Action action in actions)
            {
                if (action.probability == 100)
                {
                    succesState = state + action;
                    successors.Add(succesState);
                }
                else
                {
                    //spell is casted by "this" npc
                    succesState             = state + action;   //spell casted succesfull
                    succesState.probability = action.probability;
                    //noEffectState = state;                      //casting has no effect,
                    failState             = state;               //casting fail and harm caster
                    failState.myHP       -= action.enemyHpTaken;
                    failState.myHP       -= action.hpGot;
                    failState.probability = failProb;

                    //spell is casted by this NPCs enemy
                    enemySuccesState             = state - action;
                    enemySuccesState.probability = action.probability;
                    enemyFailState             = state;
                    enemyFailState.enemyHP    -= action.enemyHpTaken;
                    enemyFailState.enemyHP    -= action.hpGot;
                    enemyFailState.probability = failProb;

                    //check if states are valid
                    if (CheckStats(character, enemyChar, ref enemyFailState))
                    {
                        successors.Add(enemyFailState);
                    }
                    if (CheckStats(character, enemyChar, ref enemySuccesState))
                    {
                        successors.Add(enemySuccesState);
                    }
                    if (CheckStats(character, enemyChar, ref succesState))
                    {
                        successors.Add(succesState);
                    }
                    if (CheckStats(character, enemyChar, ref failState))
                    {
                        successors.Add(failState);
                    }
                }
            }

            return(successors);
        }