A while ago me and a friend had an idea for a computer game. You would control a collection of bacteria all which needed to feed and would die of old age given enough time. They could also reproduce in order of keep their population going and fight enemy bacteria population controlled by an other player. The aim of the game was from your bacteria to out compete the other players bacteria on the map. So far so unoriginal, our new idea was that rather than controlling the creatures through say using a mouse and keyboard to give them orders you would instead controls them by writing the code for how they behaved. It would be a real time competitive programming game.
The game interface would be a map with a text panel on the right where the user would enter code that the creatures would execute to make their decisions. There were commands for where to move, what to eat, when to breed, etc. This was also a really nice space from which to play with algorithms like neural nets, evolutionary algorithms, clustering, A*, etc. We played around with it a bit and had a fair amount of fun, but we eventually realized that even for us who had built it, the game was too complicated for anyone to actually play. At least not in real time. So we abandoned it as a fun experiment.
But I recently saw this post on stack overflow that reminded me of that game. So I thought I would share some of the code for how to do in application code compilation in .Net. Hopefully it will be of use to some people and maybe even if I get enough interest I may try and clean up the rest of the code and release it as an open source project. Because despite being painfully complicated, when it did work it was fun, at least for uber nerds like us.
RunTimeTypeCreator
Here is the one and only method in the lib method:
public static T CreateType(string source,
IEnumerable assemblies,
out List compilationErrors)
where T : class
It will attempt to create an instance of the type T from the source passed in. The source will be compiled with references to all the assemblies in the assemblies parameter. So for example you could do this with it.
namespace RunTimeTypeCreator.Tests
{
public interface ITestType
{
bool Success { get; }
}
public class RunTimeTypeCreatorTests
{
public static bool TestVariable = false;
public void Example()
{
const string source = @"
using RunTimeTypeCreator.Tests;
public class TestTypeClass : RunTimeTypeCreatorTests.ITestType
{
public bool Success { get { return RunTimeTypeCreatorTests.TestVariable; } }
}";
List compilationErrors;
var type = RunTimeTypeCreator.CreateType(source,
new[] { "RunTimeTypeCreator.Tests.dll" }, //the name of this assembly
out compilationErrors);
TestVariable = false;
//will print true
Console.WriteLine(type.Success)
//will print false
TestVariable = true;
Console.WriteLine(type.Success)
}
}
}
Which is kind of cool I think. Here’s a quick run through of how it works, this just shows the code minus bits of validation and error reporting, so if you want the full thing I would recommend getting it from github
var csc = new CSharpCodeProvider();
var parameters = new CompilerParameters
{
//we don't want a physical executable in this case
GenerateExecutable = false,
//this is what allows it to access variables in our domain
GenerateInMemory = true
};
//add all the assmeblies we care about
foreach (var assembly in assemblies)
parameters.ReferencedAssemblies.Add(assembly);
//compile away, will load the class into memory
var result = csc.CompileAssemblyFromSource(parameters, source);
//we compiled succesfully so now just use reflection to get the type we want
var types = result.CompiledAssembly.GetTypes()
.Where(x => typeof(T).IsAssignableFrom(x)).ToList();
//create the type and return
return (T)Activator.CreateInstance(types.First());
I also had some other code around validating what the user was doing, Making sure they weren’t trying to access the file system, open ports or creating memory leaks/recursive loops. I’ll try and clean this up and post it at a future date.
Full code is available here on github.
A while ago me and a friend had an idea for a computer game. You would control a collection of bacteria all which needed to feed and would die of old age given enough time bus driving simulator
Then bellow that, a tab button should appear saying disk cleanup. Click that then wait for a new window to open. When it does, make sure all the boxes are checked with a tick, and then hit ok. Then a computer prompt will appear about deleting these files, you click ok. gtx 1060 comparable