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); }
///<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); } }
private bool ThinkMed() { LookEventArgs Mlook = new LookEventArgs(); SearchWayEventArgs Way = new SearchWayEventArgs(); if (PartEat(Mlook, Way)) { return(false); } return(true); }
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); }
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); }
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("Можно!"); }
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); }