public void run() { try { remoteProcessClient.WriteToken(token); int teamSize = remoteProcessClient.ReadTeamSize(); remoteProcessClient.WriteProtocolVersion(); Game game = remoteProcessClient.readGameContext(); IStrategy[] strategies = new IStrategy[teamSize]; for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) { strategies[strategyIndex] = new MyStrategy(); } PlayerContext playerContext; while ((playerContext = remoteProcessClient.ReadPlayerContext()) != null) { Trooper playerTrooper = playerContext.Trooper; Move move = new Move(); strategies[playerTrooper.TeammateIndex].Move(playerTrooper, playerContext.World, game, move); remoteProcessClient.WriteMove(move); } } finally { remoteProcessClient.Close(); } }
Move BruteForceDo() { var fictive = 0; if (queue.Count < Team.Count()) { foreach (var tr in Team) { if (!queue.Contains(tr.Id)) { queue.Add(tr.Id); fictive++; } } } OpponentCommander = Opponents.FirstOrDefault(opp => opp.Type == TrooperType.Commander); state = new State(); state.Position = new Point[Team.Count()]; state.stance = new int[Team.Count()]; state.act = new int[Team.Count()]; state.hit = new int[Team.Count()]; state.medikit = new bool[Team.Count()]; state.grenade = new bool[Team.Count()]; Troopers = new Trooper[Team.Count()]; CommanderId = -1; foreach (var tr in troopers) { if (tr.IsTeammate) { int pos = GetQueuePlace2(tr, true) - 1; state.Position[pos] = new Point(tr); state.stance[pos] = GetStanceId(tr.Stance); state.medikit[pos] = tr.IsHoldingMedikit; state.grenade[pos] = tr.IsHoldingGrenade; Troopers[pos] = tr; if (tr.Type == TrooperType.Commander) CommanderId = pos; } } state.id = 0; state.profit = 0; state.act[0] = Troopers[0].ActionPoints; MyCount = state.Position.Count(); for(var i = 0; i < MyCount; i++) state.hit[i] = Troopers[i].Hitpoints; for (var i = 1; i < Troopers.Count(); i++) state.act[i] = getInitialActionPoints(Troopers[i]); stack = new ArrayList[MyCount]; bestStack = new ArrayList[MyCount]; for (var i = 0; i < MyCount; i++) { stack[i] = new ArrayList(); bestStack[i] = null; } bestProfit = -Inf; counter = 0; OpponentsCount = Opponents.Count(); MyCount = state.Position.Count(); Multiplier = Math.Min(MyCount, 3); state.opphit = new int[OpponentsCount]; probab = new double[OpponentsCount]; for (var i = 0; i < probab.Length; i++) probab[i] = 1.0; for (var i = 0; i < OpponentsCount; i++) { state.opphit[i] = Opponents[i].Hitpoints; // Чтобы уменьшить приоритет стрельбы в "мнимую" цель if (world.MoveIndex - OpponentsMemoryAppearTime[i] > 1) probab[i] /= 2; else if (OpponentsMemoryType[i] == self.Type && world.MoveIndex - OpponentsMemoryAppearTime[i] == 1) probab[i] /= 2; // TODO: можно точнее else if (!(OpponentsMemoryType[i] == self.Type || IsBetween(OpponentsMemoryType[i], self.Type, Opponents[i].Type))) probab[i] /= 2; } dfs_changeStance1(); // remove fictive from queue queue.RemoveRange(queue.Count - fictive, fictive); var move = new Move(); ReduceStack(bestStack[0]); if (bestStack[0].Count == 0) { // EndTurn bestStack[0].Add("at " + self.X + " " + self.Y); } var cmd = ((string)bestStack[0][0]).Split(' '); if (cmd[0] == "st") { // Change stance var ds = int.Parse(cmd[1]); if (ds < 0) move.Action = ActionType.LowerStance; else if (ds > 0) move.Action = ActionType.RaiseStance; else throw new InvalidDataException(); } else if (cmd[0] == "at") { var x = int.Parse(cmd[1]); var y = int.Parse(cmd[2]); var to = bestStack[0].Count == 1 ? GoScouting(new Point(x, y), new Point(Opponents[0]), changeStanceAllow: true) : GoToUnit(self, new Point(x, y), map, beginFree: true, endFree: false); if (to.X == -1) move.Action = to.Y == -1 ? ActionType.LowerStance : ActionType.RaiseStance; else { move.Action = ActionType.Move; move.X = to.X; move.Y = to.Y; } } else if (cmd[0] == "sh") { var x = int.Parse(cmd[1]); var y = int.Parse(cmd[2]); move.Action = ActionType.Shoot; move.X = x; move.Y = y; } else if (cmd[0] == "med") { var to = new Point(int.Parse(cmd[1]), int.Parse(cmd[2])); move.Action = ActionType.UseMedikit; move.X = to.X; move.Y = to.Y; } else if (cmd[0] == "gr") { var to = new Point(int.Parse(cmd[1]), int.Parse(cmd[2])); move.Action = ActionType.ThrowGrenade; move.X = to.X; move.Y = to.Y; } else if (cmd[0] == "heal") { var to = new Point(int.Parse(cmd[1]), int.Parse(cmd[2])); move.Action = ActionType.Heal; move.X = to.X; move.Y = to.Y; } else { throw new NotImplementedException(cmd.ToString()); } return move; }
// Основной метод 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 WriteMove(Move move) { WriteEnum((sbyte?) MessageType.Move); if (move == null) { WriteBoolean(false); } else { WriteBoolean(true); WriteEnum((sbyte?) move.Action); WriteEnum((sbyte?) move.Direction); WriteInt(move.X); WriteInt(move.Y); } writer.Flush(); }
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); }