C# Assignment. Optimize Existing Application

========================================================================

  Minefield Project Overview



========================================================================


This application consists of a large number of mine objects that have a unique identifier, a position,

a team and can be marked as active or invulnerable.


Each loop, all active mines find what other non-invulnerable mines are within their blast radius

(i.e. what other mines would be damaged if it exploded). Then, for each team, the mine with the most targets is exploded.


This continues until a round occurs in which no target mines were targeted/damaged by the explosion of mines from each team.


The team with the most remaining mines is declared the winner.


Tips:

-start by making sure the code compiles cleanly

-get the code to run (it does not run successfully right off the bat)

-verify that the code is accomplishing its main goal correctly

-look for ways to optimize the code for both performance and memory usage

 * there are significant gains that can be made in performance

-look to enforce defensive programming (error checking and handling, etc.)

-invulnerable mines cannot take damage from other mines

-invulnerable mines are not targetable

-inactive mines cannot be triggered to explode. They can only explode from taking too much damage

-active mines, even if they are invulnerable, can be triggered to explode.

-even a mine with no targets can be triggered to explode

-chain reactions are possible (i.e. a fatally damaged mine will explode and damage its targets)

-friendly fire is on (an exploding mine will damage both enemy and friendly targets within its destructive radius)


Please comment changes and alterations to the code. Feel free to document your work and progress in the comment

notes section at the top of Minefield.cs. In general, the more insight you provide into your work the better.

If you try alternative approaches, even if they don't work out the way you hope, be sure to document the decision making

you made along the way.


Make sure that your name, the date you did this test and the amount of time taken are marked

in Minefield.cs.


Try to stick to the code convention that you find in the existing code. Feel free to fix

any inconsistencies.


Getting the exact results provided below is not a requirement to "pass" the test. We are far more interested

in code fixes, cleanup, style, improvements, issues uncovered, performance considerations, etc.


In a moment you'll see why getting the same as the results listed below is not even going to be possible after a 

certain point.


The results below are provided as a guide. You should be able to replicate them after getting the code to compile and

fixing any crashes. If you start to refactor or make significant changes then all bets are off. So if you consider 

matching the results below to be an important first step, focus on that early before making any major changes.


But again, matching the results is not the end goal of this test. You do not need to match the results. You need

to show us your abilities as a programmer. Focus on things that you are unhappy with in the code, its layout and 

structure. Explain your rationale for making those changes.


In a real working environment you'd be able to ask the design intent behind how certain things work. You don't

have that luxury doing this test. If there are certain things that really bug you or you're unsure how to proceed 

feel free to reach out to HR and ask for clarification. 


It's perfectly fine for you to identify the conundrum and pick what way you think it should be working. Again, document

your insight and choice.


And now for the reason why your results will not match the results below in the end anyway:


Implement the following

Mines now move. Add a velocity to each mine, with a random magnitude between zero and 10 units, in a random direction

   selected at time of mine creation. All mines move at the end of a turn.



Feel free to design and implement this new feature in whatever way you deem most suitable.


Usage of .Net Framework 4.5.2 or later is permitted.


It is preferred that Visual Studio 2015 or later is used as your development environment. Visual Studio

Community 2019 can be downloaded free from:

http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx

If another development environment is used please provide details.


Note any and all performance tools and techniques used. 


Do not modify the existing three input parameters used. Feel free to add additional inputs if needed.


The three parameters are: Random seed, Number of teams, and Number of mines per team


Here are some sample results that show program output after bug fixes and initial cleanup. Again, don't obsess on 

these results. They are only provided as an initial goal for the cleanup portion. 



Random seed: 987654

Number of teams: 3

Number of mines per team: 500

Object id 1071 position (-755.938, 93.133, -556.052) active Y invulnerable N

Object id 275 position (266.852, -32.735, 970.941) active Y invulnerable N

Object id 934 position (570.726, -275.077, -346.969) active N invulnerable N

Object id 1863 position (903.713, -300.514, 338.788) active Y invulnerable Y

Object id 3885 position (331.019, 376.530, 101.836) active Y invulnerable N

Object id 1470 position (-924.728, 20.487, -262.222) active Y invulnerable N

Object id 3201 position (379.957, 81.881, 458.886) active Y invulnerable N

Object id 2538 position (-119.712, -5.246, -345.135) active Y invulnerable N

Object id 455 position (-610.912, -547.901, -254.453) active Y invulnerable N

Object id 2465 position (429.587, -295.623, -74.395) active Y invulnerable N

Turn 1: Team 0 picks Mine with object id 2540 (with 2 targets) to explode

Turn 1: Team 1 picks Mine with object id 1104 (with 3 targets) to explode

Turn 1: Team 2 picks Mine with object id 553 (with 2 targets) to explode

Turn 2: Team 0 picks Mine with object id 2223 (with 2 targets) to explode

Turn 2: Team 1 picks Mine with object id 358 (with 3 targets) to explode

Turn 2: Team 2 picks Mine with object id 581 (with 2 targets) to explode

Turn 3: Team 0 picks Mine with object id 2466 (with 1 targets) to explode

Turn 3: Team 1 picks Mine with object id 4973 (with 2 targets) to explode

Turn 3: Team 2 picks Mine with object id 4548 (with 2 targets) to explode

Turn 4: Team 0 picks Mine with object id 53 (with 1 targets) to explode

Turn 4: Team 1 picks Mine with object id 4247 (with 2 targets) to explode

Turn 4: Team 2 picks Mine with object id 3923 (with 1 targets) to explode

Team 0 has 357 mines remaining

Team 1 has 385 mines remaining

Team 2 has 424 mines remaining

Team 2 WINS after 41 turns!!


Random seed: 456

Number of teams: 3

Number of mines per team: 1000

Object id 5241 position (-502.488, 960.968, -673.866) active Y invulnerable N

Object id 8308 position (-429.672, 251.257, -690.690) active Y invulnerable N

Object id 9649 position (518.235, 635.312, -637.790) active Y invulnerable N

Object id 5054 position (-410.384, -226.540, -217.858) active Y invulnerable Y

Object id 2728 position (373.186, -937.465, -62.392) active Y invulnerable N

Object id 8632 position (-651.196, 446.681, 638.653) active Y invulnerable N

Object id 5008 position (893.620, 164.387, 108.439) active Y invulnerable N

Object id 7782 position (-93.770, -602.303, 213.354) active Y invulnerable Y

Object id 4858 position (-599.576, 697.088, -730.733) active Y invulnerable N

Object id 507 position (698.314, 716.660, 750.904) active Y invulnerable N

Turn 1: Team 0 picks Mine with object id 3398 (with 3 targets) to explode

Turn 1: Team 1 picks Mine with object id 2609 (with 4 targets) to explode

Turn 1: Team 2 picks Mine with object id 5427 (with 3 targets) to explode

Turn 2: Team 0 picks Mine with object id 6725 (with 3 targets) to explode

Turn 2: Team 1 picks Mine with object id 8415 (with 3 targets) to explode

Turn 2: Team 2 picks Mine with object id 9307 (with 3 targets) to explode

Turn 3: Team 0 picks Mine with object id 4314 (with 3 targets) to explode

Turn 3: Team 1 picks Mine with object id 4372 (with 3 targets) to explode

Turn 3: Team 2 picks Mine with object id 5106 (with 3 targets) to explode

Turn 4: Team 0 picks Mine with object id 4800 (with 3 targets) to explode

Turn 4: Team 1 picks Mine with object id 553 (with 3 targets) to explode

Turn 4: Team 2 picks Mine with object id 8917 (with 3 targets) to explode

Team 0 has 623 mines remaining

Team 1 has 722 mines remaining

Team 2 has 773 mines remaining

Team 2 WINS after 115 turns!!


Random seed: 654321

Number of teams: 5

Number of mines per team: 1500

Object id 8591 position (-898.894, -290.149, 50.030) active Y invulnerable N

Object id 7110 position (-303.245, 718.965, -516.425) active Y invulnerable N

Object id 1466 position (637.269, -285.511, -88.674) active Y invulnerable N

Object id 10286 position (-312.755, -866.798, -53.850) active Y invulnerable N

Object id 10766 position (316.465, 415.601, 571.089) active Y invulnerable N

Object id 3469 position (956.990, -160.174, -141.135) active Y invulnerable N

Object id 44 position (447.428, -995.504, 571.503) active N invulnerable N

Object id 14905 position (-256.135, -394.987, -613.572) active Y invulnerable N

Object id 14267 position (-446.510, -544.947, 657.727) active Y invulnerable N

Object id 7000 position (-123.204, -670.820, 631.414) active Y invulnerable N

Turn 1: Team 0 picks Mine with object id 1920 (with 6 targets) to explode

Turn 1: Team 1 picks Mine with object id 1678 (with 6 targets) to explode

Turn 1: Team 2 picks Mine with object id 7753 (with 6 targets) to explode

Turn 1: Team 3 picks Mine with object id 7578 (with 5 targets) to explode

Turn 1: Team 4 picks Mine with object id 11024 (with 8 targets) to explode

Turn 2: Team 0 picks Mine with object id 947 (with 5 targets) to explode

Turn 2: Team 1 picks Mine with object id 801 (with 6 targets) to explode

Turn 2: Team 2 picks Mine with object id 7181 (with 6 targets) to explode

Turn 2: Team 3 picks Mine with object id 1515 (with 4 targets) to explode

Turn 2: Team 4 picks Mine with object id 3190 (with 6 targets) to explode

Turn 3: Team 0 picks Mine with object id 13719 (with 5 targets) to explode

Turn 3: Team 1 picks Mine with object id 5827 (with 6 targets) to explode

Turn 3: Team 2 picks Mine with object id 9530 (with 6 targets) to explode

Turn 3: Team 3 picks Mine with object id 8955 (with 4 targets) to explode

Turn 3: Team 4 picks Mine with object id 9682 (with 5 targets) to explode

Turn 4: Team 0 picks Mine with object id 14543 (with 5 targets) to explode

Turn 4: Team 1 picks Mine with object id 10092 (with 6 targets) to explode

Turn 4: Team 2 picks Mine with object id 1466 (with 4 targets) to explode

Turn 4: Team 3 picks Mine with object id 13093 (with 4 targets) to explode

Turn 4: Team 4 picks Mine with object id 10741 (with 5 targets) to explode

Team 0 has 565 mines remaining

Team 1 has 574 mines remaining

Team 2 has 738 mines remaining

Team 3 has 814 mines remaining

Team 4 has 949 mines remaining

Team 4 WINS after 278 turns!!


These results were obtained on a Windows 10 PC.



/////////////////////////////////////////////////////////////////////////////

Get Help With a similar task to - C# Assignment. Optimize Existing Application

Login to view and/or buy answers.. or post an answer
Additional Instructions:

Mine-Assignment- Copy/Minefield/Minefield/Mine.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Minefield { class Mine : Object { public float[] Position = new float[3]; public float DestructiveRadius = 0.0f; public float Health = 0.0f; public float ExplosiveYield = 0.0f; List<Object> TargetList = new List<Object>(); public event EventHandler MineDetonated; public override float[] GetPosition() { return Position; } public override void SetPosition(float[] pos) { Position = pos; } public int GetTeam() { return Team; } public float GetDistance(float[] positionA, float[] positionB) { float distance = 0.0f; for (int i = 0; i < 3; i++) { distance += (float)Math.Pow(positionA[i] - positionB[i], 2.0f); } return (float)Math.Sqrt(distance); } public void FindCurrentTargets() { if (!Active) { return; } TargetList = new List<Object>(); for (int i = 0; i < ObjectManager.GetSingleton().GetNumberOfObjects(); i++) { Object obj = ObjectManager.GetSingleton().GetObject(i); float distance = GetDistance(GetPosition(), obj.GetPosition()); if (distance > DestructiveRadius) { break; } //TODO: Any other reasons to not add this object? TargetList.Add(obj); } } public int GetNumberOfEnemyTargets() { int numberOfEnemyTargets = 0; for (int i = 0; i < TargetList.Count; ++i) { if (((Mine)TargetList[i]).GetTeam() != GetTeam()) { numberOfEnemyTargets++; } } return numberOfEnemyTargets; } public void Explode() { foreach (Object obj in TargetList) { float distance = GetDistance(GetPosition(), obj.GetPosition()); // damage is inverse-squared of distance float factor = 1.0f - (distance / DestructiveRadius); float damage = (factor * factor) * ExplosiveYield; ((Mine)obj).TakeDamage(damage); } // Destroy self TakeDamage(Health); } void TakeDamage(float damage) { Health -= damage; if (Health < 0.0f) { MineDetonated(this, new EventArgs()); } } } } Mine-Assignment- Copy/Minefield/Minefield/Minefield.cs using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; // // ZOS Software Engineer Applicant C# Test 1.0 // // Submitted by: // // Date: // // Time taken: // // Notes: // // // // // namespace Minefield { public class Game { public abstract class IOutputHandler { public abstract void Log(string s); public virtual void LogLine(string s) { Log(s + "\n"); } public virtual void LogF(string format, params object[] args) { string s = String.Format(format, args); Log(s); } } public class PerformanceTimer { public string Msg = ""; Stopwatch Timer = new Stopwatch(); public PerformanceTimer(string msg, IOutputHandler output) { Msg = msg; Output = output; Timer.Start(); } public void Stop() { Timer.Stop(); Output.LogF("{0} {1}\n", Msg, Timer.ElapsedMilliseconds); } } const int NumberOfWorkerThreads = 16; internal int NumberOfTeams = 3; internal int NumberOfMinesPerTeam = 1500; public static IOutputHandler Output = null; public void SetRandomSeed(int randomSeed) { RandomGen.SetRandomSeed(randomSeed); } public void SetNumberOfTeams(int numTeams) { NumberOfTeams = numTeams; } public void SetNumberOfMinesPerTeam(int numMines) { NumberOfMinesPerTeam = numMines; } void FindTargets() { bool done = false; while (!done) { int index = ObjectManager.GetSingleton().GetNextFindTargetsIndex(); if (index < ObjectManager.GetSingleton().GetNumberOfObjects()) { Mine mine = ObjectManager.GetSingleton().GetObject(index) as Mine; mine.FindCurrentTargets(); } else { done = true; } } } public int Run() { Output.LogLine("Random seed: " + RandomGen.Seed); Output.LogLine("Number of teams: " + NumberOfTeams); Output.LogLine("Number of mines per team: " + NumberOfMinesPerTeam); PerformanceTimer timer = new PerformanceTimer("Time taken in milliseconds:", Output); for (int i = 0; i < NumberOfTeams; i++) { for (int j = 0; j < NumberOfMinesPerTeam; j++) { float[] position = new float[3]; for (int k = 0; k < 3; ++k) { position[k] = RandomGen.GetRandomFloat32_Range(-1000.0f, 1000.0f); } uint objectId = RandomGen.GetRandomUint32() % (NumberOfMinesPerTeam * 10); ObjectManager.GetSingleton().AddMineObject(objectId, position, i); } } for (int i = 0; i < 10; i++) { Object obj = ObjectManager.GetSingleton().GetObject(i); if (obj != null) { float[] position = obj.GetPosition(); Output.LogF("Object id {0} position ({1}, {2}, {3}) active {4} invulnerable {5}\n", obj.ObjectId, position[0], position[1], position[2], obj.Active ? "Y" : "N", obj.Invulnerable ? "Y" : "N"); } } Output.LogF("Number of objects in system {0}. Num Detonated {1}\n", ObjectManager.GetSingleton().GetNumberOfObjects(), ObjectManager.GetSingleton().GetNumberDetonated()); int numberOfTurns = 0; bool targetsStillFound = true; while (targetsStillFound) { try { numberOfTurns++; targetsStillFound = false; ObjectManager.GetSingleton().ResetNextFindTargetIndex(); List<Thread> threads = new List<Thread>(); for (int i = 0; i < NumberOfWorkerThreads; i++) { Thread workerThread = new Thread(FindTargets); workerThread.Start(); threads.Add(workerThread); } foreach (Thread workerThread in threads) { workerThread.Join(); } for (int i = 0; i < NumberOfTeams; i++) { Mine mine = (Mine)ObjectManager.GetSingleton().GetObjectWithMostEnemyTargets(i); if (mine.GetNumberOfEnemyTargets() > 0) { targetsStillFound = true; } if (numberOfTurns < 5) { Output.LogF("Turn {0}: Team {1} picks Mine with object id {2} (with {3} targets) to explode\n", numberOfTurns, i, mine.ObjectId, mine.GetNumberOfEnemyTargets()); } mine.Explode(); } } catch (Exception e) { Output.LogLine("Exception encountered! " + e.Message); } } int winningTeam = 0; int winningObjectCount = 0; for (int i = 0; i < NumberOfTeams; i++) { Output.LogF("Team {0} has {1} mines remaining\n", i,ObjectManager.GetSingleton().GetNumberOfObjectForTeam(i)); if (ObjectManager.GetSingleton().GetNumberOfObjectForTeam(i) > winningObjectCount) { winningObjectCount = ObjectManager.GetSingleton().GetNumberOfObjectForTeam(i); winningTeam = i; } } Output.LogF("Team {0} WINS after {1} turns!!\n", winningTeam, numberOfTurns); timer.Stop(); return 0; } } } Mine-Assignment- Copy/Minefield/Minefield/Minefield.csproj Debug AnyCPU {34387370-6933-4582-A563-68804A8A0D36} Library Properties Minefield Minefield v4.5.2 512 true full false bin\Debug\ DEBUG;TRACE prompt 3 pdbonly true bin\Release\ TRACE prompt 4 Mine-Assignment- Copy/Minefield/Minefield/Object.cs using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Minefield { public class Object { public int BitFlags = 0; public int Team = 0; public enum ObjectBitFlags { Active = 0x0000, Invulnerable = 0x0002, } public int ObjectId { get; set; } public bool Active { get { return (BitFlags & (int)ObjectBitFlags.Active) != 0; } set { if (value) { BitFlags &= (int)ObjectBitFlags.Active; } else { BitFlags &= ~(int)ObjectBitFlags.Active; } } } public bool Invulnerable { get { return (BitFlags & (int)ObjectBitFlags.Invulnerable) != 0; } } public virtual float[] GetPosition() { return new float[] { 0, 0, 0 }; } public virtual void SetPosition(float[] pos) { } } } Mine-Assignment- Copy/Minefield/Minefield/ObjectManager.cs using System; using System.Linq; using System.Drawing; using System.Threading; namespace Minefield { class ObjectManager { const int cMaximumNumberOfObjects = 1000000; private static ObjectManager Instance = null; private Mutex Lock = new Mutex(); private int NumberOfObjects; public int GetNumberOfObjects() { return NumberOfObjects; } private int MinesDetonated = 0; public int GetNumberDetonated() { return MinesDetonated; } Object[] m_Objects = new Object[cMaximumNumberOfObjects]; int NextFindTargetIndex; private ObjectManager() { } public static ObjectManager GetSingleton() { if (Instance == null) { Instance = new ObjectManager(); } return Instance; } void OnMineDetonated(object sender, EventArgs e) { MinesDetonated++; RemoveObject(((Object)sender)); } public void AddMineObject(uint objectId, float[] position, int team) { Lock.WaitOne(); for (uint i = 0; i < NumberOfObjects; i++) { if (m_Objects[i].ObjectId == objectId) { // If objectId matches an existing entry then just consider it as getting updated (even potentially switched to a new team) Mine mineObject = new Mine(); mineObject.ObjectId = m_Objects[i].ObjectId; mineObject.Team = m_Objects[i].Team; mineObject.BitFlags = m_Objects[i].BitFlags; for (int j = 0; j < 3; j++) { mineObject.Position[j] = ((Mine)m_Objects[i]).Position[j]; } m_Objects[i] = mineObject; Lock.ReleaseMutex(); return; } } if (NumberOfObjects == cMaximumNumberOfObjects) { Lock.ReleaseMutex(); return; } m_Objects[NumberOfObjects] = new Mine(); m_Objects[NumberOfObjects].ObjectId = objectId; m_Objects[NumberOfObjects].Team = team; m_Objects[NumberOfObjects].SetPosition(position); ((Mine)m_Objects[NumberOfObjects]).DestructiveRadius = RandomGen.GetRandomFloat32_Range(10.0f, 100.0f); ((Mine)m_Objects[NumberOfObjects]).MineDetonated += new EventHandler(OnMineDetonated); bool active = (RandomGen.GetRandomFloat32() < .95f); m_Objects[NumberOfObjects].Active = active; if (RandomGen.GetRandomFloat32() < .1f) { m_Objects[NumberOfObjects].BitFlags = Object.ObjectBitFlags.Invulnerable; } NumberOfObjects++; Lock.ReleaseMutex(); } public void RemoveObject(Object obj) { for (uint i = 0; i < NumberOfObjects; ++i) { if (m_Objects[i].ObjectId == obj.ObjectId) { // Do a fast remove and replace this location with object currently at end m_Objects[i] = m_Objects[NumberOfObjects - 1]; m_Objects[NumberOfObjects - 1] = null; } } if (NumberOfObjects % 100 == 0) Game.Output.LogLine(String.Format("Number of objects in system {0}. Num Detonated {1}\n", NumberOfObjects, MinesDetonated)); } public Object GetObject(int index) { return m_Objects[index]; } public Object GetObjectById(int objectId) { for (uint i = 0; i < NumberOfObjects; ++i) { if (m_Objects[i].ObjectId == objectId) { return m_Objects[i]; } } return null; } public bool IsValidObject(Object obj) { for (uint i = 0; i < NumberOfObjects; ++i) { if (m_Objects[i] == obj) { return true; } } return false; } public int GetNextFindTargetsIndex() { Lock.WaitOne(); int index = NextFindTargetIndex; NextFindTargetIndex++; Lock.ReleaseMutex(); return index; } public void ResetNextFindTargetIndex() { NextFindTargetIndex = 0; } public Object GetObjectWithMostEnemyTargets(int team) { Object bestObject = null; for (uint i = 0; i < NumberOfObjects; i++) { if (m_Objects[i].Team == team) { if (bestObject == null) { bestObject = m_Objects[i]; } else if (((Mine)m_Objects[i]).GetNumberOfEnemyTargets() > ((Mine)bestObject).GetNumberOfEnemyTargets()) { bestObject = m_Objects[i]; } } } return bestObject; } public int GetNumberOfObjectForTeam(int team) { return m_Objects.Count(obj => obj?.Team == team); } } } Mine-Assignment- Copy/Minefield/Minefield/Properties/AssemblyInfo.cs using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Minefield")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("ZeniMax Online Studios")] [assembly: AssemblyProduct("Minefield")] [assembly: AssemblyCopyright("Copyright © ZeniMax Media 2019")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("34387370-6933-4582-a563-68804a8a0d36")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] Mine-Assignment- Copy/Minefield/Minefield/Random.cs using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace Minefield { internal class RandomGen { public static Random Rand = new Random(Seed); private static Int32 m_Seed = 0; public static Int32 Seed { get { return m_Seed; } private set { m_Seed = value; } } public static void SetRandomSeed(Int32 randomSeed) { Seed = randomSeed; Rand = new Random(Seed); } public static UInt32 GetRandomUint32() { return (UInt32)Rand.Next(); } public static Single GetRandomFloat32() { return (Single)Rand.NextDouble(); } public static Single GetRandomFloat32_Range(Single min, Single max) { return min + (GetRandomFloat32() * (max - min)); } } } Mine-Assignment- Copy/Minefield/Minefield/ReadMe.txt ======================================================================== Minefield Project Overview ======================================================================== This application consists of a large number of mine objects that have a unique identifier, a position, a team and can be marked as active or invulnerable. Each loop, all active mines find what other non-invulnerable mines are within their blast radius (i.e. what other mines would be damaged if it exploded). Then, for each team, the mine with the most targets is exploded. This continues until a round occurs in which no target mines were targeted/damaged by the explosion of mines from each team. The team with the most remaining mines is declared the winner. Tips: -start by making sure the code compiles cleanly -get the code to run (it does not run successfully right off the bat) -verify that the code is accomplishing its main goal correctly -look for ways to optimize the code for both performance and memory usage * there are significant gains that can be made in performance -look to enforce defensive programming (error checking and handling, etc.) -invulnerable mines cannot take damage from other mines -invulnerable mines are not targetable -inactive mines cannot be triggered to explode. They can only explode from taking too much damage -active mines, even if they are invulnerable, can be triggered to explode. -even a mine with no targets can be triggered to explode -chain reactions are possible (i.e. a fatally damaged mine will explode and damage its targets) -friendly fire is on (an exploding mine will damage both enemy and friendly targets within its destructive radius) Please comment changes and alterations to the code. Feel free to document your work and progress in the comment notes section at the top of Minefield.cs. In general, the more insight you provide into your work the better. If you try alternative approaches, even if they don't work out the way you hope, be sure to document the decision making you made along the way. Make sure that your name, the date you did this test and the amount of time taken are marked in Minefield.cs. Try to stick to the code convention that you find in the existing code. Feel free to fix any inconsistencies. Getting the exact results provided below is not a requirement to "pass" the test. We are far more interested in code fixes, cleanup, style, improvements, issues uncovered, performance considerations, etc. In a moment you'll see why getting the same as the results listed below is not even going to be possible after a certain point. The results below are provided as a guide. You should be able to replicate them after getting the code to compile and fixing any crashes. If you start to refactor or make significant changes then all bets are off. So if you consider matching the results below to be an important first step, focus on that early before making any major changes. But again, matching the results is not the end goal of this test. You do not need to match the results. You need to show us your abilities as a programmer. Focus on things that you are unhappy with in the code, its layout and structure. Explain your rationale for making those changes. In a real working environment you'd be able to ask the design intent behind how certain things work. You don't have that luxury doing this test. If there are certain things that really bug you or you're unsure how to proceed feel free to reach out to HR and ask for clarification. It's perfectly fine for you to identify the conundrum and pick what way you think it should be working. Again, document your insight and choice. And now for the reason why your results will not match the results below in the end anyway: implement the following feature additions: Mines now move. Add a velocity to each mine, with a random magnitude between zero and 10 units, in a random direction selected at time of mine creation. All mines move at the end of a turn. Feel free to design and implement this new feature in whatever way you deem most suitable. Usage of .Net Framework 4.5.2 or later is permitted. It is preferred that Visual Studio 2015 or later is used as your development environment. Visual Studio Community 2019 can be downloaded free from: http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx If another development environment is used please provide details. Note any and all performance tools and techniques used. Do not modify the existing three input parameters used. Feel free to add additional inputs if needed. The three parameters are: Random seed, Number of teams, and Number of mines per team Here are some sample results that show program output after bug fixes and initial cleanup. Again, don't obsess on these results. They are only provided as an initial goal for the cleanup portion. Random seed: 987654 Number of teams: 3 Number of mines per team: 500 Object id 1071 position (-755.938, 93.133, -556.052) active Y invulnerable N Object id 275 position (266.852, -32.735, 970.941) active Y invulnerable N Object id 934 position (570.726, -275.077, -346.969) active N invulnerable N Object id 1863 position (903.713, -300.514, 338.788) active Y invulnerable Y Object id 3885 position (331.019, 376.530, 101.836) active Y invulnerable N Object id 1470 position (-924.728, 20.487, -262.222) active Y invulnerable N Object id 3201 position (379.957, 81.881, 458.886) active Y invulnerable N Object id 2538 position (-119.712, -5.246, -345.135) active Y invulnerable N Object id 455 position (-610.912, -547.901, -254.453) active Y invulnerable N Object id 2465 position (429.587, -295.623, -74.395) active Y invulnerable N Turn 1: Team 0 picks Mine with object id 2540 (with 2 targets) to explode Turn 1: Team 1 picks Mine with object id 1104 (with 3 targets) to explode Turn 1: Team 2 picks Mine with object id 553 (with 2 targets) to explode Turn 2: Team 0 picks Mine with object id 2223 (with 2 targets) to explode Turn 2: Team 1 picks Mine with object id 358 (with 3 targets) to explode Turn 2: Team 2 picks Mine with object id 581 (with 2 targets) to explode Turn 3: Team 0 picks Mine with object id 2466 (with 1 targets) to explode Turn 3: Team 1 picks Mine with object id 4973 (with 2 targets) to explode Turn 3: Team 2 picks Mine with object id 4548 (with 2 targets) to explode Turn 4: Team 0 picks Mine with object id 53 (with 1 targets) to explode Turn 4: Team 1 picks Mine with object id 4247 (with 2 targets) to explode Turn 4: Team 2 picks Mine with object id 3923 (with 1 targets) to explode Team 0 has 357 mines remaining Team 1 has 385 mines remaining Team 2 has 424 mines remaining Team 2 WINS after 41 turns!! Random seed: 456 Number of teams: 3 Number of mines per team: 1000 Object id 5241 position (-502.488, 960.968, -673.866) active Y invulnerable N Object id 8308 position (-429.672, 251.257, -690.690) active Y invulnerable N Object id 9649 position (518.235, 635.312, -637.790) active Y invulnerable N Object id 5054 position (-410.384, -226.540, -217.858) active Y invulnerable Y Object id 2728 position (373.186, -937.465, -62.392) active Y invulnerable N Object id 8632 position (-651.196, 446.681, 638.653) active Y invulnerable N Object id 5008 position (893.620, 164.387, 108.439) active Y invulnerable N Object id 7782 position (-93.770, -602.303, 213.354) active Y invulnerable Y Object id 4858 position (-599.576, 697.088, -730.733) active Y invulnerable N Object id 507 position (698.314, 716.660, 750.904) active Y invulnerable N Turn 1: Team 0 picks Mine with object id 3398 (with 3 targets) to explode Turn 1: Team 1 picks Mine with object id 2609 (with 4 targets) to explode Turn 1: Team 2 picks Mine with object id 5427 (with 3 targets) to explode Turn 2: Team 0 picks Mine with object id 6725 (with 3 targets) to explode Turn 2: Team 1 picks Mine with object id 8415 (with 3 targets) to explode Turn 2: Team 2 picks Mine with object id 9307 (with 3 targets) to explode Turn 3: Team 0 picks Mine with object id 4314 (with 3 targets) to explode Turn 3: Team 1 picks Mine with object id 4372 (with 3 targets) to explode Turn 3: Team 2 picks Mine with object id 5106 (with 3 targets) to explode Turn 4: Team 0 picks Mine with object id 4800 (with 3 targets) to explode Turn 4: Team 1 picks Mine with object id 553 (with 3 targets) to explode Turn 4: Team 2 picks Mine with object id 8917 (with 3 targets) to explode Team 0 has 623 mines remaining Team 1 has 722 mines remaining Team 2 has 773 mines remaining Team 2 WINS after 115 turns!! Random seed: 654321 Number of teams: 5 Number of mines per team: 1500 Object id 8591 position (-898.894, -290.149, 50.030) active Y invulnerable N Object id 7110 position (-303.245, 718.965, -516.425) active Y invulnerable N Object id 1466 position (637.269, -285.511, -88.674) active Y invulnerable N Object id 10286 position (-312.755, -866.798, -53.850) active Y invulnerable N Object id 10766 position (316.465, 415.601, 571.089) active Y invulnerable N Object id 3469 position (956.990, -160.174, -141.135) active Y invulnerable N Object id 44 position (447.428, -995.504, 571.503) active N invulnerable N Object id 14905 position (-256.135, -394.987, -613.572) active Y invulnerable N Object id 14267 position (-446.510, -544.947, 657.727) active Y invulnerable N Object id 7000 position (-123.204, -670.820, 631.414) active Y invulnerable N Turn 1: Team 0 picks Mine with object id 1920 (with 6 targets) to explode Turn 1: Team 1 picks Mine with object id 1678 (with 6 targets) to explode Turn 1: Team 2 picks Mine with object id 7753 (with 6 targets) to explode Turn 1: Team 3 picks Mine with object id 7578 (with 5 targets) to explode Turn 1: Team 4 picks Mine with object id 11024 (with 8 targets) to explode Turn 2: Team 0 picks Mine with object id 947 (with 5 targets) to explode Turn 2: Team 1 picks Mine with object id 801 (with 6 targets) to explode Turn 2: Team 2 picks Mine with object id 7181 (with 6 targets) to explode Turn 2: Team 3 picks Mine with object id 1515 (with 4 targets) to explode Turn 2: Team 4 picks Mine with object id 3190 (with 6 targets) to explode Turn 3: Team 0 picks Mine with object id 13719 (with 5 targets) to explode Turn 3: Team 1 picks Mine with object id 5827 (with 6 targets) to explode Turn 3: Team 2 picks Mine with object id 9530 (with 6 targets) to explode Turn 3: Team 3 picks Mine with object id 8955 (with 4 targets) to explode Turn 3: Team 4 picks Mine with object id 9682 (with 5 targets) to explode Turn 4: Team 0 picks Mine with object id 14543 (with 5 targets) to explode Turn 4: Team 1 picks Mine with object id 10092 (with 6 targets) to explode Turn 4: Team 2 picks Mine with object id 1466 (with 4 targets) to explode Turn 4: Team 3 picks Mine with object id 13093 (with 4 targets) to explode Turn 4: Team 4 picks Mine with object id 10741 (with 5 targets) to explode Team 0 has 565 mines remaining Team 1 has 574 mines remaining Team 2 has 738 mines remaining Team 3 has 814 mines remaining Team 4 has 949 mines remaining Team 4 WINS after 278 turns!! These results were obtained on a Windows 10 PC. ///////////////////////////////////////////////////////////////////////////// Mine-Assignment- Copy/Minefield/Minefield.sln Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Minefield", "Minefield\Minefield.csproj", "{34387370-6933-4582-A563-68804A8A0D36}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {34387370-6933-4582-A563-68804A8A0D36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Debug|Any CPU.Build.0 = Debug|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Release|Any CPU.ActiveCfg = Release|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal Mine-Assignment- Copy/MinefieldCLI/MinefieldCLI/MinefieldCLI/MinefieldCLI.csproj Debug AnyCPU {45F871B1-8EB5-409B-A955-6F42E36961E0} Exe Properties MinefieldCLI MinefieldCLI v4.5.2 512 true AnyCPU true full false bin\Debug\ DEBUG;TRACE prompt 4 AnyCPU pdbonly true bin\Release\ TRACE prompt 4 {34387370-6933-4582-A563-68804A8A0D36} Minefield Mine-Assignment- Copy/MinefieldCLI/MinefieldCLI/MinefieldCLI/Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Minefield; namespace MinefieldCLI { class MinefieldCLI { private class StdOutOutput : Game.IOutputHandler { public StdOutOutput() { } public override void Log(string s) { foreach (string line in s.Split(new char[] { '\n' })) { Console.WriteLine(line); } } } static void Main(string[] args) { Game.Output = new StdOutOutput(); Game minefieldGame = new Game(); if (args.Length > 1) { minefieldGame.SetRandomSeed(Convert.ToInt32(args[1])); } if (args.Length > 2) { minefieldGame.SetNumberOfTeams(Convert.ToInt32(args[2])); } if (args.Length > 3) { minefieldGame.SetNumberOfMinesPerTeam(Convert.ToInt32(args[3])); } if (minefieldGame.Run() != 0) { Console.WriteLine("Encountered an error in game simulation!"); } Console.WriteLine("Done!"); } } } Mine-Assignment- Copy/MinefieldCLI/MinefieldCLI/MinefieldCLI/Properties/AssemblyInfo.cs using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("MinefieldCLI")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("ZeniMax Online Studios")] [assembly: AssemblyProduct("MinefieldCLI")] [assembly: AssemblyCopyright("Copyright © ZeniMax Media 2019")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("45f871b1-8eb5-409b-a955-6f42e36961e0")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] Mine-Assignment- Copy/MinefieldCLI/MinefieldCLI/MinefieldCLI.sln Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinefieldCLI", "MinefieldCLI\MinefieldCLI.csproj", "{45F871B1-8EB5-409B-A955-6F42E36961E0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Minefield", "..\..\Minefield\Minefield\Minefield.csproj", "{34387370-6933-4582-A563-68804A8A0D36}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {45F871B1-8EB5-409B-A955-6F42E36961E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {45F871B1-8EB5-409B-A955-6F42E36961E0}.Debug|Any CPU.Build.0 = Debug|Any CPU {45F871B1-8EB5-409B-A955-6F42E36961E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {45F871B1-8EB5-409B-A955-6F42E36961E0}.Release|Any CPU.Build.0 = Release|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Debug|Any CPU.Build.0 = Debug|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Release|Any CPU.ActiveCfg = Release|Any CPU {34387370-6933-4582-A563-68804A8A0D36}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal

Related Questions

Similar orders to C# Assignment. Optimize Existing Application
6
Views
0
Answers
Creating a DNS server (written in C)
WANT >=50% due to being swamped (only standard option minimal, don't care about cache or non-blocking). I require periodic updates of code with a description as there is a Git commit tracking. Also require a makefile according to the specifications and a g...
20
Views
0
Answers
Create inheritance project for a restaurant
Projects must include: -at least three different levels of inheritance - at least nine classes total -the highest superclass must have at least two methods -every subclass must contain a unique method that was not present in its super...
16
Views
0
Answers
Python Code for Suggesting Pets
Must have ___init___ ; ___str___ ; for loops ; while loops ; and must define a function which returns something, I wrote down what idea I had in that form so its best to follow it, this is an entry-level computer science project so it should be pretty easy...
22
Views
0
Answers
Quick HW Computer Science on LL(1) and object creation
Due at 12:00pm today. The question details are in the files attached. One question is on the impact of a parser being LL(1) or not. Another is on imagining a mistake in object creation. The answers are probably max 2 lines long....