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, int efGay)
  13. :base (hasDp, has4pc, executionTime, crit, haste, efGay)
  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. //1-2hp EF
  86. else if (EFGay > 0 && HolyPower >= EFGay)
  87. {
  88. CastEF();
  89. }
  90. //wait 1s for HS
  91. else if (HS.Time < 1)
  92. {
  93. CastNothing(HS.Time);
  94. }
  95. //HL filler least priority
  96. else
  97. {
  98. CastHL();
  99. }
  100. }
  101. }
  102.  
  103. public class Timer
  104. {
  105. public Timer(List<Timer> timers, double defaultTime)
  106. {
  107. _defaultTime = defaultTime;
  108. _active = false;
  109. _time = 0;
  110. timers.Add(this);
  111. }
  112. private bool _active;
  113. private double _time;
  114. private double _defaultTime;
  115.  
  116. public double Time
  117. {
  118. get
  119. {
  120. return _time;
  121. }
  122. }
  123. protected bool Active
  124. {
  125. get
  126. {
  127. return _active;
  128. }
  129. }
  130.  
  131. public void Set()
  132. {
  133. _time = _defaultTime;
  134. _active = true;
  135. }
  136.  
  137. public void Reset()
  138. {
  139. _active = false;
  140. _time = 0;
  141. }
  142.  
  143. public void Update(double time)
  144. {
  145. if(!_active) return;
  146. _time -= time;
  147. if(_time < Consts.eps) Reset();
  148. if (TimeoutHandler!=null) TimeoutHandler();
  149. }
  150.  
  151. public Action TimeoutHandler;
  152. }
  153.  
  154. public class Buff: Timer
  155. {
  156. public Buff(List<Timer> timers, double time): base(timers, time)
  157. {
  158.  
  159. }
  160.  
  161. public static implicit operator bool(Buff b)
  162. {
  163. return b.Active;
  164. }
  165. }
  166.  
  167. public class Cooldown: Timer
  168. {
  169. public Cooldown(List<Timer> timers, double time): base(timers, time)
  170. {
  171.  
  172. }
  173.  
  174. public static implicit operator bool(Cooldown cd)
  175. {
  176. return !cd.Active;
  177. }
  178. }
  179.  
  180. public class PaladinRotation
  181. {
  182. private List<Timer> _timers = new List<Timer>();
  183. private double _time = 0;
  184. private readonly double _maxTime;
  185. protected readonly Buff FreeEF;
  186. protected readonly Buff FreeLoD;
  187. protected readonly Buff DoubleHS;
  188. protected readonly Buff DP;
  189. protected readonly Buff IoL;
  190. protected readonly Cooldown HS;
  191. protected int HolyPower = 0;
  192. protected readonly bool Has4pc;
  193. protected readonly bool HasDP;
  194. protected readonly int EFGay;
  195. protected readonly double Crit;
  196. protected readonly double Haste;
  197. protected readonly double _hasteMult;
  198. private readonly Result _result = new Result();
  199.  
  200. public void CastHS()
  201. {
  202. if (!HS) throw new Exception("hs cd");
  203. if (DoubleHS)
  204. {
  205. DoubleHS.Reset();
  206. }
  207. else
  208. {
  209. HS.Set();
  210. }
  211. if (HolyPower < 5) HolyPower++;
  212. if (Roll(Crit * 2))
  213. {
  214. _result.HSCrits++;
  215. IoL.Set();
  216. }
  217. AddTime(Hasted(1.5));
  218. _result.HSCount++;
  219. }
  220.  
  221. public void CastHL()
  222. {
  223. if(IoL)
  224. {
  225. IoL.Reset();
  226. AddTime(Hasted(1));
  227. if (Roll(10)) DoubleHS.Set();
  228. AddTime(1 - Hasted(1));
  229. _result.IoLHL++;
  230. }
  231. else
  232. {
  233. if (Roll(10)) DoubleHS.Set();
  234. AddTime(Hasted(2.5));
  235. }
  236. _result.HLCount++;
  237. }
  238.  
  239. public void CastEF()
  240. {
  241. if (FreeEF && FreeEF.Time >= Hasted(1.5))
  242. {
  243. FreeEF.Reset();
  244. _result.EF3++;
  245. if (HasDP && Roll(25)) DP.Set();
  246. if (Has4pc && Roll(20)) FreeLoD.Set();
  247. }
  248. else if (DP && DP.Time >= Hasted(1.5))
  249. {
  250. DP.Reset();
  251. _result.EF3++;
  252. if (HasDP && Roll(25)) DP.Set();
  253. if (Has4pc && Roll(20)) FreeLoD.Set();
  254. }
  255. else if (HolyPower >= 3)
  256. {
  257. HolyPower -= 3;
  258. _result.EF3++;
  259. if (HasDP && Roll(25)) DP.Set();
  260. if (Has4pc && Roll(20)) FreeLoD.Set();
  261. }
  262. else if (EFGay > 0 && HolyPower >= EFGay)
  263. {
  264. switch(HolyPower)
  265. {
  266. case 1:
  267. _result.EF1++;
  268. if (HasDP && Roll(25/3.0)) DP.Set();
  269. if (Has4pc && Roll(20)) FreeLoD.Set();
  270. break;
  271. case 2:
  272. _result.EF2++;
  273. if (HasDP && Roll(25*2/3.0)) DP.Set();
  274. if (Has4pc && Roll(20)) FreeLoD.Set();
  275. break;
  276. default: throw new Exception("failed 1HP EF gay attempt"); break;
  277. }
  278. HolyPower = 0;
  279. }
  280. else
  281. {
  282. throw new Exception("1HP EF gay attempt");
  283. }
  284. AddTime(Hasted(1.5));
  285. _result.EFCount++;
  286. }
  287.  
  288. public void CastLoD()
  289. {
  290. if (FreeLoD && FreeLoD.Time >= Hasted(1.5))
  291. {
  292. FreeLoD.Reset();
  293. }
  294. else if (DP && DP.Time >= Hasted(1.5))
  295. {
  296. DP.Reset();
  297. }
  298. else if (HolyPower >= 3)
  299. {
  300. HolyPower -= 3;
  301. }
  302. else
  303. {
  304. throw new Exception("1HP LoD gay attempt");
  305. }
  306. AddTime(Hasted(1.5));
  307. if (HasDP && Roll(25)) DP.Set();
  308. if (Has4pc && Roll(25)) FreeEF.Set();
  309. _result.LoDCount++;
  310. }
  311.  
  312. public void CastNothing(double time)
  313. {
  314. AddTime(time);
  315. _result.WaitTime+=time;
  316. }
  317.  
  318. public bool Roll(double chance)
  319. {
  320. return RandomHelper.R.NextDouble() < chance / 100;
  321. }
  322.  
  323. public double Hasted(double time)
  324. {
  325. return time * _hasteMult;
  326. }
  327.  
  328. public PaladinRotation(bool hasDp, bool has4pc, double executionTime, double crit, double haste, int efGay)
  329. {
  330. HasDP = hasDp;
  331. Has4pc = has4pc;
  332. EFGay = efGay;
  333. _maxTime = executionTime;
  334. Crit = crit;
  335. Haste = haste;
  336. _hasteMult = 1 / (1 + Haste / 100);
  337. FreeEF = new Buff(_timers, 10);
  338. FreeLoD = new Buff(_timers, 10);
  339. DP = new Buff(_timers, 8);
  340. DoubleHS = new Buff(_timers, 15);
  341. IoL = new Buff(_timers, 15);
  342. HS = new Cooldown(_timers, Hasted(6));
  343. }
  344.  
  345. public void AddTime(double time)
  346. {
  347. if (time <= Consts.eps) throw new Exception("time interval " + time.ToString());
  348. foreach (var timer in _timers)
  349. {
  350. timer.Update(time);
  351. }
  352. _time += time;
  353. _result.TotalTime = _time;
  354. }
  355.  
  356. public virtual void Step()
  357. {
  358.  
  359. }
  360.  
  361. public Result Execute()
  362. {
  363. while(_time < _maxTime) Step();
  364. return _result;
  365. }
  366. }
  367.  
  368. public static class RandomHelper
  369. {
  370. public static void Init()
  371. {
  372. R = new Random();
  373. }
  374. public static Random R;
  375.  
  376. }
  377.  
  378. public class Result
  379. {
  380. public int LoDCount;
  381. public int EFCount;
  382. public int HSCount;
  383. public int HLCount;
  384. public double TotalTime;
  385. public double WaitTime;
  386. public int IoLHL;
  387. public int HSCrits;
  388. public int EF1;
  389. public int EF2;
  390. public int EF3;
  391.  
  392. public override string ToString()
  393. {
  394. return string.Format("LoD: {0}, EF: {1}, HS: {2}, HL: {3}", LoDCount, EFCount, HSCount, HLCount);
  395. }
  396. }
  397.  
  398. public class Test
  399. {
  400. public static void WriteResults(List<Result> results, double crit, double haste, double mastery)
  401. {
  402. var lods = results.Average(u=>u.LoDCount);
  403. var ef1 = results.Average(u=>u.EF1);
  404. var ef2 = results.Average(u=>u.EF2);
  405. var ef3 = results.Average(u=>u.EF3);
  406. var efs = ef3 + ef2*2/3.0 + ef1/3.0;
  407. var hss = results.Average(u=>u.HSCount);
  408. var hls = results.Average(u=>u.HLCount);
  409. var hscrits = results.Average(u=>u.HSCrits);
  410. var time = results.Average(u=>u.TotalTime);
  411. 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",
  412. results.Count,
  413. lods,
  414. efs,
  415. hss,
  416. hls,
  417. results.Average(u=>u.IoLHL),
  418. results.Average(u=>u.WaitTime)
  419. ));
  420. var mana = hss * 2352 + hls * 3300;
  421. Console.WriteLine(string.Format("EF1: {0:F1}, EF2: {1:F1}, EF3: {2:F1}, mana: {3:F0}", ef1, ef2, ef3, mana));
  422. var critmult = 1 + crit / 100;
  423. var lodheal = 7398*6;
  424. var hlheal = 25150;
  425. var hsheal = 11736;
  426. var efheal = 26619 + 1008*15*(1 + haste/100);
  427. var masterymult = mastery / 100;
  428. var healing = lods * (1 + 0.3*11/12.0 + masterymult) * critmult * lodheal +
  429. (hss + hscrits) * (1 + 1 + masterymult) * hsheal +
  430. hls * (1 + 1 + masterymult) * critmult * hlheal +
  431. efs * (1 + 1 + masterymult) * critmult * efheal;
  432.  
  433. var hps = healing / time;
  434. var hpm = healing / mana;
  435. Console.WriteLine(string.Format("hps: {0:F0}, hpm: {1:F2}", hps, hpm));
  436. }
  437.  
  438. public static void Main()
  439. {
  440. try
  441. {
  442. RandomHelper.Init();
  443. List<Result> results1 = new List<Result>();
  444. var crit = 25;
  445. var haste = 25;
  446. var mastery = 25;
  447.  
  448. Console.WriteLine ("10k iter, no DP, 4pc, 600s, 25% crit, 25% haste, no gay");
  449. for (int i=0; i<10000; i++)
  450. {
  451. var rotation = new MyRotation(false, true, 600, crit, haste, 0);
  452. var result = rotation.Execute();
  453. results1.Add(result);
  454. }
  455. WriteResults(results1, crit, haste, mastery);
  456.  
  457. results1 = new List<Result>();
  458.  
  459. Console.WriteLine ("10k iter, no DP, 4pc, 600s, 25% crit, 25% haste, 1hp gay");
  460. for (int i=0; i<10000; i++)
  461. {
  462. var rotation = new MyRotation(false, true, 600, crit, haste, 1);
  463. var result = rotation.Execute();
  464. results1.Add(result);
  465. }
  466. WriteResults(results1, crit, haste, mastery);
  467.  
  468. results1 = new List<Result>();
  469.  
  470. Console.WriteLine ("10k iter, no DP, 4pc, 600s, 25% crit, 25% haste, 2hp gay");
  471. for (int i=0; i<10000; i++)
  472. {
  473. var rotation = new MyRotation(false, true, 600, crit, haste, 2);
  474. var result = rotation.Execute();
  475. results1.Add(result);
  476. }
  477. WriteResults(results1, crit, haste, mastery);
  478. }
  479. catch (Exception ex)
  480. {
  481. Console.WriteLine(ex);
  482. }
  483. }
  484.  
  485. }
Success #stdin #stdout 4.93s 35208KB
stdin
Standard input is empty
stdout
10k iter, no DP, 4pc, 600s, 25% crit, 25% haste, no gay
iter: 10000 LoD: 9.3, EF: 46.6, HS: 134.1, HL: 202.7, IoLHL: 61.3, Time: 600.67s, Wait: 28.66s
EF1: 0.0, EF2: 0.0, EF3: 46.6, mana: 984278
hps: 43949, hpm: 26.82
10k iter, no DP, 4pc, 600s, 25% crit, 25% haste, 1hp gay
iter: 10000 LoD: 23.8, EF: 49.0, HS: 129.6, HL: 157.6, IoLHL: 60.8, Time: 600.80s, Wait: 19.06s
EF1: 97.9, EF2: 15.5, EF3: 6.0, mana: 824772
hps: 40882, hpm: 29.78
10k iter, no DP, 4pc, 600s, 25% crit, 25% haste, 2hp gay
iter: 10000 LoD: 12.8, EF: 47.2, HS: 132.8, HL: 192.4, IoLHL: 61.4, Time: 600.71s, Wait: 25.37s
EF1: 0.0, EF2: 51.1, EF3: 13.1, mana: 947503
hps: 43275, hpm: 27.44