/
Reportutil.cs
131 lines (112 loc) · 4.34 KB
/
Reportutil.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using System.Linq;
using SparkNet;
using static coil.Coilutil;
using static coil.Solverutil;
namespace coil
{
public static class Reportutil
{
public class ReportData
{
public ReportData() { }
public int sqs;
public int decisionCount;
public double divergence;
public double easyDecisionPercent;
public double hardDecisionPercent;
public double tweakSuccessPercent;
public double coveragePercent;
public string lcStr;
public double totalSeconds;
public int segCount;
public string levelSize;
public double avgNeighborCount;
public double avgSegLen;
}
public static string Report(ReportData data, bool multiline = false)
{
var linebreak = "";
if (multiline)
{
linebreak = "\n";
}
return $"{data.lcStr} {data.totalSeconds.ToString("0.0")}s {linebreak}" +
$"segs{data.segCount} cov{data.coveragePercent.ToString("##0.0")}% " +
$"dec{data.easyDecisionPercent.ToString("0.0")}/{data.hardDecisionPercent.ToString("0.0")}% {linebreak}" +
$"{data.levelSize} div={data.divergence} nei={data.avgNeighborCount.ToString("0.0")} asl{data.avgSegLen.ToString("0.0")} {linebreak}"+
$"{data.tweakSuccessPercent.ToString("##0.0")}%";
}
public static double GetCoveragePercent(Level level, out int sqs)
{
sqs = (level.Height - 2) * (level.Width - 2);
var sum = 1;
foreach (var seg in level.Segs)
{
sum += seg.Len;
}
var coveragePercent = 100.0 * sum / sqs;
return coveragePercent;
}
public static ReportData GetReport(Level level, TimeSpan ts, TweakStats tweakStats = null)
{
var res = new ReportData();
res.lcStr = level.LevelConfiguration.GetStr();
res.totalSeconds = ts.TotalSeconds;
res.segCount = level.Segs.Count;
res.levelSize = $"{level.Width - 2}x{level.Height - 2}";
var decisions = GetDecisions(level);
//hard decisions not done yet. doable now.
var easyDecisions = decisions.Item1;
var hardDecisions = decisions.Item2;
res.decisionCount = easyDecisions.Count + hardDecisions.Count;
res.coveragePercent = GetCoveragePercent(level, out int sqs);
res.sqs = sqs;
res.hardDecisionPercent = hardDecisions.Count * 1.0 / sqs * 100;
res.easyDecisionPercent = easyDecisions.Count * 1.0 / sqs * 100;
//Divergence = per seg, how distant other segs does it see?
//problem - this prioritizes long paths.
res.divergence = GetDivergence(level);
res.avgNeighborCount = GetAvgNeighborCount(level);
res.avgSegLen = GetAvgSegLen(level);
var tweakTrySum = (tweakStats.SuccessCt + tweakStats.NoTweaks + tweakStats.NoTweaksQualify);
var tweakSuccessPercent = tweakStats.SuccessCt * 100.0 / tweakTrySum;
res.tweakSuccessPercent = tweakSuccessPercent;
//TODO it would be cool to sparkline render various things like periodic segment length.
return res;
}
/// <summary>
/// for ever
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
public static double GetDivergence(Level level)
{
return 0;
}
/// <summary>
/// for ever
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
public static double GetAvgNeighborCount(Level level)
{
var tot = 0;
foreach (var seg in level.Segs)
{
var neighbors = GetNeighboringSegs(level, seg);
tot += neighbors.Count;
}
return tot * 1.0 / level.Segs.Count;
}
public static double GetAvgSegLen(Level level)
{
var tot = 0;
foreach (var seg in level.Segs)
{
tot += seg.Len;
}
return tot * 1.0 / level.Segs.Count;
}
}
}