示例#1
0
 public LetOnFloor(Tank pParent) : base(pParent)
 {
 }
示例#2
0
        public void Update(bool pRefresh)
        {
            if (pRefresh)
            {
                #region Affectation des entrées
                Tank    CurrentTank       = Parent.Tanks[Parent.IndexTank];
                Vector2 normalisedTankPos = MapNormalisation(CurrentTank.Position);
                int     index             = 0;

                _inputs[index] = normalisedTankPos.X; index++;
                _inputs[index] = normalisedTankPos.Y; index++;
                _inputs[index] = (float)utils.MapValue(MathHelper.ToRadians(0), MathHelper.ToRadians(360), -1, 1, CurrentTank.Angle); index++;
                _inputs[index] = (float)utils.MapValue(MathHelper.ToRadians(0), MathHelper.ToRadians(360), -1, 1, CurrentTank.AngleCannon); index++;
                _inputs[index] = CurrentTank.Life / 100; index++;
                _inputs[index] = CurrentTank.Fuel / 100; index++;

                #region Eau la plus proche
                Vector2 min     = -Vector2.One;
                float   distMin = -1;
                for (int i = 0; i < Parent.Parent.WaterPosition.Count; i++)
                {
                    Rectangle water = Parent.Parent.WaterPosition[i];
                    if (water.Location.X < CurrentTank.Position.X)
                    {
                        float dist = (float)Math.Abs(utils.MathDist(CurrentTank.Position, water.Location.ToVector2()));
                        if (distMin > dist || distMin == -1)
                        {
                            distMin = dist;
                            min     = water.Location.ToVector2();
                        }
                    }
                    else
                    {
                        float dist = (float)Math.Abs(utils.MathDist(CurrentTank.Position.X, CurrentTank.Position.Y, water.Right, water.Top));
                        if (distMin > dist || distMin == -1)
                        {
                            distMin = dist;
                            min     = new Vector2(water.Right, water.Top);
                        }
                    }
                }
                #endregion

                Vector2 waterDist = MapNormalisation(min) - normalisedTankPos;
                _inputs[index] = waterDist.X; index++;
                _inputs[index] = waterDist.Y; index++;

                #region Drop le plus proche
                Drop    drop = (Drop)ShortestDistance(CurrentTank, Parent.Parent.LstActors.FindAll(d => d is Drop));
                Vector2 dropDist;
                if (drop == null)
                {
                    dropDist = Vector2.One;
                }
                else
                {
                    dropDist = MapNormalisation(drop.Position - CurrentTank.Position);
                }
                #endregion

                _inputs[index] = dropDist.X; index++;
                _inputs[index] = dropDist.Y; index++;

                #region Allié le plus proche
                Tank    friend = (Tank)ShortestDistance(CurrentTank, Parent.Tanks.FindAll(t => t.Parent == Parent && t != CurrentTank).Cast <IActor>().ToList());
                Vector2 friendDist;
                float   life = 0;
                if (friend == null)
                {
                    friendDist = Vector2.One;
                    life       = 1;
                }
                else
                {
                    friendDist = MapNormalisation(friend.Position - CurrentTank.Position);
                    life       = friend.Life / 100;
                }
                #endregion

                _inputs[index] = friendDist.X; index++;
                _inputs[index] = friendDist.Y; index++;
                _inputs[index] = life; index++;

                #region Ennemi le plus proche
                List <Tank> tanks = new List <Tank>();
                for (int i = 0; i < Parent.Parent.Teams.Count; i++)
                {
                    Team team = Parent.Parent.Teams[i];
                    tanks.AddRange(team.Tanks);
                }
                Tank    ennemy = (Tank)ShortestDistance(CurrentTank, tanks.FindAll(t => t.Parent != Parent).Cast <IActor>().ToList());
                Vector2 ennemyDist;
                if (ennemy == null)
                {
                    ennemyDist = Vector2.One;
                    life       = 1;
                }
                else
                {
                    ennemyDist = MapNormalisation(ennemy.Position - CurrentTank.Position);
                    life       = ennemy.Life / 100;
                }
                #endregion

                _inputs[index] = ennemyDist.X; index++;
                _inputs[index] = ennemyDist.Y; index++;
                _inputs[index] = life; index++;

                #region Actions
                for (int i = 0; i < Enum.GetValues(typeof(Action.eActions)).Length; i++)
                {
                    #region Sélection
                    if (CurrentTank.SelectedAction == (Action.eActions)i)
                    {
                        _inputs[index] = 1; index++;
                    }
                    else
                    {
                        _inputs[index] = 0; index++;
                    }
                    #endregion

                    #region Inventaire
                    if (Parent.Inventory.ContainsKey((Action.eActions)i))
                    {
                        int val = Parent.Inventory[(Action.eActions)i];
                        if (val == -1)
                        {
                            val = 10;
                        }
                        _inputs[index] = (float)utils.MapValue(0, 10, -1, 1, val, true); index++;
                    }
                    #endregion
                }
                #endregion

                #endregion

                float[] outputs = Genome.FeedForward(_inputs);

                #region Affectation des sorties
                bool[] commands = new bool[outputs.Length];
                for (int i = 0; i < outputs.Length; i++)
                {
                    if (outputs[i] >= 0f)
                    {
                        commands[i] = true;
                    }
                }
                OnPressedLeft = commands[0] && !IsDownLeft;
                IsDownLeft    = commands[0];

                OnPressedRight = commands[1] && !IsDownRight;
                IsDownRight    = commands[1];

                OnPressedUp = commands[2] && !IsDownUp;
                IsDownUp    = commands[2];

                OnPressedDown = commands[3] && !IsDownDown;
                IsDownDown    = commands[3];

                OnPressedSpace  = commands[4] && !IsDownSpace;
                OnReleasedSpace = !commands[4] && IsDownSpace;
                IsDownSpace     = commands[4];

                OnPressedN = commands[5] && !IsDownN;
                IsDownN    = commands[5];

                for (int i = 1; i < Enum.GetValues(typeof(Action.eActions)).Length; i++)
                {
                    if (commands[i + 5])
                    {
                        if (Parent.SelectAction((Action.eActions)i))
                        {
                            break;
                        }
                    }
                }
                #endregion
            }
            else
            {
                OnPressedLeft   = false;
                OnPressedRight  = false;
                OnPressedUp     = false;
                OnPressedDown   = false;
                OnPressedSpace  = false;
                OnPressedN      = false;
                IsDownLeft      = false;
                IsDownRight     = false;
                IsDownUp        = false;
                IsDownDown      = false;
                IsDownSpace     = false;
                IsDownN         = false;
                OnReleasedSpace = false;
            }
        }