/// <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);
        }
        /// <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);
        }