PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/JTacticalSim.Console/BaseConsoleIOHandler.cs

https://github.com/Queztionmark/JTacticalSim
C# | 498 lines | 380 code | 97 blank | 21 comment | 50 complexity | 497f200ec1aa8c102efc523258f79088 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using JTacticalSim.API;
  7. using JTacticalSim.API.Component;
  8. using JTacticalSim.API.DTO;
  9. using JTacticalSim.API.Game;
  10. using JTacticalSim.API.Service;
  11. using JTacticalSim.Utility;
  12. namespace JTacticalSim.Console
  13. {
  14. public abstract class BaseConsoleIOHandler
  15. {
  16. protected ParsedCommandArgs _commandArgs;
  17. protected bool _inputError = false;
  18. protected IGame _theGame { get; set; }
  19. protected BaseConsoleIOHandler(IGame theGame)
  20. {
  21. _theGame = theGame;
  22. }
  23. #region Public Virtual Methods
  24. public virtual void SetInputError(string error)
  25. {
  26. _inputError = true;
  27. _theGame.Renderer.HandleErrorUI(error, null);
  28. }
  29. public virtual void RenderBoard()
  30. {
  31. // Enter main game sate
  32. // The statechanged event handler will call the state renderer (board in this case)
  33. _theGame.StateSystem.ChangeState(StateType.GAME_IN_PLAY);
  34. }
  35. public virtual void RefreshScreen()
  36. {
  37. _theGame.StateSystem.Render();
  38. }
  39. public virtual void GetCommandInput(ICommandInterface ci)
  40. { throw new NotImplementedException();}
  41. #endregion
  42. protected virtual void DrawLine()
  43. {
  44. System.Console.Write("________________________________________________________");
  45. }
  46. protected virtual void RunCommand(ICommandInterface ci)
  47. {
  48. _inputError = false;
  49. var commands = CommandInterface.GetInputCommandMethods(_theGame.StateSystem.CurrentStateType);
  50. // Allow for the name and alias
  51. var dictItem = commands.SingleOrDefault(kvp => (kvp.Key.CommandName.ToLowerInvariant() == _commandArgs.Command.ToLowerInvariant()) ||
  52. kvp.Key.Alias.ToLowerInvariant() == _commandArgs.Command.ToLowerInvariant());
  53. // We found the command
  54. if (dictItem.Key != null && dictItem.Value != null)
  55. {
  56. dictItem.Value.Invoke(ci, null);
  57. if (dictItem.Key.RefreshScreen && !_inputError)
  58. RefreshScreen();
  59. return;
  60. }
  61. // No command found
  62. System.Console.ForegroundColor = ConsoleColor.Red;
  63. System.Console.WriteLine("Command not recognized");
  64. System.Console.ResetColor();
  65. }
  66. protected virtual void ParseCommandArgs(string command)
  67. {
  68. // Get all args. Skip the command text
  69. string[] tmp = command.Split(' ').ToArray();
  70. _commandArgs.Command = tmp.First();
  71. _commandArgs.Args = tmp.Skip(1).Where(arg => !arg.Contains("--")).ToArray();
  72. _commandArgs.Switches = tmp.Skip(1).Where(arg => arg.Contains("--")).ToList();
  73. _commandArgs.Cancel = (tmp.Any(i => i.ToLowerInvariant() == "cancel"));
  74. _commandArgs.Switches.ForEach(arg => arg.ToLowerInvariant());
  75. }
  76. protected virtual bool IsValidRow(string input)
  77. {
  78. int intVal;
  79. if (!CommandLineUtil.ConsoleUtils.IsValidateNumericInput(input))
  80. {
  81. SetInputError("Row must be a positive numeric value.");
  82. return false;
  83. }
  84. intVal = Convert.ToInt32(input);
  85. if (intVal > _theGame.GameBoard.DefaultAttributes.Height - 1 || intVal < 0)
  86. {
  87. SetInputError("Row must be between 0 and {0}".F(_theGame.GameBoard.DefaultAttributes.Height - 1));
  88. return false;
  89. }
  90. _inputError = false;
  91. return true;
  92. }
  93. protected virtual bool IsValidColumn(string input)
  94. {
  95. int intVal;
  96. if (!CommandLineUtil.ConsoleUtils.IsValidateNumericInput(input))
  97. {
  98. SetInputError("Column must be a positive numeric value.");
  99. return false;
  100. }
  101. intVal = Convert.ToInt32(input);
  102. if (intVal > _theGame.GameBoard.DefaultAttributes.Width - 1 || intVal < 0)
  103. {
  104. SetInputError("Column must be between 0 and {0}".F(_theGame.GameBoard.DefaultAttributes.Width - 1));
  105. return false;
  106. }
  107. _inputError = false;
  108. return true;
  109. }
  110. protected virtual bool IsValidLocationEntered()
  111. {
  112. if (_commandArgs.Args.Length < 2)
  113. {
  114. SetInputError("Command requires a Column and Row value.");
  115. return false;
  116. }
  117. _inputError = false;
  118. return (IsValidRow(_commandArgs.Args[1]) && IsValidColumn(_commandArgs.Args[0]));
  119. }
  120. protected virtual IResult<bool> IsValidScenarioTitleEntered(string input)
  121. {
  122. var Result = _theGame.JTSServices.RulesService.ScenarioTitleIsValid(input);
  123. var r = Result.ConvertServiceResultData(_theGame.JTSServices);
  124. return r;
  125. }
  126. protected virtual IResult<bool> IsValidGameTitleEntered(string input)
  127. {
  128. var sResult = _theGame.JTSServices.RulesService.GameTitleIsValid(input);
  129. var r = sResult.ConvertServiceResultData(_theGame.JTSServices);
  130. return r;
  131. }
  132. protected virtual MouseButton GetValidMouseButtonClick(string input)
  133. {
  134. // if no input default is left click
  135. if (input == null) return MouseButton.LEFT;
  136. var validButtonClicks = new List<string>
  137. {
  138. "l", "left", "r", "right", "m", "middle"
  139. };
  140. _inputError = false;
  141. switch (input.ToLowerInvariant())
  142. {
  143. case ("l") :
  144. case ("left") :
  145. return MouseButton.LEFT;
  146. case ("ll") :
  147. return MouseButton.DOUBLELEFT;
  148. case("r") :
  149. case ("right") :
  150. return MouseButton.RIGHT;
  151. case("rr") :
  152. return MouseButton.DOUBLERIGHT;
  153. case ("m") :
  154. case ("middle") :
  155. return MouseButton.MIDDLE;
  156. default :
  157. return MouseButton.LEFT;
  158. }
  159. }
  160. protected virtual string GetValidUnitName()
  161. {
  162. string unitName;
  163. //Restrict to 16 characters to not f-up the board
  164. System.Console.Write("Unit Name : ");
  165. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel();
  166. //unitName = Interaction.InputBox("Enter a valid unit name [16 chrs or less] : ", "Unit Name", "", 100, 100);
  167. while ((unitName.Length > 16 || unitName.Length == 0) && !_commandArgs.Cancel)
  168. {
  169. System.Console.ForegroundColor = ConsoleColor.Red;
  170. System.Console.Write("Enter a valid unit name [16 chrs or less] : ");
  171. System.Console.ResetColor();
  172. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel();
  173. //unitName = Interaction.InputBox("Enter a valid unit name [16 chrs or less] : ", "Unit Name", "", 100, 100);
  174. }
  175. while (!_theGame.JTSServices.RulesService.UnitNameIsUnique(unitName).Result && !_commandArgs.Cancel)
  176. {
  177. System.Console.ForegroundColor = ConsoleColor.Red;
  178. System.Console.Write("Unit name in use : ");
  179. System.Console.ResetColor();
  180. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel();
  181. //unitName = Interaction.InputBox("Unit name in use. Enter a valid unit name [16 chrs or less] : ", "Unit Name", "", 100, 100);
  182. }
  183. return unitName;
  184. }
  185. protected virtual IUnit GetValidReinforcementUnit(string unitName)
  186. {
  187. IUnit unit = GetValidUnit(unitName);
  188. while (!_theGame.CurrentTurn.Player.UnplacedReinforcements.Contains(unit))
  189. {
  190. System.Console.ForegroundColor = ConsoleColor.Red;
  191. System.Console.Write("{0} is not a currently unplaced unit. Unit Name : ".F(unitName));
  192. System.Console.ResetColor();
  193. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  194. unit = GetValidUnit(unitName);
  195. }
  196. return unit;
  197. }
  198. protected virtual IUnit GetValidUnit(string unitName)
  199. {
  200. IUnit unit;
  201. // Get and validate unit to move
  202. if (string.IsNullOrWhiteSpace(unitName))
  203. {
  204. System.Console.Write("Unit Name : ");
  205. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  206. //unitName = Interaction.InputBox("Unit Name [16 chrs or less] : ", "Unit Name", "", 100, 100);
  207. }
  208. try
  209. {
  210. unit = _theGame.JTSServices.GenericComponentService.GetByName<IUnit, IUnitDTO>(unitName);
  211. }
  212. catch (ComponentNotFoundException)
  213. {
  214. unit = null;
  215. }
  216. while (unit == null && !_commandArgs.Cancel)
  217. {
  218. System.Console.ForegroundColor = ConsoleColor.Red;
  219. System.Console.Write("Enter a valid unit name : ");
  220. System.Console.ResetColor();
  221. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  222. //unitName = unitName = Interaction.InputBox("Enter a valid unit name [16 chrs or less] : ", "Unit Name", "", 100, 100);
  223. try
  224. {
  225. unit = _theGame.JTSServices.GenericComponentService.GetByName<IUnit, IUnitDTO>(unitName);
  226. }
  227. catch (ComponentNotFoundException)
  228. {
  229. unit = null;
  230. }
  231. }
  232. while (unit == null || !unit.Country.Equals(_theGame.CurrentTurn.Player.Country))
  233. {
  234. System.Console.ForegroundColor = ConsoleColor.Red;
  235. System.Console.Write("Select a unit from your country : ");
  236. System.Console.ResetColor();
  237. unitName = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  238. //unitName = unitName = Interaction.InputBox("Enter a valid unit name [16 chrs or less] : ", "Unit Name", "", 100, 100);
  239. try
  240. {
  241. unit = _theGame.JTSServices.GenericComponentService.GetByName<IUnit, IUnitDTO>(unitName);
  242. }
  243. catch (ComponentNotFoundException)
  244. {
  245. unit = null;
  246. }
  247. }
  248. return unit;
  249. }
  250. protected virtual IUnitType GetValidUnitType(bool forCurrentTile)
  251. {
  252. var options = "";
  253. if (forCurrentTile)
  254. {
  255. var UnitTypes = _theGame.JTSServices.UnitService.GetUnitTypesAllowableForTile(_theGame.GameBoard.SelectedNode.DefaultTile());
  256. options = GetCommandInputOptions(UnitTypes);
  257. }
  258. System.Console.Write("Unit Type {0} : ", options);
  259. var name = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  260. IUnitType unitType;
  261. try
  262. {
  263. unitType = _theGame.JTSServices.UnitService.GetUnitTypeByName(name);
  264. }
  265. catch (ComponentNotFoundException)
  266. {
  267. unitType = null;
  268. }
  269. while (unitType == null && !_commandArgs.Cancel)
  270. {
  271. System.Console.ForegroundColor = ConsoleColor.Red;
  272. System.Console.Write("Enter a valid Unit Type {0} : ", options);
  273. System.Console.ResetColor();
  274. name = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  275. //country = Interaction.InputBox(string.Format("Faction not valid. Faction [{0}] ", sb.ToString()), "Faction by Country", "", 100, 100);
  276. try
  277. {
  278. unitType = _theGame.JTSServices.UnitService.GetUnitTypeByName(name);
  279. }
  280. catch (ComponentNotFoundException)
  281. {
  282. unitType = null;
  283. }
  284. }
  285. return unitType;
  286. }
  287. protected virtual IUnitClass GetValidUnitClass(IUnitType unitType)
  288. {
  289. // Get available unit classes
  290. var ids = _theGame.JTSServices.DataService.LookupAllowableUnitClassesByUnitBaseType(unitType.BaseType.ID);
  291. var unitClasses = _theGame.JTSServices.UnitService.GetUnitClassesByIDs(ids).Result;
  292. string options = GetCommandInputOptions(unitClasses);
  293. System.Console.Write("Unit Class {0} : ", options);
  294. var name = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  295. //country = Interaction.InputBox(String.Format("Faction [{0}] : ", sb.ToString()), "Faction by Country", "", 100, 100);
  296. IUnitClass unitClass;
  297. try
  298. {
  299. unitClass = _theGame.JTSServices.UnitService.GetUnitClassByName(name);
  300. }
  301. catch (ComponentNotFoundException)
  302. {
  303. unitClass = null;
  304. }
  305. while (unitClass == null && !_commandArgs.Cancel)
  306. {
  307. System.Console.ForegroundColor = ConsoleColor.Red;
  308. System.Console.Write("Enter a valid Unit Class {0} : ", options);
  309. System.Console.ResetColor();
  310. name = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  311. //country = Interaction.InputBox(string.Format("Faction not valid. Faction [{0}] ", sb.ToString()), "Faction by Country", "", 100, 100);
  312. try
  313. {
  314. unitClass = _theGame.JTSServices.UnitService.GetUnitClassByName(name);
  315. }
  316. catch (ComponentNotFoundException)
  317. {
  318. unitClass = null;
  319. }
  320. }
  321. return unitClass;
  322. }
  323. protected virtual IUnitGroupType GetValidUnitGroupType()
  324. {
  325. var sb = new StringBuilder();
  326. string options = GetCommandInputOptions<IUnitGroupType, IUnitGroupTypeDTO>();
  327. System.Console.Write("Unit Group Type {0} : ", options);
  328. var name = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  329. //country = Interaction.InputBox(String.Format("Faction [{0}] : ", sb.ToString()), "Faction by Country", "", 100, 100);
  330. IUnitGroupType unitGroupType;
  331. try
  332. {
  333. unitGroupType = _theGame.JTSServices.UnitService.GetUnitGroupTypeByName(name);
  334. }
  335. catch (ComponentNotFoundException)
  336. {
  337. unitGroupType = null;
  338. }
  339. while (unitGroupType == null && !_commandArgs.Cancel)
  340. {
  341. System.Console.ForegroundColor = ConsoleColor.Red;
  342. System.Console.Write("Enter a valid Unit Group Type {0} : ", options);
  343. System.Console.ResetColor();
  344. name = CommandLineUtil.ConsoleUtils.GetInputWithCancel().ToLowerInvariant();
  345. //country = Interaction.InputBox(string.Format("Faction not valid. Faction [{0}] ", sb.ToString()), "Faction by Country", "", 100, 100);
  346. try
  347. {
  348. unitGroupType = _theGame.JTSServices.UnitService.GetUnitGroupTypeByName(name);
  349. }
  350. catch (ComponentNotFoundException)
  351. {
  352. unitGroupType = null;
  353. }
  354. }
  355. return unitGroupType;
  356. }
  357. protected virtual INode GetSelectedNode()
  358. {
  359. if (_theGame.GameBoard.SelectedNode == null)
  360. {
  361. SetInputError("You must select a location first.");
  362. return null;
  363. }
  364. return _theGame.GameBoard.SelectedNode;
  365. }
  366. protected virtual bool MoveUnitToSelectedNode(IUnit unit)
  367. {
  368. var sourceNode = _theGame.JTSServices.NodeService.GetNodeAt(unit.Location);
  369. var targetNode = _theGame.GameBoard.SelectedNode;
  370. if (targetNode == null)
  371. return false;
  372. var r = unit.MoveToLocation(targetNode, sourceNode);
  373. if (r.Status != ResultStatus.SUCCESS)
  374. {
  375. SetInputError(r.Message);
  376. return false;
  377. }
  378. return true;
  379. }
  380. protected virtual string GetCommandInputOptions<T, dtoT>()
  381. where T : IBaseComponent
  382. where dtoT : IBaseGameComponentDTO
  383. {
  384. StringBuilder sb = new StringBuilder();
  385. sb.Append("[ ");
  386. var table = _theGame.JTSServices.GenericComponentService.GetComponentTable<T, dtoT>();
  387. table.Records.ToList().ForEach(t => sb.Append("{0} ".F(t.Name)));
  388. sb.Append("]");
  389. return sb.ToString();
  390. }
  391. protected virtual string GetCommandInputOptions<T>(IEnumerable<T> components)
  392. where T : IBaseComponent
  393. {
  394. StringBuilder sb = new StringBuilder();
  395. sb.Append("[ ");
  396. components.ToList().ForEach(t => sb.Append("{0} ".F(t.Name)));
  397. sb.Append("]");
  398. return sb.ToString();
  399. }
  400. }
  401. }