// Основной метод public void Move(Trooper self, World world, Game game, Move move) { if (self.ActionPoints == 0) return; cnt_invoke = 0; m_self = self; m_game = game; m_world = world; m_cells = world.Cells; // Определение игрока-цели Player nearToCentr = null; foreach (Player p in world.Players) if (p.Id != self.PlayerId && p.ApproximateX >= 0 && p.ApproximateY >= 0) if (nearToCentr == null || FindNextStep(self.X, self.Y, nearToCentr.ApproximateX, nearToCentr.ApproximateY, 3).dist > FindNextStep(self.X, self.Y, p.ApproximateX, p.ApproximateY, 3).dist ) nearToCentr = p; if (nearToCentr != null) { targetX = nearToCentr.ApproximateX; targetY = nearToCentr.ApproximateY; } if (m_cellDangerous == null) CellDangerous(); if (targetX == -1 && targetY == -1) { targetX = self.X; targetY = self.Y; } // Запрос цели const double stageDist = 2.5; if (self.GetDistanceTo(targetX, targetY) <= stageDist || world.MoveIndex - moveWithoutEnemy >= 4) { bool CommanderAlive = false; foreach (Trooper tr in world.Troopers) if (tr.IsTeammate && tr.Type == TrooperType.Commander) CommanderAlive = true; if (!CommanderAlive) { targetX = random.Next(world.Width); targetY = random.Next(world.Height); moveWithoutEnemy = world.MoveIndex; } else if (self.Type == TrooperType.Commander && self.ActionPoints >= game.CommanderRequestEnemyDispositionCost) { move.Action = ActionType.RequestEnemyDisposition; moveWithoutEnemy = world.MoveIndex; return; } } // Заполнение списка солдат, определение отсутствия врагов if (self.ActionPoints >= self.InitialActionPoints) m_troopers = new ArrayList(); foreach (Trooper trooper in m_world.Troopers) { if (trooper.IsTeammate == false) moveWithoutEnemy = m_world.MoveIndex; bool isExist = false; for (int i = 0; i < m_troopers.Count; i++) { MyTrooper mt = (MyTrooper)m_troopers[i]; if (mt.Id == trooper.Id && mt.PlayerId == trooper.PlayerId) { isExist = true; m_troopers[i] = new MyTrooper(trooper); break; } } if (!isExist) m_troopers.Add(new MyTrooper(trooper)); } // Выбор оптимального действия Move m = FindNextMove(new MyTrooper(self), new ArrayList(m_world.Players), m_troopers, new ArrayList(m_world.Bonuses)).move; move.Action = m.Action; move.Direction = m.Direction; move.X = m.X; move.Y = m.Y; return; }
public void Move(Trooper self, World world, Game game, Move move) { if (form == null) { thread = new Thread(showWindow); thread.Start(); Thread.Sleep(1000); } var panel = form.panel; var drawArea = new Bitmap(panel.Size.Width, panel.Size.Height); panel.Image = drawArea; Graphics g = Graphics.FromImage(drawArea); Pen pen = new Pen(Brushes.Black); g.DrawLine(pen, 1, 1, 40, 40); this.self = self; this.world = world; this.game = game; this.move = move; InitializeVariables(); ProcessApproximation(); if (world.MoveIndex == 37 && self.Type == TrooperType.Commander) world = world; var allowHill = !CheckShootMe(); if (BonusGoal != null && GetTrooper(MyStrategy.WhoseBonus) == null) BonusGoal = null; if (BonusGoal != null && IsHaveBonus(GetTrooper(MyStrategy.WhoseBonus), GetBonusAt(BonusGoal))) BonusGoal = null; // Карта где медик и снайпер отдельно (map03) // Координаты где собираться: // 18 13 // 11 6 if (MapHash == Lab2Map && world.MoveIndex <= 2 && (self.Type == TrooperType.FieldMedic || self.Type == TrooperType.Sniper) && Opponents.Count() == 0 ) { var rightLower = new Point(18, 14); var leftUpper = new Point(11, 5); var goal = rightLower.GetDistanceTo(self) < leftUpper.GetDistanceTo(self) ? rightLower : leftUpper; var to = GoScouting(goal, goal); if (to != null) { Go(ActionType.Move, to); return; } } if (IfFieldRationNeed()) { Go(ActionType.EatFieldRation); return; } Reached(new Point(self)); if (Opponents.Count() != 0) { AllowTakeBonus = false; // Чтобы знали куда бежать если противник отступит PointGoal = new Point(Opponents[0]); PointGoal.profit = world.MoveIndex; var action = BruteForceDo(); if (action != null) { if (Equal(self, action) && action.Action == ActionType.Move && self.ActionPoints < GetMoveCost()) { Go(ActionType.EndTurn); } else { Go(action.Action, new Point(action.X, action.Y)); } return; } } if (self.Type == TrooperType.FieldMedic) { var ifHelp = IfHelpTeammate(); if (ifHelp != null) { var goal = GetTrooperAt(ifHelp.X, ifHelp.Y); if (goal != null && goal.Hitpoints < goal.MaximalHitpoints && ifHelp.Nearest(self) && game.FieldMedicHealCost <= self.ActionPoints) { Go(ActionType.Heal, ifHelp); return; } if (IsCanMove()) { var to = GoToUnit(self, ifHelp, map, beginFree: true, endFree: true); if (to != null) { Go(ActionType.Move, to); return; } } } } var ifUseMedikit = IfUseMedikit(); if (ifUseMedikit != null) { Go(ActionType.UseMedikit, ifUseMedikit); return; } if (allowHill && IfRequestEnemyDisposition()) { Go(ActionType.RequestEnemyDisposition); return; } // Группировка if ((GetTeamRadius() > MaxTeamRadius && self.Id == commander.Id || GetTeamRadius() > MaxTeamRadius/2 && self.Id != commander.Id) && self.ActionPoints >= GetMoveCost()) { var bestTurn = new Point(0, 0, Inf); for (var i = 0; i < Width; i++) { for (var j = 0; j < Height; j++) { var r = Math.Max(MaxTeamRadius, GetTeamRadius(self.Id, new Point(i, j))); if (r < bestTurn.profit && r < GetTeamRadius()) { bestTurn.Set(i, j, r); } } } if (bestTurn.profit < Inf) { var to = GoScouting(bestTurn, PointGoal ?? (BonusGoal ?? bestTurn)); if (to != null) { Go(ActionType.Move, to); return; } } } Trooper whoseBonus = null; var ifTeamBonus = IfTeamBonus(ref whoseBonus, AllowTakeBonus); if (ifTeamBonus != null && BonusGoal == null && map[ifTeamBonus.X, ifTeamBonus.Y] == 0 && !Equal(ifTeamBonus, self)) { BonusGoal = ifTeamBonus; MyStrategy.WhoseBonus = whoseBonus.Id; } var waitingHelp = false; //allowHill && IfNeedHelp() && self.Type != TrooperType.FieldMedic && GetBestHelper() != null; var allowNothing = true; if (!waitingHelp && IsCanMove() && BonusGoal != null && MyStrategy.WhoseBonus == self.Id) { if (IsCanUpper()) { Go(ActionType.RaiseStance); return; } allowNothing = false; var to = GoScouting(BonusGoal, PointGoal ?? BonusGoal); //GoToUnit(self, BonusGoal, map, beginFree: true, endFree: false); // Если путь до бонуса пока что занят, то все равно идти к нему if (to == null) { to = GoToUnit(self, BonusGoal, notFilledMap, beginFree: true, endFree: true); if (to != null && map[to.X, to.Y] == 0 && self.ActionPoints >= 2 * GetMoveCost(self)) // TODO: ??? { Go(ActionType.Move, to); return; } } else { if (GetTeamRadius(self.Id, to) > MaxTeamRadius && GetTeamRadius() > GetTeamRadius(self.Id, to)) to = GoScouting(new Point(self), PointGoal ?? BonusGoal); Go(ActionType.Move, to); return; } } // Пытаюсь освободить дорогу до бонуса if (IsCanMove() && BonusGoal != null && MyStrategy.WhoseBonus != self.Id) { if (IsCanUpper()) { Go(ActionType.RaiseStance); return; } var bestTurn = SkipPath(GetTrooper(MyStrategy.WhoseBonus), PointGoal ?? BonusGoal); var to = bestTurn == null ? null : GoScouting(bestTurn, PointGoal ?? (BonusGoal ?? new Point(commander)));//GoToUnit(self, bestTurn, map, beginFree: true, endFree: false); if (to == null || Equal(to, self) && self.ActionPoints < GetMoveCost()) // если Equal(to, self)) тоже делаем move, иначе он не дойдет обратно Go(ActionType.EndTurn); else Go(ActionType.Move, to); return; } var ifNothing = IfNothing(); if (allowNothing && ifNothing != null && IsCanMove()) { if (IsCanUpper()) { Go(ActionType.RaiseStance); return; } Point to; if (self.Id == commander.Id) { to = GoToUnit(self, ifNothing, map, beginFree: true, endFree: false); if (GetTeamRadius(self.Id, to) > MaxTeamRadius) to = GoScouting(new Point(self), ifNothing); } else { to = GoScouting(ifNothing, ifNothing); } if (to == null || Equal(self, to) && self.ActionPoints < GetMoveCost()) { if (to == null && changedCommander == -1) { // значит мы застряли // передать коммандование ChangeCommander(); } else { Go(ActionType.EndTurn); return; } } else if (!waitingHelp) { Go(ActionType.Move, to); return; } } Point go = GoScouting(new Point(self), IfNothingCommander() ?? new Point(self)); // подумать что делать if (Equal(self, go) && self.ActionPoints < GetMoveCost()) Go(ActionType.EndTurn); else Go(ActionType.Move, go); }