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