public AnalyzerEngineProgram(AnalyzerEngine engine, FileLogger logger, FileLogger errorLogger, StatusSnapShotGenerator snapGen, EventHubProcessor eventHubProcessor) { Engine = engine; Logger = logger; ErrorLogger = errorLogger; SnapShotGenerator = snapGen; EventHubProcessor = eventHubProcessor; SnapShotGenerator.StartGenerator(); Engine.OnStateChanged += HandleEngineStateChange; Engine.OnReportException += HandleEngineException; EventProcessor.OnUpdatedInfo += HandleEventProcessorInfo; var toMessageLoop = new ToMessageLoop() { Engine = Engine, Logger = Logger, SnapShotGenerator = SnapShotGenerator, MesseageOutputQueue = MesseageOutputQueue }; var messageTimer = new Timer(MessageLoop, toMessageLoop, 0, 1000); Program.Timers.Add(messageTimer); var snapshotUpdateThread = new Thread(() => { while (true) { UpdateSnapshotAnalyzerInfo(); CurrentState.LastSnapshot = SnapShotGenerator.LastFileGeneratedTime; Thread.Sleep(4000); } }); snapshotUpdateThread.Name = nameof(snapshotUpdateThread); snapshotUpdateThread.Priority = ThreadPriority.BelowNormal; snapshotUpdateThread.IsBackground = true; snapshotUpdateThread.Start(); }
public void PrintStats() { var prices = AnalyzerEngine.CalculateAveragePrices(m_counts, m_allValues, m_excludedValues); for (int i = 0; i < prices.Length; i++) { foreach (var pair in prices[i]) { m_log("Item {0}, price {1} chance {2}", i, pair.Item1, pair.Item2); } } }
private static void Main(string[] args) { SetWindowSize(WindowWidth, WindowHeight); Clear(); var storageConnection = ConfigurationManager.AppSettings["AzureStorageConnectionString"]; var eventhubConnS = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString.Listen"]; Eventhubpath = ConfigurationManager.AppSettings["EventHubPath"]; var alarmQueueConnS = ConfigurationManager.AppSettings["ServiceBus.Queue.Connectionstring"]; var alarmQueueName = ConfigurationManager.AppSettings["ServiceBus.Queue.Name"]; WriteLineAndLog("Starting analyzer for hub: " + Eventhubpath); var alarmQueue = new ServiceBusConnection <AlarmMessage>(alarmQueueConnS, alarmQueueName); var alarmManger = new AlarmMessageManager(alarmQueue); var ruleStorage = new DocumentDBRuleStorage(ConfigurationManager.AppSettings["DocDBEndPointUrl"], ConfigurationManager.AppSettings["AuthorizationKey"], ConfigurationManager.AppSettings["RuleDatabaseId"], ConfigurationManager.AppSettings["RuleCollectionId"]); Engine = new AnalyzerEngine(); ServiceBusConnectionStringBuilder builder = new ServiceBusConnectionStringBuilder(eventhubConnS); builder.TransportType = TransportType.Amqp; var connection = new EventHubProcessor(builder.ToString(), Eventhubpath); WriteLineAndLog("Starting event receiver."); var recTask = connection.StartReceiver <EventProc>(storageConnection); recTask.Wait(); WriteLineAndLog("Receiver waiting."); var engineStartCounter = 0; var maxEngineRestarts = 10; try { new Thread(() => { Thread.CurrentThread.IsBackground = true; while (true) { if (!AwaitingInput) { Render(); Thread.Sleep(500); } } }).Start(); new Thread(() => { Thread.CurrentThread.IsBackground = true; while (true) { ParseInput(); } }).Start(); while (true) { MessageAggregator.Collection.Clear(); for (var i = 0; i < 500; ++i) { TimeStampedMessage <string> msg; if (Engine.EngineMessages.TryDequeue(out msg)) { MessageAggregator.AddMessage(msg, msg.Message.GenerateMessageIdentifierFromString()); } } foreach (var messageTracker in MessageAggregator.Collection) { MesseageOutputQueue.Enqueue($"{messageTracker.Value.Message} | {messageTracker.Value.AmountCounter} times from {messageTracker.Value.FirstOccurrence} to {messageTracker.Value.LastOccurrence}"); } if (Engine.State == State.ShuttingDown) { continue; } if (Engine.State == State.Stopped) { Engine.StartEngine(ruleStorage, alarmManger); if (maxEngineRestarts <= engineStartCounter++) { var message = $"AnalyserEngine main task has been restared {engineStartCounter - 1} times. Engine is down and can not recover! Resetting start counter."; Logger.AddRow(message); MesseageOutputQueue.Enqueue(message); var alarm = new AlarmMessage(AlarmLevel.High, AppDomain.CurrentDomain.FriendlyName, message); alarmManger.RaiseAlarm(alarm); engineStartCounter = 0; } } var timer = new Stopwatch(); timer.Start(); while (!Engine.EngineIsRunning && timer.ElapsedMilliseconds < 30000) { MesseageOutputQueue.Enqueue("Awaiting engine start. Waited " + timer.ElapsedMilliseconds + " ms"); Thread.Sleep(1000); } timer.Reset(); } } catch (Exception ex) { var alarm = new AlarmMessage(AlarmLevel.High, AppDomain.CurrentDomain.FriendlyName, $"Exception in main loop.", ex.Message); alarmManger.RaiseAlarm(alarm); WriteLineAndLog($"Exception in main loop."); WriteLineAndLog(ex.ToString()); } WriteLineAndLog("End of program."); }
public void Init(object me, int[] counts, int[] values, int max_rounds, LogDelegate log) { m_counts = counts; m_values = values; m_rounds = max_rounds * 2; m_log = log; m_maxIncome = 0; int count = 0; for (int i = 0; i < counts.Length; i++) { m_maxIncome += m_counts[i] * values[i]; count += m_counts[i]; } Generator generator = new Generator(m_counts, 1, count, m_maxIncome); int currentSet = -1; int currentValues = -1; for (int i = 0; i < generator.Combinations.Count; i++) { if (Utils.ArrayEquals(m_counts, generator.Combinations[i].Item1)) { currentSet = i; for (int j = 0; j < generator.Combinations[i].Item2.Length; j++) { if (Utils.ArrayEquals(generator.Combinations[i].Item2[j], m_values)) { currentValues = j; break; } } break; } } if (currentSet == -1 || currentValues == -1) { throw new HaggleException("Data and values not found in generated sets!"); } m_allValues = generator.Combinations[currentSet].Item2; m_myValuesIndex = currentValues; m_rejectedOffers = new CheckList <string>(); m_excludedValues = new CheckList <int>(); m_excludedValues.Add(currentValues); m_offers = AnalyzerEngine.FindBestOffers(m_counts, m_allValues, m_excludedValues, m_myValuesIndex); m_log(Utils.Format("I'm analyzer player {0}, {1}", AcceptThreshold, RejectThreshold)); #if LOG_OFFERS m_log("Initial list of offers"); for (int i = 0; i < m_offers.Length; i++) { m_log(Utils.Format("{0}: valid: {1}", m_offers[i], ValidOffer(m_offers[i], false))); } #endif #if DEBUG_RIG PrintStats(); #endif }
public bool CheckOffer(int[] offer, int turnsLeft) { // enemy would not offer me the items that could give him 9+ score, so let's remove them from the offer table { bool changed = false; for (int i = 0; i < m_allValues.Length; i++) { if (m_excludedValues.Contains(i)) { continue; } // enemy income for his offer (inverted counts) int income = AnalyzerEngine.CalculateIncomeForOffer(m_counts, m_allValues[i], offer, false); if (income >= m_maxIncome * RejectThreshold) // items enemy offered me would cost him 9-10, that is very unlikely { m_excludedValues.Add(i); changed = true; } // enemy income for items left to enemy int invIncome = AnalyzerEngine.CalculateIncomeForOffer(m_counts, m_allValues[i], offer, true); if (invIncome < m_maxIncome * MinEnemyIncomeThreshold) // items left to enemy would cost less then 2-3, that is definitelly not possible { m_excludedValues.Add(i); changed = true; } } if (changed) { m_offers = AnalyzerEngine.FindBestOffers(m_counts, m_allValues, m_excludedValues, m_myValuesIndex); #if DEBUG_RIG PrintStats(); #endif #if LOG_OFFERS m_log("Revised list of offers (according to enemy move)"); for (int i = 0; i < m_offers.Length; i++) { m_log(Utils.Format("{0}: valid: {1}", m_offers[i], ValidOffer(m_offers[i], false))); } #endif } } OfferHolder holder = AnalyzerEngine.TestOffer(m_counts, m_allValues, m_excludedValues, m_myValuesIndex, offer); if (holder == null) // should never happen now { m_log("!!!!Empty offer!!!!"); return(false); } m_log(Utils.Format("[{0}] Checking offer {1}", turnsLeft, holder)); if (holder.MyIncome >= m_maxIncome * AcceptThreshold) // always accept if we're given good option { return(true); } if (turnsLeft <= 1 && holder.MyIncome > 0) // French move ;) { m_log("I surrender! Give me at least " + holder.MyIncome); return(true); } if (!ValidOffer(holder, true)) { return(false); } if (m_lastOffer != null && holder.MyIncome >= m_lastOffer.MyIncome) // better than my current offer { return(true); } return(false); }
public OfferHolder MakeOffer(int turnsLeft) { OfferHolder selectedOffer = null; for (int i = 0; i < m_offers.Length; i++) { if (ValidOffer(m_offers[i], false)) { selectedOffer = m_offers[i]; break; } } if (m_greed) // greed guy does not want to make last offer { if (selectedOffer == null) // no offers left, stick with last one { selectedOffer = m_lastOffer; } } else { if (turnsLeft <= 2) { this.m_log("Making last offer!"); selectedOffer = null; for (var i = 0; i < this.m_offers.Length; i++) { if (this.m_offers[i].EnemyMedian > 0 && this.m_offers[i].EnemyAverage >= this.m_maxIncome * LastOfferThreshold && this.m_offers[i].MyIncome > 0) { return(this.m_offers[i]); } } } if (selectedOffer == null) // no offers left, try relaxed list { m_log("No meaninful offers left!"); for (int i = 0; i < m_offers.Length; i++) { if (this.m_offers[i].EnemyMedian > 0 && m_offers[i].EnemyAverage >= MinOfferThreshold * m_maxIncome && m_offers[i].MyIncome > 0 && !m_rejectedOffers.Contains(m_offers[i].OfferCode)) // relaxed check: not fairest option, but still good { selectedOffer = m_offers[i]; break; } } if (selectedOffer == null) // no offers left, stick with last one { m_log("No offers left and no relaxed found!"); selectedOffer = m_lastOffer; } } } m_rejectedOffers.Add(selectedOffer.OfferCode); m_lastOffer = selectedOffer; // if enemy rejected my offer, that means that his total for this offer never reached 9 or 10 bool changed = false; for (int i = 0; i < m_allValues.Length; i++) { if (m_excludedValues.Contains(i)) { continue; } int income = AnalyzerEngine.CalculateIncomeForOffer(m_counts, m_allValues[i], m_lastOffer.Offer, true); if (income >= m_maxIncome * RejectThreshold) { m_excludedValues.Add(i); changed = true; } } if (changed) { m_offers = AnalyzerEngine.FindBestOffers(m_counts, m_allValues, m_excludedValues, m_myValuesIndex); #if DEBUG_RIG PrintStats(); #endif #if LOG_OFFERS m_log("Revised list of offers (for next move)"); for (int i = 0; i < m_offers.Length; i++) { m_log(Utils.Format("{0}: valid: {1}", m_offers[i], ValidOffer(m_offers[i], false))); } #endif } return(selectedOffer); }