GameLogic
and LogicTests
(Unit Tests Project). In the first, we will write the actual logic of the game on pure C # without using the Unity namespace, the second will test our logic with the built-in test tool. Let's add the first Core class to GameLogic and write the first test to check our bundle:
public class Core { public static void Main () {} public Core () {} }
[TestClass] public class Init { [TestMethod] public void TestMethod1 () { Assert.IsInstanceOfType(new Core(), typeof(Core)); } }
public enum BuildingType { Empty, PowerPlant }
public enum ModuleType { Generator }
public class Core { public static void Main () {} public readonly Ship Ship = new Ship(); public Core () { Ship.CreateEmptyRooms(); } }
public class Ship { // public readonly int RoomsLimit = 10; private readonly List<Room> rooms = new List<Room>(); public IEnumerable<Room> Rooms { get { return rooms; } } public void CreateEmptyRooms () { for (var i = 0; i < RoomsLimit; i++) { rooms.Add(new Room(i)); } } public Room GetRoom (int index) { return rooms[index]; } }
public class Room { public readonly int Index; // public Building Building { get; set; } public Room (int index) { Index = index; // - - Building = new Building(BuildingType.Empty); } }
public class Building { // , public readonly int ModulesLimit = 10; public readonly BuildingType Type; // private readonly Dictionary<int, Module> modules = new Dictionary<int, Module>(); public IEnumerable<Module> Modules { get { return modules.Values; } } public Building (BuildingType type) { Type = type; } public Module GetModule (int position) { return modules.ContainsKey(position) ? modules[position] : null; } public void SetModule (int position, Module module) { if (position < 0 || position >= ModulesLimit) { throw new IndexOutOfRangeException( "Position " + position + " is out of range [0:" + ModulesLimit + "]" ); } modules[position] = module; } }
public class Module { public readonly ModuleType Type; public Module (ModuleType type) { Type = type; } }
public abstract class Command { public Core Core { get; private set; } public bool IsValid { get; private set; } public Command Execute (Core core) { Core = core; IsValid = Run(); return this; } protected abstract bool Run (); }
public class BuildingConstruct : Command { public readonly Room Room; public readonly Building Building; public BuildingConstruct (Room room, Building building) { Room = room; Building = building; } protected override bool Run () { // , - if (Room.Building.Type != BuildingType.Empty) { return false; } // if (Building.Type == BuildingType.Empty) { return false; } Room.Building = Building; return true; } }
public class ModuleConstruct : Command { public readonly Building Building; public readonly Module Module; public readonly int Position; public ModuleConstruct (Building building, Module module, int position) { Building = building; Module = module; Position = position; } protected override bool Run () { if (Building.Type == BuildingType.Empty) { return false; } if (Position < 0 || Position >= Building.ModulesLimit) { return false; } if (Building.GetModule(Position) != null) { return false; } Building.SetModule(Position, Module); return true; } }
[TestClass] public class Architecture { [TestMethod] public void CorrectConstruction () { var core = new Core(); var room = core.Ship.GetRoom(0); Assert.AreEqual(BuildingType.Empty, room.Building.Type); Assert.AreEqual(0, room.Building.Modules.Count()); Assert.IsTrue( new BuildingConstruct( room, new Building(BuildingType.PowerPlant) ) .Execute(core) .IsValid ); Assert.AreEqual(BuildingType.PowerPlant, room.Building.Type); Assert.AreEqual(0, room.Building.Modules.Count()); Assert.IsTrue( new ModuleConstruct( room.Building, new Module(ModuleType.Generator), 2 ) .Execute(core) .IsValid ); Assert.AreEqual(BuildingType.PowerPlant, room.Building.Type); Assert.AreEqual(ModuleType.Generator, room.Building.GetModule(2).Type); Assert.AreEqual(1, room.Building.Modules.Count()); } [TestMethod] public void IncorrectConstruction () { var core = new Core(); var room = core.Ship.GetRoom(0); Assert.IsFalse( new BuildingConstruct( room, new Building(BuildingType.Empty) ) .Execute(core) .IsValid ); Assert.IsFalse( new ModuleConstruct( room.Building, new Module(ModuleType.Generator), 2 ) .Execute(core) .IsValid ); new BuildingConstruct( room, new Building(BuildingType.PowerPlant) ) .Execute(core); Assert.IsFalse( new BuildingConstruct( room, new Building(BuildingType.PowerPlant) ) .Execute(core) .IsValid ); Assert.IsFalse( new ModuleConstruct( room.Building, new Module(ModuleType.Generator), 666 ) .Execute(core) .IsValid ); } }
class BuildingConfig
" and " class ModuleConfig
", they will keep all the settings of our facilities.
// public class BuildingConfig { public BuildingType Type; // public int ModulesLimit; // public ModuleType[] AvailableModules; }
public class ModuleConfig { public ModuleType Type; }
public class Building { // ... public readonly BuildingConfig Config; // ... // , public Building (BuildingConfig config) { Type = config.Type; ModulesLimit = config.ModulesLimit; Config = config; } }
public class Module { // ... public readonly ModuleConfig Config; // , public Module (ModuleConfig config) { // ... Type = config.Type; Config = config; } }
public class Factory { public Building ProduceBuilding (BuildingType type) { throw new Exception("Not implemented yet"); } public Module ProduceModule (ModuleType type) { throw new Exception("Not implemented yet"); } }
// : public class Core { // ... public readonly Factory Factory = new Factory(); public Core () { // Ship.CreateEmptyRooms(Factory); } }
// : public class Ship { // ... public void CreateEmptyRooms (Factory factory) { for (var i = 0; i < RoomsLimit; i++) { rooms.Add(new Room(i, factory.ProduceBuilding(BuildingType.Empty))); } }
// - -: public class Room { // ... public Room (int index, Building building) { Index = index; Building = building; } }
// new Building(Type); // core.Factory.ProduceBuilding(Type);
// new Module(Type); // core.Factory.ProduceModule(Type);
"Not implemented yet"
. To do this, go back to our factory and implement several buildings and modules. public class Factory { private readonly Dictionary<BuildingType, BuildingConfig> buildings = new Dictionary<BuildingType, BuildingConfig>() { { BuildingType.Empty, new BuildingConfig() { Type = BuildingType.Empty }}, { BuildingType.PowerPlant, new BuildingConfig() { Type = BuildingType.PowerPlant, ModulesLimit = 5, AvailableModules = new[]{ ModuleType.Generator } }}, { BuildingType.Smeltery, new BuildingConfig() { Type = BuildingType.Smeltery, ModulesLimit = 4, AvailableModules = new[]{ ModuleType.Furnace } }}, { BuildingType.Roboport, new BuildingConfig() { Type = BuildingType.Roboport, ModulesLimit = 3, AvailableModules = new[]{ ModuleType.Digger, ModuleType.Miner } }} }; private readonly Dictionary<ModuleType, ModuleConfig> modules = new Dictionary<ModuleType, ModuleConfig>() { { ModuleType.Generator, new ModuleConfig() { Type = ModuleType.Generator }}, { ModuleType.Furnace, new ModuleConfig() { Type = ModuleType.Furnace }}, { ModuleType.Digger, new ModuleConfig() { Type = ModuleType.Digger }}, { ModuleType.Miner, new ModuleConfig() { Type = ModuleType.Miner }} }; public Building ProduceBuilding (BuildingType type) { if (!buildings.ContainsKey(type)) { throw new ArgumentException("Unknown building type: " + type); } return new Building(buildings[type]); } public Module ProduceModule (ModuleType type) { if (!modules.ContainsKey(type)) { throw new ArgumentException("Unknown module type: " + type); } return new Module(modules[type]); } }
[TestMethod] public void CantConstructInWrongBuilding () { var core = new GameLogic.Core(); var room = core.Ship.GetRoom(0); new BuildingConstruct( room, core.Factory.ProduceBuilding(BuildingType.PowerPlant) ) .Execute(core); Assert.IsFalse( new ModuleConstruct( room.Building, core.Factory.ProduceModule(ModuleType.Furnace), 2 ) .Execute(core) .IsValid ); Assert.AreEqual(null, room.Building.GetModule(2)); }
public class ModuleConstruct : Command { // ... protected override bool Run () { // ... if (!Building.Config.AvailableModules.Contains(Module.Type)) { return false; } // ...
[TestMethod] public void ModulesLimits () { var core = new GameLogic.Core(); var roomRoboport = core.Ship.GetRoom(0); var roomPowerPlant = core.Ship.GetRoom(1); Assert.IsTrue( new BuildingConstruct( roomRoboport, core.Factory.ProduceBuilding(BuildingType.Roboport) ) .Execute(core) .IsValid ); Assert.IsTrue( new BuildingConstruct( roomPowerPlant, core.Factory.ProduceBuilding(BuildingType.PowerPlant) ) .Execute(core) .IsValid ); Assert.IsFalse( new ModuleConstruct( roomRoboport.Building, core.Factory.ProduceModule(ModuleType.Miner), 3 ) .Execute(core) .IsValid ); Assert.IsTrue( new ModuleConstruct( roomPowerPlant.Building, core.Factory.ProduceModule(ModuleType.Generator), 3 ) .Execute(core) .IsValid ); }
public class Turns { public int CurrentTurn { get; private set; } internal void NextTurn () { CurrentTurn++; } }
public class Core { public readonly Turns Turns = new Turns(); }
public class NextTurn : Command { protected override bool Run () { // Core.Turns.NextTurn(); return true; } }
public class NextTurnCount : Command { public const int Max = 32; public readonly int Count; public NextTurnCount (int count) { Count = count; } protected override bool Run () { if (Count < 0 || Count > Max) { return false; } for (var i = 0; i < Count; i++) { var nextTurn = new NextTurn().Execute(Core); if (!nextTurn.IsValid) return false; } return true; } }
[TestClass] public class Turns { [TestMethod] public void NextTurnsCommand () { var core = new Core(); Assert.AreEqual(0, core.Turns.CurrentTurn); Assert.IsTrue( new NextTurnCount(4) .Execute(core) .IsValid ); Assert.AreEqual(4, core.Turns.CurrentTurn); } }
public class TimeWarp { public readonly int Speed_Stop = 0; public readonly int Speed_X1 = 1000; public readonly int Speed_X2 = 500; public readonly int Speed_X5 = 200; public readonly Core Core; private int currentSpeed; public int currentTime { get; private set; } public TimeWarp (Core core) { currentSpeed = Speed_Stop; Core = core; } public void SetSpeed (int speed) { currentSpeed = speed; currentTime = Math.Min(speed, currentTime); } public int GetSpeed () { return currentSpeed; } public bool IsStopped () { return currentSpeed == Speed_Stop; } public void AddTime (int ms) { if (IsStopped()) return; currentTime += ms; // // while (currentTime >= currentSpeed) NextTurn // ? // 20 if (currentTime < currentSpeed) return; currentTime -= currentSpeed; new NextTurn().Execute(ore); } }
[TestMethod] public void TimeWarp () { var core = new Core(); var time = new TimeWarp(core); Assert.AreEqual(0, core.Turns.CurrentTurn); time.SetSpeed(time.Speed_X5); time.AddTime(50); time.AddTime(50); time.AddTime(50); time.AddTime(50); Assert.AreEqual(1, core.Turns.CurrentTurn); time.AddTime(199); Assert.AreEqual(1, core.Turns.CurrentTurn); time.AddTime(1); Assert.AreEqual(2, core.Turns.CurrentTurn); }
public TimeComponent : MonoBehaviour { public TimeWarp timeWarp; public void Awake () { timeWarp = ...; // } public void Update () { timeWarp.AddTime( Time.deltaTime ); } }
Source: https://habr.com/ru/post/322258/
All Articles