public Line ( double x1, double y1, double x2, double y2, float r = 0f, float g = 0f, float b = 0f ) : void | ||
x1 | double | |
y1 | double | |
x2 | double | |
y2 | double | |
r | float | |
g | float | |
b | float | |
리턴 | void |
public void Move(Wizard self, World world, Game game, Move move) { #if DEBUG // один раз вызвать Begin*() vc.BeginPost(); #endif move.Speed = game.WizardForwardSpeed; move.StrafeSpeed = game.WizardStrafeSpeed; move.Turn = game.WizardMaxTurnAngle; move.Action = ActionType.MagicMissile; #if DEBUG // вывод отладочной информации vc.Text(self.X - 35, self.Y - 37, string.Format("{0:D} | {1:F0} : {2:F0}", self.RemainingCooldownTicksByAction[(int)ActionType.MagicMissile], self.X, self.Y)); vc.Line(self.X, self.Y, self.X + Math.Cos(self.Angle - game.StaffSector / 2f) * self.CastRange, self.Y + Math.Sin(self.Angle - game.StaffSector / 2f) * self.CastRange, 1f, 0.7f, 0.7f); vc.Line(self.X, self.Y, self.X + Math.Cos(self.Angle + game.StaffSector / 2f) * self.CastRange, self.Y + Math.Sin(self.Angle + game.StaffSector / 2f) * self.CastRange, 1f, 0.7f, 0.7f); vc.Arc(self.X, self.Y, self.CastRange, self.Angle - game.StaffSector / 2f, game.StaffSector, 1f, 0.7f, 0.7f); #endif move.Turn = 0.01; move.Speed = 3; move.Action = ActionType.MagicMissile; #if DEBUG // в конце вызвать End*() vc.EndPost(); #endif }
/// <summary> /// Передвижение с отрисовкой /// </summary> /// <param name="point">Класс, описывающий точку на карте</param> /// <param name="world">Игровой мир</param> /// <param name="game">Константы игры</param> /// <param name="self">Собственный маг</param> /// <param name="move">Управление магом</param> /// <param name="vc">Объект-визуализатор</param> public void goToVisual(Point2D point, World world, Game game, Wizard self, Move move, VisualClient vc) { List <LinePoint> trace = new List <LinePoint>(); trace = getTrace(point, world, game, self); //отрисовываем все отрезки пути до hotZone int iCount = 0; foreach (LinePoint LP in trace) { double myX1; double myY1; if (iCount < 1) { myX1 = self.X; myY1 = self.Y; } else { myX1 = trace.ElementAt(iCount - 1).X; myY1 = trace.ElementAt(iCount - 1).Y; } iCount++; double myX2 = LP.X; double myY2 = LP.Y; vc.Line(myX1, myY1, myX2, myY2, 0.0f, 1.0f, 0.0f); } double angle = self.GetAngleTo(trace[0].X, trace[0].Y); double px = trace[0].X; double py = trace[0].Y; if (trace.Count > 1) { if (isCrash(self) || CheckCrash == 1) { if (Math.Sqrt(Math.Pow(CrashP[0] - self.X, 2) + Math.Pow(CrashP[1] - self.Y, 2)) < CrashDis) { CrashedMove(move, self, game); CheckCrash = 1; } else { CrashP[0] = -1000; CrashP[1] = -1000; angle = self.GetAngleTo(trace[0].X, trace[0].Y); move.Turn = angle; if (Math.Abs(angle) < game.StaffSector / 4.0D) { move.Speed = game.WizardForwardSpeed; } if ((Math.Sqrt(Math.Pow(trace[0].X - self.X, 2) + Math.Pow(trace[0].Y - self.Y, 2))) < 10) { CheckCrash = 0; } } } else { double resX = px - trace[1].Y; double resY = py - trace[1].X; double res = Math.Sqrt(Math.Pow(resX, 2) + Math.Pow(resY, 2)); if (self.GetDistanceTo(trace[0].X, trace[0].Y) < 60) { i = 1; } if (i == 1) { angle = self.GetAngleTo(trace[1].X, trace[1].Y); if (self.GetDistanceTo(trace[0].X, trace[0].Y) >= res / 2) { i = 0; } } else { angle = self.GetAngleTo(trace[0].X, trace[0].Y); } move.Turn = angle; if (Math.Abs(angle) < game.StaffSector / 4.0D) { move.Speed = game.WizardForwardSpeed; } } } else { move.Turn = angle; if (Math.Abs(angle) < game.StaffSector / 4.0D) { move.Speed = game.WizardForwardSpeed; } } }
public void Move(Wizard self, World world, Game game, Move move) { #region //1. Стратегическая составляющая. //Это выбор стратегии для всех участников (если мы - верховный) //Выбор стратегии из пожеланий верховного //Это выбор актуальной стратегии на данный момент //(рашить или обороняться, где именно рашить, куда отступать и т.д.) //по каим-то иипирическим коэффициентам учитывает: //количество врагов (и их уровень/здоровье) //колчество союзников (и их уровень/здоровье) //перспективность прорыва //критичность обороны //расстояние до этой точки //наличие близких бонусов // и т.д. //Выдает координаты (или точку), куда двигаться нашему магу (и союзным магам, если мы - верховный) //Ответственный - Литвинов Михаил //2. Прокладка маршрута до точки из стратегической составляющей //Берем текущие наши координаты и желаемые координаты (из стратегической сост). //Учитывая деревья, врагов и союзников, прокладываем оптимальный маршрут до точки назначения. //Работает до какого-то порога расстояния (если мы дальше порогового значения). //3. Тактическая составляющая //Поведение нашего мага в приоритетной зоне: //атака крипов или магов противника //атака на башню противника //тактическое отступление за спины союзников //выбор типа атаки //подбор бонуса //уворачивание от стрел противника //принятие стрелы соперника в себя, защита союзника //подсвет башням //и т.д. //Здесь необходимо просчитывать физику наперед //Здесь может быть полезно использовать генетические алгопритмы и другие приемы ИИ //Ответственный - Ткаченко Сергей //4. Просчет вариантов прокачки //Учитывание пожеланий верховного //Выбор пожеланий для прокачки всех союзников (если мы - верховный) // //5. Выполнение действий //Это может быть регулятор //Это выполнение атак //и т.д. #endregion if (world.TickIndex < 1) { setVisual(); } if (vc != null) { vc.BeginPre(); vc.FillRect(0, 0, 500, 500, 1.0f, 0.0f, 1.0f); vc.FillRect(3500, 3500, 4000, 4000, 1.0f, 1.0f, 0.0f); vc.FillRect(1650, 1650, 2350, 2350, 1.0f, 0.0f, 1.0f); vc.EndPre(); vc.BeginPost(); //начинаем отрисовку поверх всех объектов локал-раннера string str = Convert.ToString(self.X) + " : " + Convert.ToString(self.Y); vc.Text(self.X, self.Y, str, 0.0f, 0.0f, 1.0f); } if (game.IsSkillsEnabled == true) { if (self.Level != oldLevel) { move.SkillToLearn = myStrat.getSkill(move, self); } } hotZone = myStrat.getHotZone(world, game, self); //myStrat.getHotZone2(world, game, self, vc); if (vc != null) { if (hotZone != null) { vc.Line(self.X, self.Y, hotZone.getX(), hotZone.getY(), 1.0f, 0.0f, 0.0f); } vc.Circle(self.X, self.Y, HOT_ZONE_POROG, 1.0f, 1.0f, 0.0f); vc.Circle(self.X, self.Y, ENEMY_POROG, 1.0f, 0.0f, 1.0f); List <LinePoint> MapPoint = myTracer.getPointMap(world); foreach (LinePoint LP in MapPoint) { vc.FillCircle(LP.X, LP.Y, 5, 0.0f, 1.0f, 0.0f); //string str = Convert.ToString(LP.X)+" : " + Convert.ToString(LP.Y); //vc.Text(LP.X, LP.Y, str, 0.0f, 0.0f, 1.0f); } } int CD = self.RemainingCooldownTicksByAction[2]; double nearestTargetDistance = myTactic.getNearestTargetDistance(world, self); if (world.TickIndex > game.FactionMinionAppearanceIntervalTicks * 0.75D) { if /*((nearestTargetDistance<ENEMY_POROG*0.9D || (nearestTargetDistance < ENEMY_POROG && CD<10) || self.GetDistanceTo(hotZone.getX(), hotZone.getY()) < HOT_ZONE_POROG)&&*/ (!myTactic.TacticIsAll(world, self, game))//) { myTactic.getTacticMove(world, game, self, move); if (vc != null) { vc.Text(self.X, self.Y + 50, "TACTIC", 0.0f, 0.0f, 1.0f); } } else { if (vc == null) { myTracer.goTo(hotZone, world, game, self, move); } else { myTracer.goToVisual(hotZone, world, game, self, move, vc); vc.Text(self.X, self.Y + 50, "TRACER", 0.0f, 0.0f, 1.0f); } } } /*if(nearestTargetDistance < ENEMY_POROG-50 ||(isTactic && nearestTargetDistance < ENEMY_POROG) || self.GetDistanceTo(hotZone.getX(), hotZone.getY()) < HOT_ZONE_POROG) * { * myTactic.getTacticMove(world, game, self, move); * if (vc != null) vc.Text(self.X, self.Y + 50, "TACTIC", 0.0f, 0.0f, 1.0f); * isTactic = true; * } else * { * if (vc == null) * { * myTracer.goTo(hotZone, world, game, self, move); * } else * { * myTracer.goToVisual(hotZone, world, game, self, move, vc); * * vc.Text(self.X, self.Y + 50, "TRACER", 0.0f, 0.0f, 1.0f); * } * isTactic = false; * }*/ //вызываем метод getHotZone у объекта-стратегии if (vc != null) { vc.EndPost(); //заканчиваем отрисовку } oldLevel = self.Level; }
/// <summary> /// !!! НЕ РЕАЛИЗОВАНО !!! Возвращает координаты самой важной зоны (реализация Овсянникова) /// </summary> /// <param name="world">Игровой мир</param> /// <param name="game">Константы игры</param> /// <param name="self">Собственный маг</param> /// <returns>Точка на двухмерной карте</returns> public Point2D getHotZone2(World world, Game game, Wizard self, VisualClient vc) { //определяеам список возможных зон List <HotZone> hotZones = getZones(world, self); //если список возможных зон не пуст if (hotZones.Count > 0) { double maxHot = 0.0D; Point2D returnPoint = new Point2D(hotZones.ElementAt(0).getX(), hotZones.ElementAt(0).getY()); //расставляем "температуру" каждой зоны foreach (HotZone hZ in hotZones) { double distanceFactor = 0.0D; double allyFactor = 0.0D; double enemyFactor = 0.0D; double allyHPFactor = 0.0D; double enemyHPFactor = 0.0D; //!!! НЕ РЕАЛИЗОВАНО ОПРЕДЕЛЕНИЕ ВЕЛИЧИН РАЗЛИЧНЫХ ФАКТОРОВ !!! foreach (Wizard wz in world.Wizards) //перебираем всех магов { double dist = wz.GetDistanceTo(hZ.getX(), hZ.getY()); //определение дистанции между текущей зоной и магом if (dist > 20 && dist < 600) { if (wz.Faction != self.Faction) { enemyFactor += 216000000.0 * K_enemy - dist * dist * dist * K_enemy; enemyHPFactor += K_enemyHP * (wz.MaxLife / wz.Life - 1); } else { allyFactor -= 216000000.0 * K_ally - dist * dist * dist * K_ally; allyHPFactor -= K_allyHP * (wz.MaxLife / (wz.MaxLife - wz.Life + 1) - 1); } } } foreach (Building build in world.Buildings) //перебираем все здания { double dist = build.GetDistanceTo(hZ.getX(), hZ.getY()); //определение дистанции между текущей зоной и зданием if (dist > 20 && dist < 600) { if (build.Faction != self.Faction) { enemyFactor += 2.0 * (216000000.0 * K_enemy - dist * dist * dist * K_enemy); enemyHPFactor += 2.3 * K_enemyHP * (build.MaxLife / build.Life - 1); } else { allyFactor -= 2.0 * (216000000.0 * K_ally - dist * dist * dist * K_ally); allyHPFactor -= 2.3 * K_allyHP * (build.MaxLife / (build.MaxLife - build.Life + 1) - 1); } } } foreach (Minion minion in world.Minions) //перебираем всех миньонов { double dist = minion.GetDistanceTo(hZ.getX(), hZ.getY()); //определение дистанции между текущей зоной и миньоном if (dist > 20 && dist < 600) { if (minion.Faction != self.Faction) { enemyFactor += 0.05 * (216000000.0 * K_enemy - dist * dist * dist * K_enemy); enemyHPFactor += 0.005 * K_enemyHP * (minion.MaxLife / minion.Life - 1); } else { allyFactor -= 0.05 * (216000000.0 * K_ally - dist * dist * dist * K_ally); allyHPFactor -= 0.005 * K_allyHP * (minion.MaxLife / (minion.MaxLife - minion.Life + 1) - 1); } } } double dist2 = self.GetDistanceTo(hZ.getX(), hZ.getY()); if (dist2 > 100) { distanceFactor = K_distance * (3000 / dist2); } hZ.hot = distanceFactor + allyFactor + enemyFactor + allyHPFactor + enemyHPFactor; if (vc != null) { vc.Text(hZ.getX(), hZ.getY(), Convert.ToString(hZ.hot), 1.0f, 0.0f, 0.0f); } } //выбираем зону с максимальной "температурой" foreach (HotZone hZ in hotZones) { if (hZ.hot > maxHot) { maxHot = hZ.hot; returnPoint = new Point2D(hZ.getX(), hZ.getY()); } } if (vc != null) { vc.Line(returnPoint.getX(), returnPoint.getY(), self.X, self.Y, 0.0f, 0.0f, 0.0f); } return(returnPoint); } else { //иначе, вызываем метод Литвинова return(getHotZone(world, game, self)); } }