private async Task TreeStrapAsync(GameBoard gameBoard, int maxDepth, TimeSpan maxTime, int maxHelperThreads, CancellationToken token) { if (null == gameBoard) { throw new ArgumentNullException(nameof(gameBoard)); } if (maxDepth < 0) { throw new ArgumentOutOfRangeException("maxDepth"); } if (maxTime < TimeSpan.Zero) { throw new ArgumentOutOfRangeException("maxTime"); } if (maxHelperThreads < 0) { throw new ArgumentOutOfRangeException("maxHelperThreads"); } // Make sure we have a clean state ResetCaches(); List <ulong> boardKeys = new List <ulong>(); while (gameBoard.GameInProgress) { if (token.IsCancellationRequested) { break; } boardKeys.Add(gameBoard.ZobristKey); if (boardKeys.Count >= 6) { int lastIndex = boardKeys.Count - 1; if (boardKeys[lastIndex] == boardKeys[lastIndex - 4] && boardKeys[lastIndex - 1] == boardKeys[lastIndex - 5]) { // We're in a loop, exit now break; } } CancellationTokenSource searchCancelationToken = new CancellationTokenSource(); if (maxTime < TimeSpan.MaxValue) { searchCancelationToken.CancelAfter(maxTime); } // Get best move Move bestMove = await GetBestMoveAsync(gameBoard, maxDepth, maxTime, maxHelperThreads, searchCancelationToken.Token); HashSet <ulong> visitedKeys = new HashSet <ulong>(); DeltaFromTransTable(gameBoard, visitedKeys, token, out MetricWeights deltaStart, out MetricWeights deltaEnd); // Update metric weights with delta StartMetricWeights.Add(deltaStart); EndMetricWeights.Add(deltaEnd); // Play best move and reset caches gameBoard.TrustedPlay(bestMove); ResetCaches(); } }
public void WriteXml(Stream outputStream) { if (null == outputStream) { throw new ArgumentNullException(nameof(outputStream)); } XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) { writer.WriteStartElement("Profile"); writer.WriteStartElement("Id"); writer.WriteValue(Id.ToString()); writer.WriteEndElement(); if (!string.IsNullOrWhiteSpace(_name)) { writer.WriteStartElement("Name"); writer.WriteValue(_name.Trim()); writer.WriteEndElement(); } writer.WriteStartElement("Generation"); writer.WriteValue(Generation); writer.WriteEndElement(); if (ParentA.HasValue) { writer.WriteStartElement("ParentA"); writer.WriteValue(ParentA.ToString()); writer.WriteEndElement(); } if (ParentB.HasValue) { writer.WriteStartElement("ParentB"); writer.WriteValue(ParentB.ToString()); writer.WriteEndElement(); } writer.WriteStartElement("Records"); for (int i = 0; i < Records.Length; i++) { writer.WriteStartElement("Record"); writer.WriteAttributeString("GameType", EnumUtils.GetExpansionPiecesString((ExpansionPieces)i)); writer.WriteAttributeString("EloRating", Records[i].EloRating.ToString()); writer.WriteAttributeString("Wins", Records[i].Wins.ToString()); writer.WriteAttributeString("Losses", Records[i].Losses.ToString()); writer.WriteAttributeString("Draws", Records[i].Draws.ToString()); writer.WriteAttributeString("AutoTrains", Records[i].AutoTrains.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("Creation"); writer.WriteValue(CreationTimestamp); writer.WriteEndElement(); writer.WriteStartElement("LastUpdated"); writer.WriteValue(LastUpdatedTimestamp); writer.WriteEndElement(); StartMetricWeights.WriteMetricWeightsXml(writer, "StartMetricWeights"); EndMetricWeights.WriteMetricWeightsXml(writer, "EndMetricWeights"); writer.WriteEndElement(); // </Profile> } }
public void WriteXml(Stream outputStream) { if (null == outputStream) { throw new ArgumentNullException("outputStream"); } XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) { writer.WriteStartElement("Profile"); writer.WriteStartElement("Id"); writer.WriteValue(Id.ToString()); writer.WriteEndElement(); if (!string.IsNullOrWhiteSpace(_name)) { writer.WriteStartElement("Name"); writer.WriteValue(_name.Trim()); writer.WriteEndElement(); } writer.WriteStartElement("Generation"); writer.WriteValue(Generation); writer.WriteEndElement(); if (ParentA.HasValue) { writer.WriteStartElement("ParentA"); writer.WriteValue(ParentA.ToString()); writer.WriteEndElement(); } if (ParentB.HasValue) { writer.WriteStartElement("ParentB"); writer.WriteValue(ParentB.ToString()); writer.WriteEndElement(); } writer.WriteStartElement("EloRating"); writer.WriteValue(EloRating); writer.WriteEndElement(); writer.WriteStartElement("Wins"); writer.WriteValue(Wins); writer.WriteEndElement(); writer.WriteStartElement("Losses"); writer.WriteValue(Losses); writer.WriteEndElement(); writer.WriteStartElement("Draws"); writer.WriteValue(Draws); writer.WriteEndElement(); writer.WriteStartElement("Creation"); writer.WriteValue(CreationTimestamp); writer.WriteEndElement(); writer.WriteStartElement("LastUpdated"); writer.WriteValue(LastUpdatedTimestamp); writer.WriteEndElement(); writer.WriteStartElement("StartMetricWeights"); MetricWeights.IterateOverWeights((bugType, bugTypeWeight) => { string key = MetricWeights.GetKeyName(bugType, bugTypeWeight); double value = StartMetricWeights.Get(bugType, bugTypeWeight); writer.WriteStartElement(key); writer.WriteValue(value); writer.WriteEndElement(); }); writer.WriteEndElement(); // </StartMetricWeights> writer.WriteStartElement("EndMetricWeights"); MetricWeights.IterateOverWeights((bugType, bugTypeWeight) => { string key = MetricWeights.GetKeyName(bugType, bugTypeWeight); double value = EndMetricWeights.Get(bugType, bugTypeWeight); writer.WriteStartElement(key); writer.WriteValue(value); writer.WriteEndElement(); }); writer.WriteEndElement(); // </EndMetricWeights> writer.WriteEndElement(); // </Profile> } }