Advertisement
d_brezoev

WarMachines

Feb 23rd, 2014
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 22.53 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using WarMachines.Interfaces;
  7.  
  8. namespace WarMachines.Engine
  9. {
  10.     using System;
  11.     using System.Collections.Generic;
  12.     using System.Linq;
  13.  
  14.     using WarMachines.Interfaces;
  15.  
  16.     public class Command : ICommand
  17.     {
  18.         private const char SplitCommandSymbol = ' ';
  19.  
  20.         private string name;
  21.         private IList<string> parameters;
  22.  
  23.         private Command(string input)
  24.         {
  25.             this.TranslateInput(input);
  26.         }
  27.  
  28.         public string Name
  29.         {
  30.             get
  31.             {
  32.                 return this.name;
  33.             }
  34.  
  35.             private set
  36.             {
  37.                 if (string.IsNullOrEmpty(value))
  38.                 {
  39.                     throw new ArgumentNullException("Name cannot be null or empty.");
  40.                 }
  41.  
  42.                 this.name = value;
  43.             }
  44.         }
  45.  
  46.         public IList<string> Parameters
  47.         {
  48.             get
  49.             {
  50.                 return this.parameters;
  51.             }
  52.  
  53.             private set
  54.             {
  55.                 if (value == null)
  56.                 {
  57.                     throw new ArgumentNullException("List of strings cannot be null.");
  58.                 }
  59.  
  60.                 this.parameters = value;
  61.             }
  62.         }
  63.  
  64.         public static Command Parse(string input)
  65.         {
  66.             return new Command(input);
  67.         }
  68.  
  69.         private void TranslateInput(string input)
  70.         {
  71.             var indexOfFirstSeparator = input.IndexOf(SplitCommandSymbol);
  72.  
  73.             this.Name = input.Substring(0, indexOfFirstSeparator);
  74.             this.Parameters = input.Substring(indexOfFirstSeparator + 1).Split(new[] { SplitCommandSymbol }, StringSplitOptions.RemoveEmptyEntries);
  75.         }
  76.     }
  77. }
  78. namespace WarMachines.Engine
  79. {
  80.     using WarMachines.Interfaces;
  81.     using WarMachines.Machines;
  82.  
  83.     public class MachineFactory : IMachineFactory
  84.     {
  85.         public IPilot HirePilot(string name)
  86.         {
  87.             return new Pilot(name);
  88.         }
  89.  
  90.         public ITank ManufactureTank(string name, double attackPoints, double defensePoints)
  91.         {
  92.             return new Tank(name, attackPoints, defensePoints);
  93.         }
  94.  
  95.         public IFighter ManufactureFighter(string name, double attackPoints, double defensePoints, bool stealthMode)
  96.         {
  97.             return new Fighter(name, attackPoints, defensePoints, stealthMode);
  98.         }
  99.     }
  100. }
  101. namespace WarMachines.Engine
  102. {
  103.     using System;
  104.     using System.Collections.Generic;
  105.     using System.Text;
  106.     using System.IO;
  107.  
  108.     using WarMachines.Interfaces;
  109.  
  110.     public sealed class WarMachineEngine : IWarMachineEngine
  111.     {
  112.         private const string InvalidCommand = "Invalid command name: {0}";
  113.         private const string PilotHired = "Pilot {0} hired";
  114.         private const string PilotExists = "Pilot {0} is hired already";
  115.         private const string TankManufactured = "Tank {0} manufactured - attack: {1}; defense: {2}";
  116.         private const string FighterManufactured = "Fighter {0} manufactured - attack: {1}; defense: {2}; stealth: {3}";
  117.         private const string MachineExists = "Machine {0} is manufactured already";
  118.         private const string MachineHasPilotAlready = "Machine {0} is already occupied";
  119.         private const string PilotNotFound = "Pilot {0} could not be found";
  120.         private const string MachineNotFound = "Machine {0} could not be found";
  121.         private const string MachineEngaged = "Pilot {0} engaged machine {1}";
  122.         private const string InvalidMachineOperation = "Machine {0} does not support this operation";
  123.         private const string FighterOperationSuccessful = "Fighter {0} toggled stealth mode";
  124.         private const string TankOperationSuccessful = "Tank {0} toggled defense mode";
  125.         private const string InvalidAttackTarget = "Tank {0} cannot attack stealth fighter {1}";
  126.         private const string AttackSuccessful = "Machine {0} was attacked by machine {1} - current health: {2}";
  127.  
  128.         private static readonly WarMachineEngine SingleInstance = new WarMachineEngine();
  129.  
  130.         private IMachineFactory factory;
  131.         private IDictionary<string, IPilot> pilots;
  132.         private IDictionary<string, IMachine> machines;
  133.  
  134.         private WarMachineEngine()
  135.         {
  136.             this.factory = new MachineFactory();
  137.             this.pilots = new Dictionary<string, IPilot>();
  138.             this.machines = new Dictionary<string, IMachine>();
  139.         }
  140.  
  141.         public static WarMachineEngine Instance
  142.         {
  143.             get
  144.             {
  145.                 return SingleInstance;
  146.             }
  147.         }
  148.  
  149.         public void Start()
  150.         {
  151.             var commands = this.ReadCommands();
  152.             var commandResult = this.ProcessCommands(commands);
  153.             this.PrintReports(commandResult);
  154.         }
  155.  
  156.         private IList<ICommand> ReadCommands()
  157.         {
  158.             var commands = new List<ICommand>();
  159.  
  160.             var currentLine = Console.ReadLine();
  161.  
  162.             while (!string.IsNullOrEmpty(currentLine))
  163.             {
  164.                 var currentCommand = Command.Parse(currentLine);
  165.                 commands.Add(currentCommand);
  166.  
  167.                 currentLine = Console.ReadLine();
  168.             }
  169.  
  170.             return commands;
  171.         }
  172.  
  173.         private IList<string> ProcessCommands(IList<ICommand> commands)
  174.         {
  175.             var reports = new List<string>();
  176.  
  177.             foreach (var command in commands)
  178.             {
  179.                 string commandResult;
  180.  
  181.                 switch (command.Name)
  182.                 {
  183.                     case "HirePilot":
  184.                         var pilotName = command.Parameters[0];
  185.                         commandResult = this.HirePilot(pilotName);
  186.                         reports.Add(commandResult);
  187.                         break;
  188.  
  189.                     case "Report":
  190.                         var pilotReporting = command.Parameters[0];
  191.                         commandResult = this.PilotReport(pilotReporting);
  192.                         reports.Add(commandResult);
  193.                         break;
  194.  
  195.                     case "ManufactureTank":
  196.                         var tankName = command.Parameters[0];
  197.                         var tankAttackPoints = double.Parse(command.Parameters[1]);
  198.                         var tankDefensePoints = double.Parse(command.Parameters[2]);
  199.                         commandResult = this.ManufactureTank(tankName, tankAttackPoints, tankDefensePoints);
  200.                         reports.Add(commandResult);
  201.                         break;
  202.  
  203.                     case "DefenseMode":
  204.                         var defenseModeTankName = command.Parameters[0];
  205.                         commandResult = this.ToggleTankDefenseMode(defenseModeTankName);
  206.                         reports.Add(commandResult);
  207.                         break;
  208.  
  209.                     case "ManufactureFighter":
  210.                         var fighterName = command.Parameters[0];
  211.                         var fighterAttackPoints = double.Parse(command.Parameters[1]);
  212.                         var fighterDefensePoints = double.Parse(command.Parameters[2]);
  213.                         var fighterStealthMode = command.Parameters[3] == "StealthON" ? true : false;
  214.                         commandResult = this.ManufactureFighter(fighterName, fighterAttackPoints, fighterDefensePoints, fighterStealthMode);
  215.                         reports.Add(commandResult);
  216.                         break;
  217.  
  218.                     case "StealthMode":
  219.                         var stealthModeFighterName = command.Parameters[0];
  220.                         commandResult = this.ToggleFighterStealthMode(stealthModeFighterName);
  221.                         reports.Add(commandResult);
  222.                         break;
  223.  
  224.                     case "Engage":
  225.                         var selectedPilotName = command.Parameters[0];
  226.                         var selectedMachineName = command.Parameters[1];
  227.                         commandResult = this.EngageMachine(selectedPilotName, selectedMachineName);
  228.                         reports.Add(commandResult);
  229.                         break;
  230.  
  231.                     case "Attack":
  232.                         var attackingMachine = command.Parameters[0];
  233.                         var defendingMachine = command.Parameters[1];
  234.                         commandResult = this.AttackMachines(attackingMachine, defendingMachine);
  235.                         reports.Add(commandResult);
  236.                         break;
  237.  
  238.                     default:
  239.                         reports.Add(string.Format(InvalidCommand, command.Name));
  240.                         break;
  241.                 }
  242.             }
  243.  
  244.             return reports;
  245.         }
  246.  
  247.         private void PrintReports(IList<string> reports)
  248.         {
  249.             var output = new StringBuilder();
  250.  
  251.             foreach (var report in reports)
  252.             {
  253.                 output.AppendLine(report);
  254.             }
  255.             using (StreamWriter writer = new StreamWriter("test.txt"))
  256.             {
  257.                 writer.Write(output.ToString());
  258.             }
  259.             Console.Write(output.ToString());
  260.         }
  261.  
  262.         private string HirePilot(string name)
  263.         {
  264.             if (this.pilots.ContainsKey(name))
  265.             {
  266.                 return string.Format(PilotExists, name);
  267.             }
  268.  
  269.             var pilot = this.factory.HirePilot(name);
  270.             this.pilots.Add(name, pilot);
  271.  
  272.             return string.Format(PilotHired, name);
  273.         }
  274.  
  275.         private string ManufactureTank(string name, double attackPoints, double defensePoints)
  276.         {
  277.             if (this.machines.ContainsKey(name))
  278.             {
  279.                 return string.Format(MachineExists, name);
  280.             }
  281.  
  282.             var tank = this.factory.ManufactureTank(name, attackPoints, defensePoints);
  283.             this.machines.Add(name, tank);
  284.  
  285.             return string.Format(TankManufactured, name, attackPoints, defensePoints);
  286.         }
  287.  
  288.         private string ManufactureFighter(string name, double attackPoints, double defensePoints, bool stealthMode)
  289.         {
  290.             if (this.machines.ContainsKey(name))
  291.             {
  292.                 return string.Format(MachineExists, name);
  293.             }
  294.  
  295.             var fighter = this.factory.ManufactureFighter(name, attackPoints, defensePoints, stealthMode);
  296.             this.machines.Add(name, fighter);
  297.  
  298.             return string.Format(FighterManufactured, name, attackPoints, defensePoints, stealthMode == true ? "ON" : "OFF");
  299.         }
  300.  
  301.         private string EngageMachine(string selectedPilotName, string selectedMachineName)
  302.         {
  303.             if (!this.pilots.ContainsKey(selectedPilotName))
  304.             {
  305.                 return string.Format(PilotNotFound, selectedPilotName);
  306.             }
  307.  
  308.             if (!this.machines.ContainsKey(selectedMachineName))
  309.             {
  310.                 return string.Format(MachineNotFound, selectedMachineName);
  311.             }
  312.  
  313.             if (this.machines[selectedMachineName].Pilot != null)
  314.             {
  315.                 return string.Format(MachineHasPilotAlready, selectedMachineName);
  316.             }
  317.  
  318.             var pilot = this.pilots[selectedPilotName];
  319.             var machine = this.machines[selectedMachineName];
  320.  
  321.             pilot.AddMachine(machine);
  322.             machine.Pilot = pilot;
  323.  
  324.             return string.Format(MachineEngaged, selectedPilotName, selectedMachineName);
  325.         }
  326.  
  327.         private string AttackMachines(string attackingMachineName, string defendingMachineName)
  328.         {
  329.             if (!this.machines.ContainsKey(attackingMachineName))
  330.             {
  331.                 return string.Format(MachineNotFound, attackingMachineName);
  332.             }
  333.  
  334.             if (!this.machines.ContainsKey(defendingMachineName))
  335.             {
  336.                 return string.Format(MachineNotFound, defendingMachineName);
  337.             }
  338.  
  339.             var attackingMachine = this.machines[attackingMachineName];
  340.             var defendingMachine = this.machines[defendingMachineName];
  341.  
  342.             if (attackingMachine is ITank && defendingMachine is IFighter && (defendingMachine as IFighter).StealthMode)
  343.             {
  344.                 return string.Format(InvalidAttackTarget, attackingMachineName, defendingMachineName);
  345.             }
  346.  
  347.             attackingMachine.Targets.Add(defendingMachineName);
  348.  
  349.             var attackPoints = attackingMachine.AttackPoints;
  350.             var defensePoints = defendingMachine.DefensePoints;
  351.  
  352.             var damage = attackPoints - defensePoints;
  353.  
  354.             if (damage > 0)
  355.             {
  356.                 var newHeathPoints = defendingMachine.HealthPoints - damage;
  357.  
  358.                 if (newHeathPoints < 0)
  359.                 {
  360.                     newHeathPoints = 0;
  361.                 }
  362.  
  363.                 defendingMachine.HealthPoints = newHeathPoints;
  364.             }
  365.  
  366.             return string.Format(AttackSuccessful, defendingMachineName, attackingMachineName, defendingMachine.HealthPoints);
  367.         }
  368.  
  369.         private string PilotReport(string pilotReporting)
  370.         {
  371.             if (!this.pilots.ContainsKey(pilotReporting))
  372.             {
  373.                 return string.Format(PilotNotFound, pilotReporting);
  374.             }
  375.  
  376.             return this.pilots[pilotReporting].Report();
  377.         }
  378.  
  379.         private string ToggleFighterStealthMode(string stealthModeFighterName)
  380.         {
  381.             if (!this.machines.ContainsKey(stealthModeFighterName))
  382.             {
  383.                 return string.Format(MachineNotFound, stealthModeFighterName);
  384.             }
  385.  
  386.             if (this.machines[stealthModeFighterName] is ITank)
  387.             {
  388.                 return string.Format(InvalidMachineOperation, stealthModeFighterName);
  389.             }
  390.  
  391.             var machineAsFighter = this.machines[stealthModeFighterName] as IFighter;
  392.             machineAsFighter.ToggleStealthMode();
  393.  
  394.             return string.Format(FighterOperationSuccessful, stealthModeFighterName);
  395.         }
  396.  
  397.         private string ToggleTankDefenseMode(string defenseModeTankName)
  398.         {
  399.             if (!this.machines.ContainsKey(defenseModeTankName))
  400.             {
  401.                 return string.Format(MachineNotFound, defenseModeTankName);
  402.             }
  403.  
  404.             if (this.machines[defenseModeTankName] is IFighter)
  405.             {
  406.                 return string.Format(InvalidMachineOperation, defenseModeTankName);
  407.             }
  408.  
  409.             var machineAsFighter = this.machines[defenseModeTankName] as ITank;
  410.             machineAsFighter.ToggleDefenseMode();
  411.  
  412.             return string.Format(TankOperationSuccessful, defenseModeTankName);
  413.         }
  414.     }
  415. }
  416. namespace WarMachines.Interfaces
  417. {
  418.     using System.Collections.Generic;
  419.  
  420.     public interface ICommand
  421.     {
  422.         string Name { get; }
  423.  
  424.         IList<string> Parameters { get; }
  425.     }
  426. }
  427. namespace WarMachines.Interfaces
  428. {
  429.     public interface IFighter : IMachine
  430.     {
  431.         bool StealthMode { get; }
  432.  
  433.         void ToggleStealthMode();
  434.     }
  435. }
  436. namespace WarMachines.Interfaces
  437. {
  438.     using System.Collections.Generic;
  439.  
  440.     public interface IMachine
  441.     {
  442.         string Name { get; set; }
  443.  
  444.         IPilot Pilot { get; set; }
  445.  
  446.         double HealthPoints { get; set; }
  447.  
  448.         double AttackPoints { get; }
  449.  
  450.         double DefensePoints { get; }
  451.  
  452.         IList<string> Targets { get; }
  453.  
  454.         void Attack(string target);
  455.  
  456.         string ToString();
  457.     }
  458. }
  459. namespace WarMachines.Interfaces
  460. {
  461.     public interface IMachineFactory
  462.     {
  463.         IPilot HirePilot(string name);
  464.  
  465.         ITank ManufactureTank(string name, double attackPoints, double defensePoints);
  466.  
  467.         IFighter ManufactureFighter(string name, double attackPoints, double defensePoints, bool stealthMode);
  468.     }
  469. }
  470. namespace WarMachines.Interfaces
  471. {
  472.     public interface IPilot
  473.     {
  474.         string Name { get; }
  475.  
  476.         void AddMachine(IMachine machine);
  477.  
  478.         string Report();
  479.     }
  480. }
  481. namespace WarMachines.Interfaces
  482. {
  483.     public interface ITank : IMachine
  484.     {
  485.         bool DefenseMode { get; }
  486.  
  487.         void ToggleDefenseMode();
  488.     }
  489. }
  490. namespace WarMachines.Interfaces
  491. {
  492.     using System.Collections.Generic;
  493.  
  494.     public interface IWarMachineEngine
  495.     {
  496.         void Start();
  497.     }
  498. }
  499.  
  500. namespace WarMachines.Machines
  501. {
  502.     public  class Fighter:Machine,IFighter
  503.     {        
  504.         private bool stealthMode;
  505.         public Fighter(string name, double attack, double defense, bool stealthMode)
  506.             :base(name,attack,defense)
  507.         {
  508.             this.HealthPoints = 200;
  509.             this.StealthMode = stealthMode;
  510.         }
  511.         public bool StealthMode
  512.         {
  513.             get { return this.stealthMode; }
  514.             private set
  515.             {
  516.                 this.stealthMode = value;
  517.             }
  518.         }
  519.  
  520.         public void ToggleStealthMode()
  521.         {
  522.             this.StealthMode = !this.StealthMode;
  523.         }
  524.         public override string ToString()
  525.         {
  526.             StringBuilder sb = new StringBuilder();
  527.             sb.Append(base.ToString());
  528.             sb.Append(" *Stealth: ");            
  529.             sb.Append(this.StealthMode ? "ON" : "OFF");
  530.             return sb.ToString();          
  531.         }
  532.     }
  533. }
  534.  
  535. namespace WarMachines.Machines
  536. {
  537.     public class Machine:IMachine
  538.     {
  539.         private string name;
  540.         private double healthPoints;
  541.         private double attackPoints;
  542.         private double defensePoints;
  543.         private IList<string> targets= new List<string>();
  544.  
  545.         public Machine(string name, double attackPoints, double defensePoints)
  546.         {
  547.             this.Name = name;
  548.             this.AttackPoints = attackPoints;
  549.             this.DefensePoints = defensePoints;
  550.             //this.Targets = new List<string>();
  551.         }
  552.        
  553.         public string Name
  554.         {
  555.             get
  556.             {
  557.                 return this.name;
  558.             }
  559.             set
  560.             {
  561.                 if (string.IsNullOrEmpty(value))
  562.                 {
  563.                     throw new ArgumentException("Invalid name");
  564.                 }
  565.                 this.name = value;
  566.             }
  567.         }
  568.  
  569.         public IPilot Pilot{get; set;}      
  570.  
  571.         public double HealthPoints
  572.         {
  573.             get
  574.             {
  575.                 return this.healthPoints;
  576.             }
  577.             set
  578.             {
  579.                 this.healthPoints = value;
  580.             }
  581.         }
  582.  
  583.         public double AttackPoints
  584.         {
  585.             get { return this.attackPoints; }
  586.             protected set { this.attackPoints = value; }
  587.         }
  588.  
  589.         public double DefensePoints
  590.         {
  591.             get { return this.defensePoints; }
  592.             protected set { this.defensePoints = value; }
  593.         }
  594.  
  595.         public IList<string> Targets
  596.         {
  597.             get { return this.targets; }
  598.             private set { this.targets = value; }
  599.         }
  600.        
  601.  
  602.         public void Attack(string target)
  603.         {
  604.            
  605.         }
  606.  
  607.         public override string ToString()
  608.         {
  609.             StringBuilder sb = new StringBuilder();            
  610.             sb.AppendLine("- " + this.Name);
  611.             sb.AppendLine(" *Type: "+ this.GetType().Name);
  612.             sb.AppendLine(" *Health: "+ this.HealthPoints);
  613.             sb.AppendLine(" *Attack: "+ this.AttackPoints);
  614.             sb.AppendLine(" *Defense: " + this.DefensePoints);
  615.             sb.Append(" *Targets: ");
  616.             sb.AppendLine(this.Targets.Count==0?"None": string.Join(", ",this.Targets));                        
  617.             return sb.ToString();
  618.         }
  619.     }
  620. }
  621.  
  622. namespace WarMachines.Machines
  623. {
  624.     public class Pilot:IPilot
  625.     {
  626.         private string name;
  627.         private List<IMachine> engagedMachines = new List<IMachine>();
  628.         public Pilot(string name)
  629.         {
  630.             this.Name = name;
  631.         }
  632.         public string Name
  633.         {
  634.             get { return this.name; }
  635.             set
  636.             {
  637.                 if (string.IsNullOrEmpty(value))
  638.                 {
  639.                     throw new ArgumentException("Name cannot be empty");
  640.                 }
  641.                 this.name = value;
  642.             }
  643.         }
  644.  
  645.         public void AddMachine(IMachine machine)
  646.         {
  647.             this.engagedMachines.Add(machine);
  648.         }
  649.  
  650.         public string Report()
  651.         {
  652.             StringBuilder sb = new StringBuilder();
  653.             sb.Append(this.Name+" - ");
  654.             if (this.engagedMachines.Count==1)
  655.             {
  656.                 sb.AppendLine("1 machine");
  657.             }
  658.             else if (this.engagedMachines.Count == 0)
  659.             {
  660.                 sb.Append("no machines");
  661.             }
  662.             else
  663.             {
  664.                 sb.AppendLine(string.Format("{0} machines",this.engagedMachines.Count));
  665.             }
  666.             foreach (var machine in this.engagedMachines.OrderBy(m => m.HealthPoints).ThenBy(mm => mm.Name))
  667.             {                
  668.                 sb.AppendLine(machine.ToString());
  669.             }          
  670.            
  671.             return sb.ToString();
  672.         }
  673.     }
  674. }
  675.  
  676. namespace WarMachines.Machines
  677. {
  678.     public class Tank: Machine,ITank
  679.     {        
  680.         private bool defenseMode;
  681.         public Tank(string name, double attack, double defense)
  682.             :base(name,attack,defense)
  683.         {
  684.             this.HealthPoints = 100;
  685.             this.ToggleDefenseMode();
  686.         }
  687.        
  688.         public bool DefenseMode
  689.         {
  690.             get { return this.defenseMode; }
  691.             private set { this.defenseMode = value; }
  692.         }
  693.  
  694.         public void ToggleDefenseMode()
  695.         {
  696.             this.defenseMode = !this.defenseMode;
  697.             if (this.defenseMode)
  698.             {
  699.                 this.DefensePoints += 30;
  700.                 this.AttackPoints -= 40;
  701.             }
  702.             else
  703.             {
  704.                 this.DefensePoints -= 30;
  705.                 this.AttackPoints += 40;
  706.             }
  707.         }
  708.         public override string ToString()
  709.         {
  710.             StringBuilder sb = new StringBuilder();
  711.             sb.Append(base.ToString());
  712.             sb.Append(" *Defense: ");
  713.             sb.Append(this.DefenseMode ? "ON" : "OFF");
  714.             return sb.ToString();
  715.         }
  716.     }
  717. }
  718. namespace WarMachines
  719. {
  720.     using WarMachines.Engine;
  721.  
  722.     public class WarMachinesProgram
  723.     {
  724.         public static void Main()
  725.         {
  726.             WarMachineEngine.Instance.Start();
  727.         }
  728.     }
  729. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement