private int CalculatePlayerPositionInRace(Opponent player) { if (CurrentRace == null) { return(0); } int output = 1; int playerCheckpoint = player.CheckpointsPassed; int beforeYou = Opponents.Count(tuple => { if (tuple == player) { return(false); } return(tuple.CheckpointsPassed > playerCheckpoint); }); output += beforeYou; var samePosAsYou = Opponents.Where(tuple => tuple.CheckpointsPassed == playerCheckpoint && tuple != player); output += samePosAsYou.Count( tuple => (CurrentRace.Checkpoints[playerCheckpoint].Subtract(tuple.Client.position)).Length() < (CurrentRace.Checkpoints[playerCheckpoint].Subtract(player.Client.position)).Length()); return(output); }
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); } }
public override void OnTick() { if (!IsRaceOngoing) { return; } lock (Opponents) { lock (CurrentRaceCheckpoints) foreach (var opponent in Opponents) { if (opponent.HasFinished || !opponent.HasStarted) { continue; } if (CurrentRaceCheckpoints.Any() && opponent.Client.LastKnownPosition.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) { opponent.CheckpointsPassed++; if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) { if (Opponents.All(op => !op.HasFinished)) { var t = new Thread((ThreadStart) delegate { Thread.Sleep(10000); Program.ServerInstance.SendChatMessageToAll("Vote for next map will start in 60 seconds!"); Thread.Sleep(30000); Program.ServerInstance.SendChatMessageToAll("Vote for next map will start in 30 seconds!"); Thread.Sleep(30000); if (!IsVoteActive()) { StartVote(); } }); t.Start(); } opponent.HasFinished = true; var pos = Opponents.Count(o => o.HasFinished); var suffix = pos.ToString().EndsWith("1") ? "st" : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; Program.ServerInstance.SendNotificationToAll("~h~" + opponent.Client.DisplayName + "~h~ has finished " + pos + suffix); Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0x45FF974EEE1C8734, opponent.Blip, 0); Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER"); Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR"); continue; } Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0xAE2AF67E9D9AF65D, opponent.Blip, CurrentRaceCheckpoints[opponent.CheckpointsPassed].X, CurrentRaceCheckpoints[opponent.CheckpointsPassed].Y, CurrentRaceCheckpoints[opponent.CheckpointsPassed].Z); Program.ServerInstance.SetNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER", 0x28477EC23D892089, 1, CurrentRaceCheckpoints[opponent.CheckpointsPassed], new Vector3(), new Vector3(), new Vector3() { X = 10f, Y = 10f, Z = 2f }, 241, 247, 57, 180, false, false, 2, false, false, false, false); if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed + 1) { var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; if (nextCp != null && curCp != null) { Vector3 dir = nextCp.Subtract(curCp); dir = dir.Normalize(); Program.ServerInstance.SetNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR", 0x28477EC23D892089, 20, curCp.Subtract(new Vector3() { X = 0f, Y = 0f, Z = -2f }), dir, new Vector3() { X = 60f, Y = 0f, Z = 0f }, new Vector3() { X = 4f, Y = 4f, Z = 4f }, 87, 193, 250, 200, false, false, 2, false, false, false, false); } } else { Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR"); } } } } }
public void onUpdate() { if (DateTime.Now.Subtract(LastSecond).TotalMilliseconds > 1000) { LastSecond = DateTime.Now; if (RaceStartCountdown > 0) { RaceStartCountdown--; if (RaceStartCountdown == 3) { API.triggerClientEventForAll("startRaceCountdown"); } else if (RaceStartCountdown == 0) { IsRaceOngoing = true; lock (Opponents) foreach (var opponent in Opponents) { API.setEntityPositionFrozen(opponent.Client, opponent.Vehicle, false); opponent.HasStarted = true; } RaceTimer = DateTime.Now; } } } if (!IsRaceOngoing) { return; } CalculatePositions(); UpdateScoreboard(); lock (Opponents) { lock (CurrentRaceCheckpoints) foreach (var opponent in Opponents) { if (opponent.HasFinished || !opponent.HasStarted) { continue; } if (CurrentRaceCheckpoints.Any() && opponent.Client.position.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) { opponent.CheckpointsPassed++; if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) { if (Opponents.All(op => !op.HasFinished)) { API.exported.mapcycler.endRoundEx(60000); } opponent.HasFinished = true; var pos = Opponents.Count(o => o.HasFinished); var suffix = pos.ToString().EndsWith("1") ? "st" : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; var timeElapsed = DateTime.Now.Subtract(RaceTimer); API.sendChatMessageToAll("~h~" + opponent.Client.name + "~h~ has finished " + pos + suffix + " (" + timeElapsed.ToString("mm\\:ss\\.fff") + ")"); opponent.TimeFinished = timeElapsed.ToString("mm\\:ss\\.fff"); API.triggerClientEvent(opponent.Client, "finishRace"); continue; } Vector3 nextPos = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; Vector3 nextDir = null; if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed + 1) { var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; if (nextCp != null && curCp != null) { Vector3 dir = nextCp.Subtract(curCp); dir.Normalize(); nextDir = dir; } } if (nextDir == null) { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, true, true); } else { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, false, true, nextDir, CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]); } } } } }
public void onUpdate(object sender, EventArgs e) { if (!IsRaceOngoing) { return; } lock (Opponents) { lock (CurrentRaceCheckpoints) foreach (var opponent in Opponents) { if (opponent.HasFinished || !opponent.HasStarted) { continue; } if (CurrentRaceCheckpoints.Any() && opponent.Client.Position.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) { opponent.CheckpointsPassed++; if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) { if (Opponents.All(op => !op.HasFinished)) { API.startThread((ThreadStart) delegate { API.sleep(10000); API.sendChatMessageToAll("Vote for next map will start in 60 seconds!"); API.sleep(30000); API.sendChatMessageToAll("Vote for next map will start in 30 seconds!"); API.sleep(30000); if (!IsVoteActive()) { StartVote(); } }); } opponent.HasFinished = true; var pos = Opponents.Count(o => o.HasFinished); var suffix = pos.ToString().EndsWith("1") ? "st" : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; API.sendChatMessageToAll("~h~" + opponent.Client.Name + "~h~ has finished " + pos + suffix); API.triggerClientEvent(opponent.Client, "finishRace"); continue; } Vector3 nextPos = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; Vector3 nextDir = null; if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed + 1) { var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; if (nextCp != null && curCp != null) { Vector3 dir = nextCp.Subtract(curCp); dir = dir.Normalize(); nextDir = dir; } } if (nextDir == null) { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, true, true); } else { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, false, true, nextDir, CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]); } } } } }
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); }
int HowManyCanShoot(Point position, TrooperStance stance) { return(Opponents.Count( trooper => world.IsVisible(GetShootingRange(self, self.Stance), position.X, position.Y, stance, trooper.X, trooper.Y, trooper.Stance) )); }