示例#1
0
        private bool PartEat(LookEventArgs Mlook, SearchWayEventArgs Way)
        {
            if (Hunger.Hung > Hunger.MaxHung * 0.8)
            {
                return(false);
            }
            if (Mlook.Envirs == null)
            {
                Mlook.MustLkEnv = true; Mlook.MustLkAnm = false;
                Mlook.radius    = RadSee.Item2;
                Mlook.Queier    = QuerEat;
                QActLook(Mlook);
            }
            float min; uint index;

            for (int iter = 0; iter < 5; iter++)
            {
                index = 0;
                min   = float.MaxValue;                          //Раскидываем по приоритету.
                for (ushort i = 0; i < Mlook.Envirs.Lenght; i++) //проверяем все окружающие Envir
                {
                    if (Mlook.Esort[i].Item1 < min && Mlook.Esort[i].Item2 == false)
                    {
                        index = i;
                        min   = Mlook.Esort[i].Item1;
                    }
                }
                if (min != float.MaxValue)
                {
                    Mlook.Esort[index].Item2 = true;
                    if (Pos.PosNear(Location, Mlook.Envirs[index].Location))
                    {
                        ActEat(Mlook.Envirs[index].Location);
                        DoAvAct(Rstate.GoEat, new List <Pos>());
                        return(true);
                    }
                    Way.TPos     = (Mlook.Envirs[index]).Location;
                    Way.StayNear = true;
                    QActSearchWay(Way);//Console.Write("1");
                    if (Way.CanGo == true)
                    {
                        DoAvAct(Rstate.GoEat, Way.MGoPos, true);
                        if (Targ.Count != 0)
                        {
                            ActGo(new GoEventArgs()
                            {
                                CurPos  = Location,
                                TargPos = Targ[Targ.Count - 1],   //не должно быть 0 элементов
                            });
                        }
                        return(true);//мы уже всё решили и выходим
                    }
                }
                else
                {
                    return(false);// всё просмотрели
                }
            }
            return(false);
        }
示例#2
0
        ///<param name="IsAnimPr">Нужно ли искать путь вместе с животными</param>
        private void ThinkNew(bool IsAnimPr = false)
        {
            LookEventArgs Mlook = new LookEventArgs();

            if (PartEnem(Mlook))
            {
                return;
            }
            SearchWayEventArgs Way = new SearchWayEventArgs()
            {
                IsAnimPr = IsAnimPr
            };

            if (PartEat(Mlook, Way))
            {
                return;
            }
            if (PartIdle())
            {
                return;
            }
            if (State == AnimState.Zero)
            {
                DoAvAct(Rstate.Disarray, new List <Pos>());
                ActRest(2);
            }
        }
示例#3
0
        private bool ThinkMed()
        {
            LookEventArgs      Mlook = new LookEventArgs();
            SearchWayEventArgs Way   = new SearchWayEventArgs();

            if (PartEat(Mlook, Way))
            {
                return(false);
            }

            return(true);
        }
示例#4
0
        private bool PartAttack(LookEventArgs Mlook, SearchWayEventArgs Way)
        {
            Mlook.MustLkAnm = true;
            Mlook.radius    = RadSee.Item2;
            Mlook.Queier    = QuerAttack;
            QActLook(Mlook);
            float min; uint index;

            for (int iter = 0; iter < 5; iter++)
            {
                index = 0;
                min   = float.MaxValue;                                              //Раскидываем по приоритету.
                for (ushort i = 0; i < Mlook.Animals.Lenght; i++)                    //проверяем все окружающие Envir
                {
                    if (Mlook.Asort[i].Item1 < min && Mlook.Asort[i].Item2 == false) //добавлять доп.условие что это еда
                    {
                        index = i;
                        min   = Mlook.Asort[i].Item1;
                    }
                }
                if (min != float.MaxValue)
                {
                    Mlook.Asort[index].Item2 = true;
                    if (Pos.PosNear(Location, Mlook.Animals[index].Location))
                    {
                        ActAttack(Mlook.Animals[index]);
                        DoAvAct(WolfState.GoAttack, new List <Pos>());
                        return(true);
                    }
                    Way.TPos     = (Mlook.Animals[index]).Location;
                    Way.StayNear = true;
                    QActSearchWay(Way);
                    if (Way.CanGo == true)
                    {
                        DoAvAct(WolfState.GoAttack, new List <Pos>());
                        ActGo(new GoEventArgs()
                        {
                            CurPos  = Location,
                            TargPos = Way.MGoPos.Last(), //не должно быть 0 элементов
                        });
                        return(true);                    //мы уже всё решили и выходим
                    }
                }
                else
                {
                    return(false);// всё просмотрели
                }
            }
            return(false);
        }
示例#5
0
        private bool ThinkMed()  //возвращает true,если надо дальше двигаться к цели
        {
            LookEventArgs Mlook = new LookEventArgs();

            if (PartEnem(Mlook))
            {
                return(false);
            }

            if (AvState == Rstate.GoEat)
            {
                Cell c = QActGetCell(Targ[0]);
                if (c.LEnvir != null && QuerEat(c.LEnvir, 1).Item2)
                {
                    Console.WriteLine("Иди дальше");
                    return(true);// можешь идти дальше
                }
                else
                {
                    DoAvAct(Rstate.Zero, new List <Pos>());
                    return(false);
                }
            }
            else if (AvState == Rstate.GoGulyat)
            {
                SearchWayEventArgs Way = new SearchWayEventArgs()
                {
                    IsAnimPr = false
                };
                if (PartEat(Mlook, Way))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#6
0
        public void SearchWayAnimal(object sender, SearchWayEventArgs e)
        {
            Pos    minP = new Pos();
            uint   min; uint minr;
            Animal send   = (sender as Animal);
            ushort radsee = send.RadSee.Item2; if (radsee > 40)
            {
                radsee = 40;
            }
            int massize = (radsee * 2 + 1);

            byte[,] Mcan;
            uint[,] Mdt;                 //если прибавлять 14, хватит и ushort
            e.MGoPos = new List <Pos>(); //обновляем
            //прибавлять к координатам массива, чтобы получить глобальные
            Pos plPos = new Pos(send.Location.X - radsee, send.Location.Y - radsee);
            Pos targ  = new Pos(e.TPos.X - plPos.X, e.TPos.Y - plPos.Y);

            if (targ.X >= massize || targ.Y >= massize || targ.X < 0 || targ.Y < 0)
            {   //Если цель за границами видимости, выходим.
                e.CanGo = false;
                return;
            }
            if (targ.X == radsee && targ.Y == radsee)
            {
                e.CanGo = true;
                return;
            }
            if (!e.isCreate)    //если массивы не были созданы, создаём их
            {
                e.isCreate = true;
                Mcan       = new byte[massize, massize]; //0- нельзя пройти, 1- можно, 2- проверенная клетка 3- путь
                Mdt        = new uint[massize, massize]; //== может работать плохо с float, поэтому uint

                for (int i = 0; i < Mcan.GetLength(0); i++)
                {
                    for (int j = 0; j < Mcan.GetLength(1); j++)
                    {
                        if (i + plPos.X >= 0 && i + plPos.X < MapX && j + plPos.Y >= 0 && j + plPos.Y < MapY && // что вне размера карты, будет непроходимым(по хорошему надо массив обрезать)
                            send.GetCanPlace(MCell[i + plPos.X, j + plPos.Y].ID, MCell[i + plPos.X, j + plPos.Y].LEnvir)) //чтобы пытался обходить остальных, нужно добавить && Mcell[,].animal==null
                        {
                            if (e.IsAnimPr && MCell[i + plPos.X, j + plPos.Y].LAnimal != null)                            //если надо проверять животных, проверяем
                            {
                                Mcan[i, j] = 0;
                            }
                            else
                            {
                                Mcan[i, j] = 1;
                            }
                        }
                        else
                        {
                            Mcan[i, j] = 0;
                        }
                        Mdt[i, j] = uint.MaxValue;
                    }
                }
                Mcan[radsee, radsee] = 1;// первая клетка не проверена
                Mdt[radsee, radsee]  = 0;
                e.Mcan = Mcan;
                e.Mdt  = Mdt;
            }
            else
            {
                Mcan = e.Mcan;
                Mdt  = e.Mdt;
            }
            int cnt = 0;

            if (Mcan[targ.X, targ.Y] == 0)
            {
                Mcan[targ.X, targ.Y] = 1;// клетка с целью будет считаться проходимой(могут быть проблемы)
            }
            void iM(int x, int y, uint mi, uint plus)
            {
                if (Mcan[x, y] == 1 && Mdt[x, y] > mi + plus)
                {
                    Mdt[x, y] = mi + plus;
                }
            }

            while (true)
            {
                if (Mcan[targ.X, targ.Y] == 2)
                {
                    break;
                }
                minr = uint.MaxValue;
                min  = uint.MaxValue;
                for (int i = 0; i < massize; i++)// ищем минимальный непроверенный элемент
                {
                    for (int j = 0; j < massize; j++)
                    {
                        if (Mcan[i, j] == 1 && Mdt[i, j] < uint.MaxValue && Matem.SQDist(targ, new Pos(i, j)) < minr)
                        {
                            minr   = Matem.SQDist(targ, new Pos(i, j));
                            min    = Mdt[i, j];
                            minP.X = i;
                            minP.Y = j;
                        }
                    }
                }
                if (minr < uint.MaxValue)  //если нашли соответствующий элемент, нужно обновить все соседние клетки
                {
                    cnt++;
                    if (minP.X + 1 < massize)
                    {
                        iM(minP.X + 1, minP.Y, min, 1000);
                    }
                    if (minP.X + 1 < massize && minP.Y + 1 < massize)
                    {
                        iM(minP.X + 1, minP.Y + 1, min, 1414);
                    }
                    if (minP.Y + 1 < massize)
                    {
                        iM(minP.X, minP.Y + 1, min, 1000);
                    }
                    if (minP.X - 1 >= 0 && minP.Y + 1 < massize)
                    {
                        iM(minP.X - 1, minP.Y + 1, min, 1414);
                    }
                    if (minP.X - 1 >= 0)
                    {
                        iM(minP.X - 1, minP.Y, min, 1000);
                    }
                    if (minP.X - 1 >= 0 && minP.Y - 1 >= 0)
                    {
                        iM(minP.X - 1, minP.Y - 1, min, 1414);
                    }
                    if (minP.Y - 1 >= 0)
                    {
                        iM(minP.X, minP.Y - 1, min, 1000);
                    }
                    if (minP.X + 1 < massize && minP.Y - 1 >= 0)
                    {
                        iM(minP.X + 1, minP.Y - 1, min, 1414);
                    }
                    Mcan[minP.X, minP.Y] = 2;
                }
                else
                {
                    break;
                }
            }

            //старый алгоритм(Дийкстра)
            #region

            //while (true)
            //{
            //    if (Mcan[targ.X, targ.Y] == 2)
            //    {
            //        break;
            //    }
            //    min = uint.MaxValue;
            //    for (int i = 0; i < massize; i++)// ищем минимальный непроверенный элемент
            //    {
            //        for (int j = 0; j < massize; j++)
            //        {
            //            if (Mcan[i, j] == 1 && Mdt[i, j] < min)//для жадного алгоритма изменить эту строку
            //            {
            //                min = Mdt[i, j];
            //                minP.X = i;
            //                minP.Y = j;

            //            }
            //        }
            //    }
            //    if (min < uint.MaxValue)  //если нашли соответствующий элемент, нужно обновить все соседние клетки
            //    {
            //        cnt++;
            //        if (minP.X + 1 < massize) iM(minP.X + 1, minP.Y, min, 1000);
            //        if (minP.X + 1 < massize && minP.Y + 1 < massize) iM(minP.X + 1, minP.Y + 1, min, 1414);
            //        if (minP.Y + 1 < massize) iM(minP.X, minP.Y + 1, min, 1000);
            //        if (minP.X - 1 >= 0 && minP.Y + 1 < massize) iM(minP.X - 1, minP.Y + 1, min, 1414);
            //        if (minP.X - 1 >= 0) iM(minP.X - 1, minP.Y, min, 1000);
            //        if (minP.X - 1 >= 0 && minP.Y - 1 >= 0) iM(minP.X - 1, minP.Y - 1, min, 1414);
            //        if (minP.Y - 1 >= 0) iM(minP.X, minP.Y - 1, min, 1000);
            //        if (minP.X + 1 < massize && minP.Y - 1 >= 0) iM(minP.X + 1, minP.Y - 1, min, 1414);
            //        Mcan[minP.X, minP.Y] = 2;
            //    }
            //    else
            //    {
            //        break;
            //    }
            //}
            #endregion
            System.Console.WriteLine(cnt);
            if (Mcan[targ.X, targ.Y] != 2)  //если целевая клетка не проверена, значит до неё нельзя добраться
            {
                e.CanGo = false;
                return;
            }
            minP.X = targ.X;              //повторное использование переменных, а что?
            minP.Y = targ.Y;              //позиция
            min    = Mdt[minP.X, minP.Y]; //сколько идти до этой клетки
                                          // Mgo[minP.X, minP.Y] = 1;        // счётчик клеток(чтобы вернуться)
            byte lastrot = 0;             // предыдущее неправление(по умолчанию никуда,т.к. они начинаются с 1
                                          // e.GoPos = minP;
            bool iG1(int x, int y, uint minus, byte dirc)
            {
                if (Mdt[x, y] == min - minus)
                {
                    e.MGoPos.Add(new Pos(minP.X + plPos.X, minP.Y + plPos.Y));
                    lastrot = 0;
                    minP.X  = x; minP.Y = y;
                    //e.MGoPos.Add(new Pos(minP.X + plPos.X, minP.Y + plPos.Y));
                    min -= minus;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            if (e.StayNear) //нужно остановиться у края цели, двигаемся один раз
            {
                if (minP.X + 1 < massize && iG1(minP.X + 1, minP.Y, 1000, 1))
                {
                    ;
                }
                else if (minP.X + 1 < massize && minP.Y + 1 < massize && iG1(minP.X + 1, minP.Y + 1, 1414, 2))
                {
                    ;
                }
                else if (minP.Y + 1 < massize && iG1(minP.X, minP.Y + 1, 1000, 3))
                {
                    ;
                }
                else if (minP.X - 1 >= 0 && minP.Y + 1 < massize && iG1(minP.X - 1, minP.Y + 1, 1414, 4))
                {
                    ;
                }
                else if (minP.X - 1 >= 0 && iG1(minP.X - 1, minP.Y, 1000, 5))
                {
                    ;
                }
                else if (minP.X - 1 >= 0 && minP.Y - 1 >= 0 && iG1(minP.X - 1, minP.Y - 1, 1414, 6))
                {
                    ;
                }
                else if (minP.Y - 1 >= 0 && iG1(minP.X, minP.Y - 1, 1000, 7))
                {
                    ;
                }
                else if (minP.X + 1 < massize && minP.Y - 1 >= 0 && iG1(minP.X + 1, minP.Y - 1, 1414, 8))
                {
                    ;
                }
            }

            bool iG(int x, int y, uint minus, byte dirk)
            {
                if (Mdt[x, y] == min - minus)
                {
                    if (lastrot != dirk)    //Если предыдущее направление не совпадает с новым, ставится точка на старой клетке
                    {
                        // e.GoPos = minP;
                        lastrot = dirk;
                        e.MGoPos.Add(new Pos(minP.X + plPos.X, minP.Y + plPos.Y));
                    }
                    minP.X = x; minP.Y = y;
                    min   -= minus;
                    return(true);
                }
                else
                {
                    return(false);
                }
            };

            while (!(minP.X == radsee && minP.Y == radsee))
            {
                if (minP.X + 1 < massize && iG(minP.X + 1, minP.Y, 1000, 1))
                {
                    ;
                }
                else if (minP.X + 1 < massize && minP.Y + 1 < massize && iG(minP.X + 1, minP.Y + 1, 1414, 2))
                {
                    ;
                }
                else if (minP.Y + 1 < massize && iG(minP.X, minP.Y + 1, 1000, 3))
                {
                    ;
                }
                else if (minP.X - 1 >= 0 && minP.Y + 1 < massize && iG(minP.X - 1, minP.Y + 1, 1414, 4))
                {
                    ;
                }
                else if (minP.X - 1 >= 0 && iG(minP.X - 1, minP.Y, 1000, 5))
                {
                    ;
                }
                else if (minP.X - 1 >= 0 && minP.Y - 1 >= 0 && iG(minP.X - 1, minP.Y - 1, 1414, 6))
                {
                    ;
                }
                else if (minP.Y - 1 >= 0 && iG(minP.X, minP.Y - 1, 1000, 7))
                {
                    ;
                }
                else if (minP.X + 1 < massize && minP.Y - 1 >= 0 && iG(minP.X + 1, minP.Y - 1, 1414, 8))
                {
                    ;
                }
            }
            e.CanGo = true;
            foreach (Pos n in e.MGoPos)
            {
                System.Console.WriteLine(n);
            }
            // e.GoPos.X += plPos.X; e.GoPos.Y += plPos.Y;//перевод ходьбы в мировые координаты.
            //System.Console.WriteLine("Можно!");
        }
示例#7
0
        private bool PartEat(LookEventArgs Mlook, SearchWayEventArgs Way)
        {
            if (Hunger.Hung > Hunger.MaxHung * 0.8)
            {
                return(false);
            }
            Mlook.MustLkAnm = true;
            Mlook.radius    = RadSee.Item2;
            Mlook.Queier    = QuerEat;
            QActLook(Mlook);
            float min; uint index;

            for (int iter = 0; iter < 3; iter++)
            {
                index = 0;
                min   = float.MaxValue;                                              //Раскидываем по приоритету.
                for (ushort i = 0; i < Mlook.Animals.Lenght; i++)                    //проверяем нужное окружение
                {
                    if (Mlook.Asort[i].Item1 < min && Mlook.Asort[i].Item2 == false) //добавлять доп.условие что это еда
                    {
                        index = i;
                        min   = Mlook.Asort[i].Item1;
                    }
                }
                if (min != float.MaxValue)
                {
                    Mlook.Asort[index].Item2 = true;
                    if (Pos.PosNear(Location, Mlook.Animals[index].Location))
                    {
                        if ((Mlook.Animals[index] as IEatable).FoodRec > 0)
                        {
                            ActEat(Mlook.Animals[index].Location);
                            DoAvAct(WolfState.GoEat, new List <Pos>());
                            return(true);
                        }
                    }
                    Way.TPos     = (Mlook.Animals[index]).Location;
                    Way.StayNear = true;
                    QActSearchWay(Way);

                    if (Way.CanGo == true)
                    {
                        DoAvAct(WolfState.GoEat, Way.MGoPos, true);
                        if (Targ.Count != 0)
                        {
                            ActGo(new GoEventArgs()
                            {
                                CurPos  = Location,
                                TargPos = Targ[Targ.Count - 1],   //не должно быть 0 элементов
                            });
                        }
                        return(true);//мы уже всё решили и выходим
                    }
                }
                else
                {
                    return(false);
                }
            }
            return(false);
        }