public Play GetDecision(DecisionRequest currentDecision, InfoCollection infoStore) { //this.playerId = playerId; //this.aiConfigStr = aiConfigStr; //this.cache = genericGameCache; this.currentDecision = currentDecision; this.infoStore = infoStore; //Set the random seed value here if (aiRandomControl.DecisionRandomPerHandSeedEnabled) { //decimal distanceToDealer = (infoStore.GetInfoValue(InfoType.GP_DealerDistance_Byte) - 1) / (infoStore.GetInfoValue(InfoType.GP_NumActivePlayers_Byte) - 1); //decimal currentWinPercentage = infoStore.GetInfoValue(InfoType.WR_CardsOnlyWinPercentage); //decimal currentPotValue = infoStore.GetInfoValue(InfoType.BP_TotalPotAmount_Decimal); var hashFunc = new Func <long, long>((long key) => { key = (~key) + (key << 21); // key = (key << 21) - key - 1; key = key ^ (key >> 24); key = (key + (key << 3)) + (key << 8); // key * 265 key = key ^ (key >> 14); key = (key + (key << 2)) + (key << 4); // key * 21 key = key ^ (key >> 28); key = key + (key << 31); return(key); }); //long randomSeed = hashFunc((long)(7919 * (distanceToDealer + 1))) ^ // hashFunc((long)(currentWinPercentage * 100)) ^ // hashFunc((long)(currentPotValue * 991)) ^ // hashFunc(1 + currentDecision.Cache.getNumHandsPlayed()); //(randomGen as CMWCRandom).ReSeed(randomSeed); //We can now seed based on the table and hand random number (randomGen as CMWCRandom).ReSeed((long)(currentDecision.Cache.TableRandomNumber ^ hashFunc(currentDecision.Cache.CurrentHandRandomNumber()) ^ hashFunc(1 + currentDecision.Cache.getCurrentHandSeqIndex()))); } //Validate the decision and then set the decision time if currently 0. return(GetDecision()); }
private int DetermineAvailableInstance(DecisionRequest newRequest) { int selectedInstanceIndex; int availableInstances; int indexAvailableMask; selectedInstanceIndex = -1; lock (instanceSelector.locker) { availableInstances = instanceSelector.instancesIdle & int.MaxValue; if (availableInstances > 0) { indexAvailableMask = 1; selectedInstanceIndex = 0; while (true) { if ((availableInstances & indexAvailableMask) > 0) { instanceSelector.instancesIdle = instanceSelector.instancesIdle ^ indexAvailableMask; break; } else if (selectedInstanceIndex > aiInstanceList.Count) { throw new Exception("Loop error!"); } selectedInstanceIndex++; indexAvailableMask = indexAvailableMask << 1; } } else { lock (decisionRequestQueue.SyncRoot) decisionRequestQueue.Enqueue(newRequest); } } return(selectedInstanceIndex); }
public virtual void PrepareAIForDecision(DecisionRequest currentDecision) { this.currentDecision = currentDecision; this.currentDecision.RequiredInfoTypeUpdateKey = GetUpdateKeyOrPreDecision(); this.currentDecision.RequiredInfoTypeUpdateConfigs = GetInfoUpdateConfigs(); }
/// <summary> /// Initiaties a decision but overrides the player config using the specified serverType and configStr /// </summary> /// <param name="handId"></param> /// <param name="playerId"></param> /// <param name="genericGameCache"></param> /// <returns></returns> public Play GetDecision(long playerId, databaseCache genericGameCache, AIGeneration serverType, string aiConfigStr) { try { //Sort out the cacheTracker CacheTracker.Instance.Update(playerId, genericGameCache); if (serverType == AIGeneration.Undefined || aiConfigStr == null) { CacheTracker.Instance.PlayerAiConfig(playerId, genericGameCache.TableId, out serverType, out aiConfigStr); } DecisionRequest newRequest = new DecisionRequest(playerId, genericGameCache, serverType, aiConfigStr, AIManager.RunInSafeMode); PreDecisionErrorChecking(newRequest.PlayerId, newRequest.Cache); //For now we will just use the old method //Determine an available AIInstance int selectedInstanceIndex = DetermineAvailableInstance(newRequest); //This could be done in a seperate thread if (selectedInstanceIndex == -1) { //There were no available instances so we join the queue and wait newRequest.WaitForDecision(); } else { if (ConcurrencyMode.Concurrency == ConcurrencyMode.ConcurencyModel.MultiCore) { Task t = Task.Factory.StartNew(aiInstanceList[selectedInstanceIndex].HandleDecisionRequest, newRequest); t.Wait(); } else { aiInstanceList[selectedInstanceIndex].HandleDecisionRequest(newRequest); } } Play aiAction = newRequest.DecisionPlay; aiAction = SetDecisionTime(ValidatePlayerDecision(aiAction, newRequest.Cache)); return(aiAction); } catch (Exception ex) { instanceSelector.instancesIdle = 0; for (int i = 0; i < aiInstanceList.Count; i++) { instanceSelector.instancesIdle = instanceSelector.instancesIdle | (1 << i); } genericGameCache.readLockCounter = 0; string fileName = LogError.Log(ex, "PokerAIError"); genericGameCache.SaveToDisk("", fileName); return(new Play(PokerAction.GeneralAIError, 0, 0, genericGameCache.getCurrentHandId(), playerId, ex.ToString(), 3)); } throw new Exception("This point should never be reached."); }
public void HandleDecisionRequest(object decisionRequestObject) { currentDecision = decisionRequestObject as DecisionRequest; //Pick that aiServer from the available list //Multiple threads can be accessing this list as it is only returning an object //If the AIserver is not found we catch in the below exception and all hell breaks loose with errors!! if (AIManager.RunInSafeMode) { if (!aiDictList.ContainsKey(currentDecision.ServerType)) { throw new Exception("Required AI not added to AI list."); } } //This gives the AI the starting config information as well as sets the first level aiDictList[currentDecision.ServerType].PrepareAIForDecision(currentDecision); //It's possible we have set the decision already in PrepareAIForDecision() if (currentDecision.DecisionPlay == null) { if (!taskTrees.ContainsKey(currentDecision.RequiredInfoTypeUpdateKey)) { taskTrees.Add(currentDecision.RequiredInfoTypeUpdateKey, new InfoProviderTaskTree(currentDecision.RequiredInfoTypeUpdateKey, infoProviderDictList)); } selectedTaskTree = taskTrees[currentDecision.RequiredInfoTypeUpdateKey]; currentDecision.RequiredInfoTypeUpdateKey = selectedTaskTree.ActualKey; UpdateProviders(); //In the future when we move to decision levels this area of the AIInstance is going to change to //Get required info types //Update Providers //Get decision //If decision is noAction go to the next step //Get required info types //Update providers //Get decision etc etc etc Play aiAction = aiDictList[currentDecision.ServerType].GetDecision(currentDecision, infoStore); currentDecision.SetDecision(aiAction); } lock (instanceSelector.locker) { lock (decisionRequestQueue.SyncRoot) { if (decisionRequestQueue.Count == 0) { instanceSelector.instancesIdle = instanceSelector.instancesIdle | (1 << instanceNumber); return; } else { this.currentDecision = decisionRequestQueue.Dequeue() as DecisionRequest; Task.Factory.StartNew(HandleDecisionRequest, currentDecision); return; } } } }