/// <summary> /// Internal helper method that returns a csv formatted line of profiling data. /// </summary> /// <param name="fxOrAi">tells whether the line of profiling data is for AI methods or framework methods.</param> /// <param name="info">the profiling data for all of the turns</param> /// <param name="currentKey">the method key to output the line of profiling data for</param> /// <param name="keyNames">all of the AI method names that map to the method keys</param> /// <param name="total">This contains the total number of method calls for all turns</param> /// <returns>a csv formatted line of profiling data</returns> private string WriteProfileLine(string fxOrAi, List <int[]> info, int currentKey, string[] keyNames, ref int total) { StringBuilder sb = new StringBuilder(); for (int curTurn = 0; curTurn < info.Count; curTurn++) { total += info[curTurn][currentKey]; sb.Append("\"" + string.Format("{0:N0}", info[curTurn][currentKey]) + "\","); } sb.Insert(0, "\"" + AIColor.ToString() + "\",\"" + fxOrAi + "\",\"" + keyNames[currentKey].ToString() + "\",\"" + string.Format("{0:N0}", total) + "\",\"" + string.Format("{0:N0}", ((decimal)total / (decimal)info.Count)) + "\","); // Trim off the trailing "," sb.Remove(sb.Length - 1, 1); return(sb.ToString()); }
/// <summary> /// Stops the AI profiling and compiles the profiling report. /// </summary> /// <returns>the profiling report as a list of strings</returns> internal List <string> WriteAndEndGame() { List <string> output = new List <string>(); if (IsEnabled) { if ((TagNames == null) || (TagNames.Length == 0)) { output.Add(this.AIColor.ToString() + ": To use the profiler, you must set Profiler.MethodNames to a list of enum names that you used with the integer keys"); } else { if (AIName != string.Empty) { output.Add("\"" + AIColor.ToString() + "'s AI Name:\",\"" + this.AIName + "\""); } output.Add("\"" + AIColor.ToString() + "'s Moves:\",\"" + this.Turns.Count + "\""); StringBuilder sb = new StringBuilder("\"Color\",\"Fx or AI\",\"Method Name\",\"Total\",\"Average\","); for (int ix = 1; ix <= Turns.Count; ix++) { sb.Append("\"Move " + ix + "\","); } // Trim off the trailing ", " sb.Remove(sb.Length - 1, 1); output.Add(sb.ToString()); if (MoveDepths.Count > 0) { sb = new StringBuilder(); int totalDepths = 0; for (int ix = 0; ix < MoveDepths.Count; ix++) { totalDepths += MoveDepths[ix]; sb.Append("\"" + MoveDepths[ix].ToString() + "\","); } int averageDepth = totalDepths / MoveTimes.Count; sb.Insert(0, "\"" + AIColor.ToString() + "\",\"AI\",\"Move Depths\",\"\",\"" + averageDepth + "\","); // Trim off the trailing "," sb.Remove(sb.Length - 1, 1); output.Add(sb.ToString()); } else { output.Add(AIColor.ToString() + "\",\"AI\",\"Move Depths\",\"Error: Set Profiler.Depth to get depth logging\""); } sb = new StringBuilder(); TimeSpan totalTime = new TimeSpan(); for (int ix = 0; ix < MoveTimes.Count; ix++) { totalTime += MoveTimes[ix]; sb.Append("\"" + MoveTimes[ix].ToString() + "\","); } TimeSpan averageTime = TimeSpan.FromMilliseconds((totalTime.TotalMilliseconds / MoveTimes.Count)); sb.Insert(0, "\"" + AIColor.ToString() + "\",\"AI\",\"Move Times\",\"" + totalTime + "\",\"" + averageTime + "\","); // Trim off the trailing "," sb.Remove(sb.Length - 1, 1); output.Add(sb.ToString()); int totalNodes = 0; for (int curProfiledMethod = 0; curProfiledMethod < TagNames.Length; curProfiledMethod++) { int total = 0; output.Add(WriteProfileLine("AI", Turns, curProfiledMethod, TagNames, ref total)); if ((MinisProfilerTag != -1) && (MaxsProfilerTag != -1) && ((MinisProfilerTag == curProfiledMethod) || (MaxsProfilerTag == curProfiledMethod))) { totalNodes += total; } } if (totalNodes > 0) { this.NodesPerSecond = ((double)totalNodes / totalTime.TotalSeconds); output.Insert(1, "\"" + AIColor.ToString() + "'s Nodes/Sec:\",\"" + string.Format("{0:N2}", this.NodesPerSecond) + "\""); } for (int curFxProfiledMethod = 0; curFxProfiledMethod < FxKeyNames.Length; curFxProfiledMethod++) { int total = 0; output.Add(WriteProfileLine("Fx", FxTurns, curFxProfiledMethod, FxKeyNames, ref total)); } } } return(output); }