fork(1) download
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4.  
  5. public static class Consts
  6. {
  7. public const double eps = 0.001;
  8. }
  9.  
  10. public class MyRotation: PaladinRotation
  11. {
  12. public MyRotation (bool hasDp, bool has4pc, double executionTime, double crit, double haste)
  13. :base (hasDp, has4pc, executionTime, crit, haste)
  14. {
  15.  
  16. }
  17.  
  18. public override void Step()
  19. {
  20. // buff expires soon
  21. if (FreeLoD && FreeLoD.Time <= Hasted(3))
  22. {
  23. CastLoD();
  24. }
  25. else if (DP && DP.Time <= Hasted(3))
  26. {
  27. CastLoD();
  28. }
  29. else if (FreeEF && FreeEF.Time <= Hasted(3))
  30. {
  31. CastEF();
  32. }
  33. //capped
  34. else if (HolyPower == 5)
  35. {
  36. CastLoD();
  37. }
  38. //HS
  39. else if (HS)
  40. {
  41. CastHS();
  42. }
  43. // buff expires soon if we wait 0.5s for HS
  44. else if (FreeLoD && FreeLoD.Time <= Hasted(3) + 0.5)
  45. {
  46. CastLoD();
  47. }
  48. else if (DP && DP.Time <= Hasted(3) + 0.5)
  49. {
  50. CastLoD();
  51. }
  52. else if (FreeEF && FreeEF.Time <= Hasted(3) + 0.5)
  53. {
  54. CastEF();
  55. }
  56. //wait 0.5s for HS
  57. else if (HS.Time < 0.5)
  58. {
  59. CastNothing(HS.Time);
  60. }
  61. //free casts
  62. else if (FreeLoD && FreeLoD.Time >= Hasted(1.5))
  63. {
  64. CastLoD();
  65. }
  66. else if (DP && DP.Time >= Hasted(1.5))
  67. {
  68. CastLoD();
  69. }
  70. else if (FreeEF && FreeEF.Time >= Hasted(1.5))
  71. {
  72. CastEF();
  73. }
  74. //3 hp LoD
  75. else if (HolyPower >= 3)
  76. {
  77. CastLoD();
  78. }
  79. //IoL HL
  80. else if (IoL)
  81. {
  82. CastHL();
  83. }
  84. //wait 1s for HS
  85. else if (HS.Time < 1)
  86. {
  87. CastNothing(HS.Time);
  88. }
  89. //HL filler least priority
  90. else
  91. {
  92. CastHL();
  93. }
  94. }
  95. }
  96.  
  97. public class Timer
  98. {
  99. public Timer(List<Timer> timers, double defaultTime)
  100. {
  101. _defaultTime = defaultTime;
  102. _active = false;
  103. _time = 0;
  104. timers.Add(this);
  105. }
  106. private bool _active;
  107. private double _time;
  108. private double _defaultTime;
  109.  
  110. public double Time
  111. {
  112. get
  113. {
  114. return _time;
  115. }
  116. }
  117. protected bool Active
  118. {
  119. get
  120. {
  121. return _active;
  122. }
  123. }
  124.  
  125. public void Set()
  126. {
  127. _time = _defaultTime;
  128. _active = true;
  129. }
  130.  
  131. public void Reset()
  132. {
  133. _active = false;
  134. _time = 0;
  135. }
  136.  
  137. public void Update(double time)
  138. {
  139. if(!_active) return;
  140. _time -= time;
  141. if(_time < Consts.eps) Reset();
  142. if (TimeoutHandler!=null) TimeoutHandler();
  143. }
  144.  
  145. public Action TimeoutHandler;
  146. }
  147.  
  148. public class Buff: Timer
  149. {
  150. public Buff(List<Timer> timers, double time): base(timers, time)
  151. {
  152.  
  153. }
  154.  
  155. public static implicit operator bool(Buff b)
  156. {
  157. return b.Active;
  158. }
  159. }
  160.  
  161. public class Cooldown: Timer
  162. {
  163. public Cooldown(List<Timer> timers, double time): base(timers, time)
  164. {
  165.  
  166. }
  167.  
  168. public static implicit operator bool(Cooldown cd)
  169. {
  170. return !cd.Active;
  171. }
  172. }
  173.  
  174. public class PaladinRotation
  175. {
  176. private List<Timer> _timers = new List<Timer>();
  177. private double _time = 0;
  178. private readonly double _maxTime;
  179. protected readonly Buff FreeEF;
  180. protected readonly Buff FreeLoD;
  181. protected readonly Buff DoubleHS;
  182. protected readonly Buff DP;
  183. protected readonly Buff IoL;
  184. protected readonly Cooldown HS;
  185. protected int HolyPower = 0;
  186. protected readonly bool Has4pc;
  187. protected readonly bool HasDP;
  188. protected readonly double Crit;
  189. protected readonly double Haste;
  190. protected readonly double _hasteMult;
  191. private readonly Result _result = new Result();
  192.  
  193. public void CastHS()
  194. {
  195. if (!HS) throw new Exception("hs cd");
  196. if (DoubleHS)
  197. {
  198. DoubleHS.Reset();
  199. }
  200. else
  201. {
  202. HS.Set();
  203. }
  204. if (HolyPower < 5) HolyPower++;
  205. if (Roll(Crit * 2)) IoL.Set();
  206. AddTime(Hasted(1.5));
  207. _result.HSCount++;
  208. }
  209.  
  210. public void CastHL()
  211. {
  212. if(IoL)
  213. {
  214. IoL.Reset();
  215. AddTime(Hasted(1));
  216. if (Roll(10)) DoubleHS.Set();
  217. AddTime(1 - Hasted(1));
  218. _result.IoLHL++;
  219. }
  220. else
  221. {
  222. if (Roll(10)) DoubleHS.Set();
  223. AddTime(Hasted(2.5));
  224. }
  225. _result.HLCount++;
  226. }
  227.  
  228. public void CastEF()
  229. {
  230. if (FreeEF && FreeEF.Time >= Hasted(1.5))
  231. {
  232. FreeEF.Reset();
  233. }
  234. else if (DP && DP.Time >= Hasted(1.5))
  235. {
  236. DP.Reset();
  237. }
  238. else if (HolyPower >= 3)
  239. {
  240. HolyPower -= 3;
  241. }
  242. else
  243. {
  244. throw new Exception("1HP EF gay attempt");
  245. }
  246. AddTime(Hasted(1.5));
  247. if (HasDP && Roll(25)) DP.Set();
  248. if (Has4pc && Roll(20)) FreeLoD.Set();
  249. _result.EFCount++;
  250. }
  251.  
  252. public void CastLoD()
  253. {
  254. if (FreeLoD && FreeLoD.Time >= Hasted(1.5))
  255. {
  256. FreeLoD.Reset();
  257. }
  258. else if (DP && DP.Time >= Hasted(1.5))
  259. {
  260. DP.Reset();
  261. }
  262. else if (HolyPower >= 3)
  263. {
  264. HolyPower -= 3;
  265. }
  266. else
  267. {
  268. throw new Exception("1HP LoD gay attempt");
  269. }
  270. AddTime(Hasted(1.5));
  271. if (HasDP && Roll(25)) DP.Set();
  272. if (Has4pc && Roll(25)) FreeEF.Set();
  273. _result.LoDCount++;
  274. }
  275.  
  276. public void CastNothing(double time)
  277. {
  278. AddTime(time);
  279. _result.WaitTime+=time;
  280. }
  281.  
  282. public bool Roll(double chance)
  283. {
  284. return RandomHelper.R.NextDouble() < chance / 100;
  285. }
  286.  
  287. public double Hasted(double time)
  288. {
  289. return time * _hasteMult;
  290. }
  291.  
  292. public PaladinRotation(bool hasDp, bool has4pc, double executionTime, double crit, double haste)
  293. {
  294. HasDP = hasDp;
  295. Has4pc = has4pc;
  296. _maxTime = executionTime;
  297. Crit = crit;
  298. Haste = haste;
  299. _hasteMult = 1 / (1 + Haste / 100);
  300. FreeEF = new Buff(_timers, 10);
  301. FreeLoD = new Buff(_timers, 10);
  302. DP = new Buff(_timers, 8);
  303. DoubleHS = new Buff(_timers, 15);
  304. IoL = new Buff(_timers, 15);
  305. HS = new Cooldown(_timers, Hasted(6));
  306. }
  307.  
  308. public void AddTime(double time)
  309. {
  310. if (time <= Consts.eps) throw new Exception("time interval " + time.ToString());
  311. foreach (var timer in _timers)
  312. {
  313. timer.Update(time);
  314. }
  315. _time += time;
  316. _result.TotalTime = _time;
  317. }
  318.  
  319. public virtual void Step()
  320. {
  321.  
  322. }
  323.  
  324. public Result Execute()
  325. {
  326. while(_time < _maxTime) Step();
  327. return _result;
  328. }
  329. }
  330.  
  331. public static class RandomHelper
  332. {
  333. public static void Init()
  334. {
  335. R = new Random();
  336. }
  337. public static Random R;
  338.  
  339. }
  340.  
  341. public class Result
  342. {
  343. public int LoDCount;
  344. public int EFCount;
  345. public int HSCount;
  346. public int HLCount;
  347. public double TotalTime;
  348. public double WaitTime;
  349. public int IoLHL;
  350.  
  351. public override string ToString()
  352. {
  353. return string.Format("LoD: {0}, EF: {1}, HS: {2}, HL: {3}", LoDCount, EFCount, HSCount, HLCount);
  354. }
  355. }
  356.  
  357. public class Test
  358. {
  359. public static void WriteResults(List<Result> results)
  360. {
  361. Console.WriteLine(string.Format("iter: {0} LoD: {1:F1}, EF: {2:F1}, HS: {3:F1}, HL: {4:F1}, IoLHL: {5:F1}, Time: {6:F2}s, Wait: {7:F2}s",
  362. results.Count,
  363. results.Average(u=>u.LoDCount),
  364. results.Average(u=>u.EFCount),
  365. results.Average(u=>u.HSCount),
  366. results.Average(u=>u.HLCount),
  367. results.Average(u=>u.IoLHL),
  368. results.Average(u=>u.TotalTime),
  369. results.Average(u=>u.WaitTime)
  370. ));
  371. }
  372.  
  373. public static void Main()
  374. {
  375. try
  376. {
  377. RandomHelper.Init();
  378. List<Result> results1 = new List<Result>();
  379. List<Result> results2 = new List<Result>();
  380. List<Result> results3 = new List<Result>();
  381. List<Result> results4 = new List<Result>();
  382.  
  383. Console.WriteLine ("10k iter, no DP, no 4pc, 600s, 25% crit, 25% haste");
  384. for (int i=0; i<10000; i++)
  385. {
  386. var rotation = new MyRotation(false, false, 600, 25, 25);
  387. var result = rotation.Execute();
  388. results1.Add(result);
  389. }
  390. WriteResults(results1);
  391.  
  392. Console.WriteLine ("10k iter, DP, no 4pc, 600s, 25% crit, 25% haste");
  393. for (int i=0; i<10000; i++)
  394. {
  395. var rotation = new MyRotation(true, false, 600, 25, 25);
  396. var result = rotation.Execute();
  397. results2.Add(result);
  398. }
  399. WriteResults(results2);
  400.  
  401. Console.WriteLine ("10k iter, no DP, 4pc, 600s, 25% crit, 25% haste");
  402. for (int i=0; i<10000; i++)
  403. {
  404. var rotation = new MyRotation(false, true, 600, 25, 25);
  405. var result = rotation.Execute();
  406. results3.Add(result);
  407. }
  408. WriteResults(results3);
  409.  
  410. Console.WriteLine ("10k iter, DP, 4pc, 600s, 25% crit, 25% haste");
  411. for (int i=0; i<10000; i++)
  412. {
  413. var rotation = new MyRotation(true, true, 600, 25, 25);
  414. var result = rotation.Execute();
  415. results4.Add(result);
  416. }
  417. WriteResults(results4);
  418.  
  419.  
  420.  
  421. }
  422. catch (Exception ex)
  423. {
  424. Console.WriteLine(ex);
  425. }
  426. }
  427.  
  428. }
Success #stdin #stdout 6.61s 37328KB
stdin
Standard input is empty
stdout
10k iter, no DP, no 4pc, 600s, 25% crit, 25% haste
iter: 10000 LoD: 44.4, EF: 0.0, HS: 134.4, HL: 209.5, IoLHL: 61.9, Time: 600.68s, Wait: 29.05s
10k iter, DP, no 4pc, 600s, 25% crit, 25% haste
iter: 10000 LoD: 59.0, EF: 0.0, HS: 134.0, HL: 200.9, IoLHL: 61.2, Time: 600.67s, Wait: 28.45s
10k iter, no DP, 4pc, 600s, 25% crit, 25% haste
iter: 10000 LoD: 46.5, EF: 11.6, HS: 134.0, HL: 201.5, IoLHL: 61.4, Time: 600.67s, Wait: 28.46s
10k iter, DP, 4pc, 600s, 25% crit, 25% haste
iter: 10000 LoD: 67.7, EF: 15.5, HS: 133.5, HL: 186.2, IoLHL: 58.6, Time: 600.66s, Wait: 26.82s