private bool TryBuildNewComponent(out AiMoveDecision move) { var queue = new Queue <BuildQueueItem>(); var used = new Dictionary <int, BuildQueueItem>(); foreach (var mineV in graph.GetNotOwnedMines(state.punter)) { var queueItem = new BuildQueueItem { CurrentVertex = mineV, SourceMine = mineV, FirstEdge = null }; queue.Enqueue(queueItem); used.Add(mineV.Id, queueItem); } while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var edge in current.CurrentVertex.Edges.Where(x => x.CanBeOwnedBy(state.punter, allowToUseOptions))) { var next = graph.Vertexes[edge.To]; BuildQueueItem prev; if (used.TryGetValue(next.Id, out prev)) { if (prev.SourceMine != current.SourceMine) { var bestMine = SelectBestMine(prev.SourceMine, current.SourceMine); if (bestMine == prev.SourceMine) { var edge1 = prev.FirstEdge ?? edge; move = AiMoveDecision.ClaimOrOption(edge1, state.punter, allowToUseOptions); return(true); } if (bestMine == current.SourceMine) { var edge1 = current.FirstEdge ?? edge; move = AiMoveDecision.ClaimOrOption(edge1, state.punter, allowToUseOptions); return(true); } } } else { var queueItem = new BuildQueueItem { CurrentVertex = next, SourceMine = current.SourceMine, FirstEdge = current.FirstEdge ?? edge }; queue.Enqueue(queueItem); used.Add(next.Id, queueItem); } } } move = null; return(false); }
public AiMoveDecision GetNextMove(State state, IServices services) { var myStrategy = StrategyProvider(state, services); var enemyStrategies = Enumerable.Range(0, state.punters) .Except(new[] { state.punter }) .Select(enemyId => StrategyProvider(state, services)) .ToArray(); var bestTurn = GetMyBestTurn(myStrategy); var enemyBestTurns = enemyStrategies .Select(s => s.NextTurns()) .Where(ts => ts.Count >= 2) .Select(ts => ts.OrderByDescending(x => x.Estimation).Take(2).ToArray()) .ToArray(); if (enemyBestTurns.Any()) { var bestestEnemyTurns = enemyBestTurns.MaxBy(ts => ts[0].Estimation - ts[1].Estimation); if (bestestEnemyTurns[0].Estimation > Settings.EnemyTurnEstimationDifferenceWeight * bestestEnemyTurns[1].Estimation && bestestEnemyTurns[0].Estimation > Settings.MyTurnEsimationWeight * bestTurn.Estimation) { bestTurn = bestestEnemyTurns[0]; } } if (bestTurn.Estimation < 0) { return(AiMoveDecision.Pass(state.punter)); } return(bestTurn.Move); }
public List <TurnResult> NextTurns() { var result = new List <TurnResult>(); var mines = Graph.Mines.Keys.ToList(); for (var i = 0; i < mines.Count; i++) { for (var j = i + 1; j < mines.Count; j++) { var denic = new Dinic(Graph, PunterId, mines[i], mines[j], out int flow); if (flow == 0 || flow == Dinic.INF) { continue; } var cut = denic.GetMinCut(); foreach (var edge in cut) { result.Add( new TurnResult { Estimation = Random.Value.NextDouble(), Move = AiMoveDecision.Claim(edge, PunterId, "Because I'm crazy!") }); } } } return(result); }
private List <TurnResult> GetTurnsForComponents(Graph graph, ConnectedComponent[] connectedComponents, ConnectedComponent currentComponent) { EdgeWeighter.Init(connectedComponents, currentComponent); var vertices = currentComponent.Vertices .SelectMany(v => graph.Vertexes[v].Edges) .ToList(); var claimVertices = vertices .Where(e => e.Owner == -1 && !AreConnected(currentComponent, e.From, e.To)) .Select(e => new TurnResult { Estimation = EdgeWeighter.EstimateWeight(e), Move = AiMoveDecision.Claim(e, PunterId) }); var optionVertices = !State.settings.options || State.map.OptionsLeft(State.punter) <= 0 ? Enumerable.Empty <TurnResult>() : vertices .Where(e => e.Owner != -1 && e.OptionOwner == -1 && !AreConnected(currentComponent, e.From, e.To)) .Select(e => new TurnResult { Estimation = EdgeWeighter.EstimateWeight(e) * OptionPenaltyMultiplier, Move = AiMoveDecision.Option(e, PunterId) }).ToList(); return(claimVertices.Concat(optionVertices) .Where(t => t.Estimation > 0) .ToList()); }
public List <TurnResult> NextTurns() { var claimedVertexes = Graph.Vertexes.Values .SelectMany(x => x.Edges) .Where(edge => edge.Owner == PunterId) .SelectMany(edge => new[] { edge.From, edge.To }) .Distinct() .ToArray(); if (claimedVertexes.Length == 0) { return(Graph.Mines.Values .SelectMany(v => v.Edges) .Where(e => e.Owner == -1) .Select( e => new TurnResult { Estimation = 1, Move = AiMoveDecision.Claim(e, PunterId, "No edges yet, selecting first mine") }) .ToList()); } var connectedComponents = ConnectedComponentsService.For(PunterId); var maxComponent = connectedComponents.MaxBy(comp => comp.Vertices.Count); EdgeWeighter.Init(connectedComponents, maxComponent); var vertices = maxComponent.Vertices .SelectMany(v => Graph.Vertexes[v].Edges) .ToList(); var claimVertices = vertices .Where(e => e.Owner == -1 && !AreConnected(maxComponent, e.From, e.To)) .Select( e => new TurnResult { Estimation = EdgeWeighter.EstimateWeight(e), Move = AiMoveDecision.Claim(e, PunterId) }); var optionVertices = !State.settings.options || State.map.OptionsLeft(State.punter) <= 0 ? Enumerable.Empty <TurnResult>() : vertices .Where(e => e.Owner != -1 && e.OptionOwner == -1 && !AreConnected(maxComponent, e.From, e.To)) .Select(e => new TurnResult { Estimation = EdgeWeighter.EstimateWeight(e) * OptionPenaltyMultiplier, Move = AiMoveDecision.Option(e, PunterId) }).ToList(); return(claimVertices.Concat(optionVertices) .Where(t => t.Estimation > 0) .ToList()); }
private AiMoveDecision TryGetNextMove() { var sitesToDefend = state.aiSetupDecision.futures.SelectMany(f => new[] { f.source, f.target }).ToArray(); var edge = new MovesSelector(allowToUseOptions, state.map, graph, sitesToDefend, state.punter).GetNeighbourToGo(); if (edge != null) { return(AiMoveDecision.ClaimOrOption(edge, state.punter, allowToUseOptions, "futures cant wait!!1")); } return(null); }
public AiMoveDecision GetNextMove(State state, IServices services) { var strategy = StrategyProvider(state, services); var turns = strategy.NextTurns(); if (!turns.Any()) { return(AiMoveDecision.Pass(state.punter)); } return(turns.MaxBy(x => x.Estimation).Move); }
public List <TurnResult> NextTurns() { Init(); return(edgesToBlock.Keys .Select( edge => new TurnResult { Estimation = EstimateWeight(edge), Move = AiMoveDecision.ClaimOrOption(edge, PunterId, allowToUseOptions) }) .Where(river => river.Estimation > 0) .ToList()); }
public List <TurnResult> NextTurns() { Init(); return(Graph.Vertexes.Values .SelectMany(v => v.Edges) .Select( edge => edge.IsFree ? new TurnResult { Estimation = EstimateWeight(edge), Move = AiMoveDecision.Claim(edge, PunterId), } : null) .Where(river => river != null && river.Estimation > 0) .ToList()); }
private static AiMoveDecision GetNextMove(IAi ai, State state, bool eatExceptions, Dictionary <IAi, Exception> lastException) { try { return(ai.GetNextMove(state, new Services(state))); } catch (Exception e) { lastException[ai] = e; if (eatExceptions) { return(AiMoveDecision.Pass(state.punter, e.ToString())); } else { throw; } } }
private bool TryExtendComponent(out AiMoveDecision move) { //TODO Сейчас увеличивает первую попавшуюся компоненту. А может быть нужно расширять самую большую компоненту. var queue = new Queue <ExtendQueueItem>(); var used = new HashSet <int>(); foreach (var mineV in graph.GetNotOwnedMines(state.punter)) { var queueItem = new ExtendQueueItem { CurrentVertex = mineV, Edge = null }; queue.Enqueue(queueItem); used.Add(mineV.Id); } while (queue.Count > 0) { var current = queue.Dequeue(); if (current.CurrentVertex.Edges.Any(x => x.IsOwnedBy(state.punter))) { move = AiMoveDecision.ClaimOrOption(current.Edge, state.punter, allowToUseOptions); return(true); } foreach (var edge in current.CurrentVertex.Edges.Where(x => x.CanBeOwnedBy(state.punter, allowToUseOptions))) { var next = graph.Vertexes[edge.To]; if (!used.Contains(next.Id)) { var queueItem = new ExtendQueueItem { CurrentVertex = next, Edge = edge }; queue.Enqueue(queueItem); used.Add(next.Id); } } } move = null; return(false); }
private AiMoveDecision TryGetNextMove() { var meetingPoint = meetingPointService.MeetingPoint; var toDo = graph.GetNotOwnedMines(state.punter).Select(x => x.Id); var myVerts = graph.Vertexes.Values.Where( v => v.Edges.Any(e => e.IsOwnedBy(state.punter)) || v.Id == meetingPoint) .Select(x => x.Id) .ToList(); var shortest = new ShortestPathFinder(graph, state.punter, myVerts); var skip = false; foreach (var mine in toDo) { var path = shortest.GetPath(mine); if (path == null) { continue; } int len = path.Count - 1; if (len > state.credits[state.punter]) { skip = true; continue; } return(AiMoveDecision.Splurge(state.punter, path.ToArray())); } if (skip) { return(AiMoveDecision.Pass(state.punter, "wait")); } return(null); }
public List <TurnResult> NextTurns() { var calculator = new ConnectedCalculator(Graph, PunterId); var result = new List <TurnResult>(); foreach (var vertex in Graph.Vertexes.Values) { foreach (var edge in vertex.Edges.Where(x => x.CanBeOwnedBy(PunterId, allowToUseOptions))) { var fromMines = calculator.GetConnectedMines(edge.From); var toMines = calculator.GetConnectedMines(edge.To); var fromScore = CalcVertexScore(toMines, fromMines, edge.From); var toScore = CalcVertexScore(fromMines, toMines, edge.To); var addScore = AggregateEdgeScores(fromScore, toScore); result.Add( new TurnResult { Estimation = addScore, Move = AiMoveDecision.ClaimOrOption(edge, PunterId, allowToUseOptions) }); } } return(result); }