Program.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. namespace CricketDuck_Standard_CLI
  5. {
  6. class MainClass
  7. {
  8. public static string traceback = "";
  9. public static int Main (string[] args)
  10. {
  11. try
  12. {
  13. Console.Write("What is the G50 value? (Enter 245 if not sure.) ");
  14. int G50 = int.Parse(Console.ReadLine());
  15. Console.Write ("Number of overs in the first innings (before interruptions): ");
  16. string N = ReadOvers();
  17. if (!IsValidOverCount (N))
  18. throw new Exception ("Number of overs is invalid or too high.");
  19. double R1 = GetResources (N, 0);
  20. Console.Write("What was the first innings score? ");
  21. int S = int.Parse(Console.ReadLine());
  22. Console.Write ("Was the first innings interrupted? (y/N) ");
  23. if (Console.ReadLine ().ToLower () == "y") {
  24. Console.Write("When did this interruption occur? ");
  25. string interruption_time = ReadOvers();
  26. Console.Write("How many wickets had been lost at the time? ");
  27. int wickets_lost = int.Parse(Console.ReadLine());
  28. Console.Write("What was the new over count? ");
  29. string new_over_count = ReadOvers();
  30. double resources_lost = GetResources(SubtractOvers(N, interruption_time), wickets_lost) - GetResources(SubtractOvers(new_over_count, interruption_time), wickets_lost);
  31. R1 -= resources_lost;
  32. }
  33. Console.Write("How many overs did the team batting second have (prior to interruptions)? ");
  34. string N2 = ReadOvers();
  35. Console.WriteLine("Pick an option:");
  36. Console.WriteLine("[1] Calculate Par score.");
  37. Console.WriteLine("[2] Calculate second innings target.");
  38. switch(Console.ReadLine())
  39. {
  40. case "1":
  41. {
  42. Console.Write("When was the second innings interrupted? ");
  43. string second_interruption = ReadOvers();
  44. Console.Write("How many wickets had the team batting second lost at the time? ");
  45. int wickets_lost = int.Parse(Console.ReadLine());
  46. double R2 = GetResources(N2, 0) - GetResources(SubtractOvers(N2, second_interruption), wickets_lost);
  47. int newTarget = CalculateNewTarget(S, R1, R2, G50);
  48. Console.WriteLine("Team 2 needed " + newTarget + " to win or " + (newTarget - 1) + " to tie from " + second_interruption + " overs.");
  49. return 0;
  50. }
  51. case "2":
  52. {
  53. double R2 = GetResources(N2, 0);
  54. Console.Write("Was the second innings interrupted? (y/N) ");
  55. if(Console.ReadLine().ToLower() == "y")
  56. {
  57. Console.Write("How many overs had passed at the time of the interruption? ");
  58. string overs_remaining1 = SubtractOvers(N2, ReadOvers());
  59. Console.Write("How many wickets had been lost at the time? ");
  60. int wickets_lost = int.Parse(Console.ReadLine());
  61. Console.Write("What was the new over count after the interruption? ");
  62. string overs_remaining2 = ReadOvers();
  63. if(SubtractOvers(N2, overs_remaining2).Contains("-"))
  64. {
  65. throw new Exception("Revised over count cannot be above original over count.");
  66. }
  67. overs_remaining2 = SubtractOvers(overs_remaining2, SubtractOvers(N2, overs_remaining1));
  68. R2 -= GetResources(overs_remaining1, wickets_lost) - GetResources(overs_remaining2, wickets_lost);
  69. }
  70. int newTarget = CalculateNewTarget(S, R1, R2, G50);
  71. Console.WriteLine("Team 2 need " + newTarget + " to win or " + (newTarget - 1) + " to tie.");
  72. return 0;
  73. }
  74. default:
  75. {
  76. throw new Exception("Invalid option.");
  77. }
  78. }
  79. }
  80. catch(Exception e) {
  81. writeTraceback("At Main(string[]):");
  82. Console.Error.WriteLine ("Traceback (most recent call last):");
  83. Console.Error.Write (traceback.ToString());
  84. Console.Error.WriteLine ("Error: " + e.GetType () + " occurred.");
  85. Console.Error.WriteLine ("Description: " + e.Message);
  86. return -1;
  87. }
  88. }
  89. protected static double GetResources(string overs_remaining, int wickets_lost)
  90. {
  91. try
  92. {
  93. // Gets the resource percentage for a given number of overs remaining and wickets lost.
  94. using (Stream database = File.OpenRead(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly ().Location) + "/table_of_resources.csv"))
  95. using (StreamReader databaseReader = new StreamReader(database)) {
  96. return Parser.parseDouble (Grep (overs_remaining + "," + wickets_lost + ",", databaseReader).Replace (overs_remaining + "," + wickets_lost + ",", ""));
  97. }
  98. }
  99. catch(Exception e) {
  100. writeTraceback ("At GetResources(string, int):");
  101. throw e;
  102. }
  103. }
  104. private static string Grep(string s, StreamReader reader)
  105. {
  106. try
  107. {
  108. // Note: This is not suitable as a C# version of the Unix 'grep'. It is more of an implementation of 'grep -c 1'.
  109. while (!reader.EndOfStream) {
  110. string s2 = reader.ReadLine ();
  111. if (s2.StartsWith(s))
  112. return s2;
  113. }
  114. throw new EndOfStreamException ();
  115. }
  116. catch(Exception e) {
  117. writeTraceback ("At Grep(string, StreamReader):");
  118. throw e;
  119. }
  120. }
  121. protected static int CalculateNewTarget(int FirstInningsTotal, double R1, double R2, int G50)
  122. {
  123. try
  124. {
  125. // R1 is the resource percentage available to the team batting first.
  126. // R2 is the resource percentage available to the team batting second.
  127. if (R2 < R1) {
  128. return (int)((FirstInningsTotal * (R2 / R1)) + 1);
  129. } else if (R2 == R1) {
  130. return FirstInningsTotal + 1;
  131. } else if (R2 > R1) {
  132. return (int)Math.Ceiling(FirstInningsTotal + ((R2 - R1) * (G50/100d)) + 1);
  133. }
  134. throw new Exception ("An unknown error occurred while calculating the new target.");
  135. }
  136. catch(Exception e) {
  137. writeTraceback ("At CalculateNewTarget(int, double, double):");
  138. throw e;
  139. }
  140. }
  141. private static bool IsValidOverCount (string n)
  142. {
  143. try
  144. {
  145. double oversAsDouble = Parser.parseDouble(n);
  146. int oversAsInteger = (int)oversAsDouble;
  147. if(oversAsDouble != Math.Abs(oversAsDouble) || Math.Abs(oversAsDouble - oversAsInteger) > 0.6 || (oversAsDouble.ToString().Split('.').Length > 1 && oversAsDouble.ToString().Split('.')[1].Length > 1) || oversAsDouble > 50)
  148. {
  149. return false;
  150. }
  151. return true;
  152. }
  153. catch {
  154. return false;
  155. }
  156. }
  157. protected static string SubtractOvers(string minuend, string subtrahend)
  158. {
  159. try
  160. {
  161. if (!IsValidOverCount (minuend) || !IsValidOverCount (subtrahend))
  162. throw new FormatException ();
  163. int m_minuend = (int.Parse (minuend.Split ('.') [0]) * 6) + ((int)minuend.Split ('.') [1] [0] - 48);
  164. int m_subtrahend = (int.Parse (subtrahend.Split ('.') [0]) * 6) + ((int)subtrahend.Split ('.') [1] [0] - 48);
  165. return BallsToOvers (m_minuend - m_subtrahend);
  166. }
  167. catch(Exception e) {
  168. writeTraceback ("At SubtractOvers(string, string):");
  169. throw e;
  170. }
  171. }
  172. private static string BallsToOvers (int i)
  173. {
  174. try
  175. {
  176. return (int)(i / 6d) + "." + (i % 6);
  177. }
  178. catch(Exception e) {
  179. writeTraceback ("At BallsToOvers(int):");
  180. throw e;
  181. }
  182. }
  183. static void writeTraceback (string data)
  184. {
  185. traceback += " " + data + "\n";
  186. }
  187. public static string ReadOvers()
  188. {
  189. string s = Console.ReadLine ();
  190. return s.Contains (".") ? s : s + ".0";
  191. }
  192. }
  193. }