/// <summary> /// расчет пути к клетке с заданным типом, на удалении не более чем /// </summary> /// <param name="stm">тип поиска</param> /// <param name="roadlen">длинна допустимого маршрута</param> /// <param name="gunTime">заряд оружия противника</param> /// <returns>Тип и координаты хода</returns> internal IStep wayOfEvil(TypesOfField stm,int roadlen,int gunTime) { int distance = 1; //int goForFar = 0; bool found = false; int interationNum = 0; IStep s = StepsAndCoord.StepsBuilder ( EpsilonBot.api.getCoordOfMe (),Steps.STEP ); Queue<Ways> q1 = new Queue<Ways> (); // основная очередь Queue<Ways> q2 = new Queue<Ways> (); // Вспомогательная Ways temp = new Ways ( EpsilonBot.api.getCoordOfMe (),0,0,0,mind.He.gun ().getTimerVal,EpsilonBot.api.getCoordOfMe () ); List<Ways> allObjects = new List<Ways> (); // все сектора с необходимого типа List<Ways> unUsableSector = new List<Ways> (); List<Ways> unUseHelthSector = new List<Ways> (); q1.Enqueue ( temp.Clone () ); while (interationNum <-1 && !found) { while ((q1.Count > 0 || q2.Count > 0) && distance <= roadlen) { q2 = new Queue<Ways> (); // Вспомогательная while (q1.Count > 0) { temp = q1.Dequeue (); // достали вершину из очереди, пора узнать что в ней изменилось temp.gun ().decTimer (); temp.len = distance; //--1------------------ if (EpsilonBot.api.isNorm ( temp.xy )) { //--4----------------- // if (temp.gun ().getTimerVal > Gun.cminSaflyTime && mind.) { //--2------------------ if (EpsilonBot.api.getTypeOfField ( temp.xy ) == stm) { allObjects.Add ( temp ); // все сектора на допустимой длинне } else { //--3------------------- if (temp.gun ().getTimerVal > Gun.cminSaflyTime && EpsilonBot.api.getTypeOfField ( temp.xy ) != TypesOfField.NOTHING) { temp.getAllUsableSectors ( unUsableSector,q2 ); //всех соседей данной вершины графа в очередь unUsableSector.Add ( temp ); if (EpsilonBot.api.getTypeOfField ( temp.xy ) == TypesOfField.MEDKIT && TypesOfField.MEDKIT != stm) { unUseHelthSector.Add ( temp ); } }//--3--------------------- }//--2---------------------- //}//--4----------------------- }//--1----------------------- distance++; q1 = q2; } } //Ways w = null; //w = new Ways (); //w.xy.setX ( 1 ); //w.xy.setY ( 4 ); //allObjects.Add ( w ); //w = new Ways (); //w.xy.setX ( 4 ); //w.xy.setY ( 1 ); //allObjects.Add ( w ); if (allObjects.Count != 0) { //bool f=false; IStep st; if (!(allObjects[0].gun ().getTimerVal > Gun.cminSaflyTime)) { st = lookAround ( allObjects,unUseHelthSector,4 );/// если маршрут выгоднее то пойти по нему } // если не выполн то запомнить ближ вершину и продолжить искать // просмотреть окрестность <=4 такую, что есть аптечка // если нашли то записали в список, и проверили остальные ячейки на данной волне удов пред услов, и выбрали лучш // если не нашли то увеличить волну q1 = q2; goForFar++ если стало >2 то идем к самой удаленной точке // distance++; } else { interationNum++; } } return goToFar ();// s; }
//----------------------------------------------- /// <summary> /// Вычисление предположительного местоположения Противника относительно предыдущих координат /// </summary> private void whereHe(MapSector sector,TypesOfField btype,TypesOfField type) { if (!mind.He.WasFound) { //int a = 1; //int b = 0; //for (int i = 1; i <= 4; i++) { // mayBeHere ( sector.xy.getX () + a,sector.xy.getY () + b,mind.hisMayBeXY,sector ); // if (i == 1 || i==3) { // a = -a; // b = -b; // } // if (i == 2) { // b = -a; // a = 0; // } //} mayBeHere ( sector.xy.getX () + 1,sector.xy.getY (),mind.hisMayBeXY,sector ); mayBeHere ( sector.xy.getX () - 1,sector.xy.getY (),mind.hisMayBeXY,sector ); mayBeHere ( sector.xy.getX (),sector.xy.getY () - 1,mind.hisMayBeXY,sector ); mayBeHere ( sector.xy.getX (),sector.xy.getY () + 1,mind.hisMayBeXY,sector ); } }
public void setType(TypesOfField ty) { if (((int)ty >= 0) && ((int)ty <= 5)) d = (int)ty; else throw new Exception("Клетка не является клеткой типа TypesOfField"); }
//----------------------------------------------- /// <summary> /// Анализ изменений содержимого сектора карты /// </summary> private void sectorAnalysis(MapSector sector,TypesOfField btype,TypesOfField type) { if (btype == TypesOfField.HI) { // если до этого там был противник то вычисляем куда он направился whereHe ( sector,btype,type ); simpleAddBase ( sector,btype,type ); // и перебиваем базу } if (btype == TypesOfField.NOTHING) { // если до этого небыло ничего simpleAddBase ( sector,btype,type ); // просто перебиваем базу } if (btype == TypesOfField.MEDKIT || btype == TypesOfField.BONUS) { // была аптечка или бонус if (type == TypesOfField.NOTHING) { // а теперь пусто то он там //if (api.isVisible ( api.getCoordOfMe (),sector.xy/*api.getCoordOfEnemy ()*/ )) { mayBeHere ( sector.xy.getX (),sector.xy.getY (),mind.hisMayBeXY,sector ); if (btype == TypesOfField.MEDKIT) { mind.He.Health += Mind.cHealthM; mind.He.WasFound = true; } if (btype == TypesOfField.BONUS) { mind.He.Money += Mind.cMoneyM; mind.He.WasFound = true; } if (mind.He.WasFound) { mind.hisMayBeXY.Clear (); mind.hisMayBeXY.AddFirst ( sector ); mind.He.XY = sector.xy; } if (btype == TypesOfField.ME) { // а теперь он знает где я mind.I.WasFound = true; } //} } } }
//----------------------------------------------- /// <summary> /// выделение указателей на вершины графа определенного типа в соответсвующую базу /// </summary> private void simpleAddBase(MapSector sector,TypesOfField btypes,TypesOfField types) { if (types == TypesOfField.MEDKIT){ // то просто добавить в базу mind.healthXY.AddFirst(sector); } if (types == TypesOfField.BONUS){ mind.moneyXY.AddFirst ( sector ); } if (types == TypesOfField.HI){ if (!mind.hisMayBeXY.Contains ( sector )) { mind.hisMayBeXY.AddFirst ( sector ); } } }
/// <summary>есть ли путь на котором будут аптечки >=2 в пределах досягаемости /// </summary> /// <returns></returns> private bool epsilonSectors(TypesOfField needElement,Logistics startPoint,int stepCount,int roketTimer) { int moneySum = 0; int healthSum = 0; int tempMoney = 0; int tempHealth = 0; healthyWay ( +1,+0,startPoint,stepCount,Gun.cTimerZeroNone, healthSum, moneySum ); subEpsilonSectors ( tempMoney,tempHealth,ref moneySum,ref healthSum ); healthyWay ( -1,-0,startPoint,stepCount,Gun.cTimerZeroNone, tempHealth, tempMoney ); subEpsilonSectors ( tempMoney,tempHealth,ref moneySum,ref healthSum ); healthyWay ( +0,+1,startPoint,stepCount,Gun.cTimerZeroNone, tempHealth, tempMoney ); subEpsilonSectors ( tempMoney,tempHealth,ref moneySum,ref healthSum ); healthyWay ( +0,-1,startPoint,stepCount,Gun.cTimerZeroNone, tempHealth, tempMoney ); subEpsilonSectors ( tempMoney,tempHealth,ref moneySum,ref healthSum ); return (healthSum >= 2 * Mind.cHealthM) /*спорная часть*//*|| (moneySum >= 2*Mind.cMoneyM && healthSum >= Mind.cHealthM)*/; }
/// <summary> /// расчет пути к сектору карты запрашиваемого типа /// </summary> /// <param name="needElement">тип ячейки к которой необходимо проложить маршрут</param> /// <param name="startPoint">отправная точка</param> /// <param name="stepCount">максимальная удаленность объекта</param> /// <returns></returns> internal IStep wayOfEvil(TypesOfField needElement,Logistics startPoint,int stepCount,int roketTimer) { int roadLen = 0; bool found = false; bool exit = false; IStep s = Helper.StepsBuilder ( startPoint.xy,Steps.STEP ); Queue<Logistics> wayBase = new Queue<Logistics> (); //база путей возможных за данную длинну Queue<Logistics> forWalk = new Queue<Logistics> (); //для прохода по графу Logistics x = new Logistics ( mind.I.XY,mind.He.gun ().getTimerVal,roadLen,startPoint ); forWalk.Enqueue ( x ); while (!found && !exit && forWalk.Count > 0 && stepCount > 0 ) { //--1------------------------- if (forWalk.Peek ().roadLen < stepCount) { roadLen = forWalk.Peek ().roadLen; while (!exit && roadLen == forWalk.Peek ().roadLen){ // обрабатываем все вершины на данной волне x = forWalk.Dequeue (); //--2------------------------- if (EpsilonBot.api.getTypeOfField ( x.xy ) == needElement) { // если нашли необходимую ячейку то стоп //--3------------------------- x.gunTimer=Gun.cTimerZeroNone; if (epsilonSectors ( TypesOfField.MEDKIT,x,Math.Min(x.gunTimer,stepCount-roadLen),x.gunTimer)){ // и если есть в окрестности аптечки //wayBase.Enqueue ( x ); found = true; }//--3------------------------ } else { // иначе possibleWays ( +1,+0,x,ref forWalk ); // извлекаем всех соседей данной вершины possibleWays ( -1,-0,x,ref forWalk ); // и по возможности помещаем в очередь possibleWays ( +0,+1,x,ref forWalk ); possibleWays ( -0,-1,x,ref forWalk ); }//--2------------------------ exit = forWalk.Count == 0; }//--1------------------------- } else { // если радиус волны больше чем длиннна возможного пути exit = true; } } if (found) { //x = findBestWay ( wayBase );// спорный момент по выбору путей s = comeBack ( x ); } return s; }
//----------------------------------------------- /// <summary> /// Вычисление предположительного местоположения Противника относительно предыдущих координат /// </summary> private void whereHe(ICoordinates xy,TypesOfField btype,TypesOfField type) { if (!mind.He.WasFound) { ICoordinates c ; c = StepsAndCoord.Coordinates ( xy.getX () + 0,xy.getY () + 0 ); mayBeHere ( c,mind.hisMayBeXY ); c = StepsAndCoord.Coordinates (xy.getX () + 1,xy.getY () + 0 ); mayBeHere ( c, mind.hisMayBeXY ); c = StepsAndCoord.Coordinates ( xy.getX () - 1,xy.getY () + 0 ); mayBeHere ( c,mind.hisMayBeXY ); c = StepsAndCoord.Coordinates ( xy.getX () + 0,xy.getY () - 1 ); mayBeHere ( c,mind.hisMayBeXY ); c = StepsAndCoord.Coordinates ( xy.getX () + 0,xy.getY () + 1 ); mayBeHere ( c,mind.hisMayBeXY ); } }
//----------------------------------------------- /// <summary> /// выделение указателей на вершины графа определенного типа в соответсвующую базу /// </summary> private void simpleAddBase(MapSector sector,TypesOfField types) { if (types == TypesOfField.MEDKIT){ // то просто добавить в базу mind.healthXY.Add(sector); } if (types == TypesOfField.BONUS){ mind.moneyXY.Add ( sector ); } if (types == TypesOfField.HI){ mayBeHere ( sector.xy, mind.hisMayBeXY ); } }
//----------------------------------------------- /// <summary> /// Анализ изменений содержимого сектора карты /// </summary> private void sectorAnalysis(ICoordinates xy,TypesOfField btype,TypesOfField type,int distance) { // если до этого там был противник, а теперь исчез, то вычисляем куда он направился if (btype == TypesOfField.HI) { whereHe ( xy,btype,type ); } if (btype == TypesOfField.MEDKIT || btype == TypesOfField.BONUS) { // была аптечка или бонус if (type == TypesOfField.NOTHING) { // а теперь пусто то он там // mayBeHere ( xy,mind.hisMayBeXY ); if (btype == TypesOfField.MEDKIT) { mind.He.Health += Mind.cHealthM; mind.He.WasFound = true; } if (btype == TypesOfField.BONUS) { mind.He.Money += Mind.cMoneyM; mind.He.WasFound = true; } if (mind.He.WasFound) { heDetected ( xy ); } if (btype == TypesOfField.ME) { // а теперь он знает где я mind.I.WasFound = true; } //} } } if (btype==TypesOfField.NOTHING){ MapSector m = new MapSector (); m.usableForWave = true; m.type = type; m.xy.Copy ( xy ); } }