public async Task Act(Observation currentObservation) { var constantManager = new ConstantManager(Race.Terran); var supplyUnit = constantManager.SupplyUnit; // Fill queue if (RequireSupply(currentObservation) && currentObservation.GetPlayerUnitsInProgress(supplyUnit).Count == 0 && !_queue.Any(b => b.UnitType == supplyUnit)) { Console.WriteLine("Queue supply"); _queue.Enqueue(new BuildQueueItem { Action = () => _buildingManager.Build(currentObservation, supplyUnit, 2, 2), PreviousCount = currentObservation.GetPlayerUnits(supplyUnit, false).Count, UnitType = supplyUnit }); } if (currentObservation.GetPlayerUnits(supplyUnit).Count == 1 && currentObservation.GetPlayerUnits(constantManager.FirstArmyBuilding, false).Count < 3 && !_queue.Any(b => b.UnitType == constantManager.FirstArmyBuilding)) { Console.WriteLine("Queue baracks"); _queue.Enqueue(new BuildQueueItem { Action = () => _buildingManager.Build(currentObservation, constantManager.FirstArmyBuilding, 3, 3), PreviousCount = currentObservation.GetPlayerUnits(constantManager.FirstArmyBuilding, false).Count, UnitType = constantManager.FirstArmyBuilding }); } if (currentObservation.GetPlayerUnits(constantManager.FirstArmyBuilding).Count > 0 && !_queue.Any(b => b.UnitType == constantManager.FirstArmyUnit)) { Console.WriteLine("Queue marine"); _queue.Enqueue(new BuildQueueItem { Action = () => _unitManager.BuildUnitIfEmptyQueue(currentObservation, constantManager.FirstArmyBuilding, constantManager.FirstArmyUnit), PreviousCount = currentObservation.GetPlayerUnits(constantManager.FirstArmyUnit, false).Count, UnitType = constantManager.FirstArmyUnit }); } if (currentObservation.GetPlayerUnits(constantManager.FirstArmyUnit).Count >= 24 && DateTime.Now.Subtract(_attackTime).TotalMinutes > 2) { Console.WriteLine("Attack move"); await _armyManager.AttackMove(currentObservation); _attackTime = DateTime.Now; } // Trigger next build queue item, dequeue if previous trigger was successful or too delayed // Next trigger waits till Act is called again if (_queue.Count > 0) { var buildItem = _queue.Peek(); if (!buildItem.Triggered) { if (currentObservation.PlayerCommon.Minerals >= Game.ResponseData.Units.First(a => a.UnitId == buildItem.UnitType).MineralCost) { var actionAvailable = await buildItem.Action(); buildItem.ActTime = DateTime.Now; buildItem.Triggered = true; if (!actionAvailable) { _queue.Dequeue(); } } } else { // Check if previous trigger was successful if (currentObservation.GetPlayerUnits(buildItem.UnitType, false).Count > buildItem.PreviousCount) { _queue.Dequeue(); } // Previous trigger was delayed else if (DateTime.Now.Subtract(buildItem.ActTime).TotalSeconds > 8) { Console.WriteLine($"BuildItem failed: {buildItem}"); _queue.Dequeue(); } } } }