Skip to content

Instantly share code, notes, and snippets.

@adrianseeley
Created November 24, 2012 14:43
Show Gist options
  • Select an option

  • Save adrianseeley/4139937 to your computer and use it in GitHub Desktop.

Select an option

Save adrianseeley/4139937 to your computer and use it in GitHub Desktop.
Valhalla :: a Snippet Bundle Containing The Current Valhalla Source
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Drawing;
using Microsoft.CSharp;
namespace valhalla_compiler
{
class Program
{
static List<String> to_compile = new List<String>() { "agent_source.prefix" };
static bool flag_compiler_notified_sleep = false;
static String source_prefix = "";
static String source_postfix = "";
static void Main(string[] args)
{
new Thread(new ThreadStart(compiler)).Start();
}
static void compiler()
{
while (true)
{
if (to_compile.Count == 0)
{
if (!flag_compiler_notified_sleep)
{
Console.WriteLine("compiler: no one in line, sleeping...");
flag_compiler_notified_sleep = true;
}
Thread.Sleep(1000);
}
else
{
flag_compiler_notified_sleep = false;
Console.WriteLine("compiler: " + to_compile.Count + " in line");
String agent_to_compile = to_compile[0];
to_compile.RemoveAt(0);
Console.WriteLine("compiler: took '" + agent_to_compile + "' from the front of the line");
Directory.CreateDirectory("slugs/");
try
{
Assembly assembly = null;
using (FileStream fs = File.Open(agent_to_compile, FileMode.Open))
{
using (StreamReader sr = new StreamReader(fs))
{
CSharpCodeProvider csharp_code_provider = new CSharpCodeProvider();
CompilerParameters compiler_parameters = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = false, TreatWarningsAsErrors = false, OutputAssembly = "slugs/" + agent_to_compile };
Assembly executing_assembly = Assembly.GetExecutingAssembly();
compiler_parameters.ReferencedAssemblies.Add(executing_assembly.Location);
compiler_parameters.ReferencedAssemblies.Add("mscorlib.dll");
compiler_parameters.ReferencedAssemblies.Add("System.Core.dll");
compiler_parameters.ReferencedAssemblies.Add("System.dll");
compiler_parameters.ReferencedAssemblies.Add("System.Drawing.dll");
compiler_parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
CompilerResults compiler_results = csharp_code_provider.CompileAssemblyFromSource(compiler_parameters, source_prefix + sr.ReadToEnd() + source_postfix);
if (compiler_results.Errors.Count > 0)
{
String compile_errors = "";
foreach (CompilerError compile_error in compiler_results.Errors) compile_errors += compile_error.ToString() +"\n\r";
Console.WriteLine(compile_errors);
}
else
{
assembly = compiler_results.CompiledAssembly;
}
}
}
//assembly holds what?
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
}
}
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class Main extends Sprite
{
private var loaded_matches :Array = new Array();
private var playback_match :Number = 0;
private var playback_frame :Number = 0;
private var draw :BitmapData = new BitmapData(1280, 1000, true);
private var draw_container :Bitmap = new Bitmap(draw);
public function Main():void
{
addChild(draw_container);
load_match("matches/broadcast.0.match");
load_match("matches/broadcast.1.match");
load_match("matches/broadcast.2.match");
}
public function load_match(path:String):void
{
var loader = new URLLoader(new URLRequest(path));loader.addEventListener(Event.COMPLETE, load_complete);
}
public function load_complete(e:Event):void
{
trace("loaded");
var target :URLLoader = e.target as URLLoader;
var string_frames :Array = (target.data as String).split("\r\n");
var json_frames :Array = new Array();
for (var f:int = 0; f < string_frames.length; f++) if(string_frames[f] != "") json_frames.push(JSON.parse(string_frames[f]));
loaded_matches.push(json_frames);
addEventListener(Event.ENTER_FRAME, per_frame);
}
public function per_frame(e:Event):void
{
draw_match_frame();
if (playback_frame < loaded_matches[playback_match].length - 1)
{
playback_frame++;
}
else
{
playback_frame = 0;
if (playback_match < loaded_matches.length - 1)
{
playback_match++;
}
else
{
playback_match = 0;
}
}
//trace("match " + playback_match);
}
public function draw_match_frame():void
{
draw.fillRect(new Rectangle(0, 0, 1000, 1000), 0xFFEEEEEE);
for (var s:int = 0; s < loaded_matches[playback_match][playback_frame].shp.length; s++)
{
var ship:Object = loaded_matches[playback_match][playback_frame].shp[s];
draw.fillRect(new Rectangle((ship.x * 10) - 12.5, (ship.y * 10) - 12.5, 25, 25), 0xFF000000);
draw.fillRect(new Rectangle((ship.x * 10) - 11.5, (ship.y * 10) - 11.5, 23, 23), parseInt("0x" + ship.c));
}
for (var l:int = 0; l < loaded_matches[playback_match][playback_frame].lsr.length; l++)
{
var laser:Object = loaded_matches[playback_match][playback_frame].lsr[l];
draw.fillRect(new Rectangle((laser.x * 10) - 5, (laser.y * 10) - 5, 10, 10), 0xFF000000);
draw.fillRect(new Rectangle((laser.x * 10) - 4, (laser.y * 10) - 4, 8, 8), 0xFFEEEEEE);
}
draw.fillRect(new Rectangle(1000, 0, 280, 1000), 0xFF777777);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Drawing;
namespace valhalla_runner
{
class Program
{
public static long broadcast_index = 0;
public static Random random = new Random();
static List<Game> to_play = new List<Game>() { new Game(), new Game(), new Game() };
static bool flag_runner_notified_sleep = false;
static HashSet<Agent> agents = new HashSet<Agent>();
static void Main(string[] args)
{
for (int a = 0; a < 100; a++) agents.Add(new Agent());
new Thread(new ThreadStart(runner)).Start();
}
static void runner()
{
while (true)
{
if (to_play.Count == 0)
{
if (!flag_runner_notified_sleep)
{
Console.WriteLine("runner: no one in line, sleeping...");
flag_runner_notified_sleep = true;
}
Thread.Sleep(1000);
}
else
{
flag_runner_notified_sleep = false;
Console.WriteLine("runner: " + to_play.Count + " in line");
Game game_to_play = to_play[0];
to_play.RemoveAt(0);
game_to_play.reset(agents);
Console.WriteLine("runner: took '" + game_to_play.headline + "' from the front of the line");
Console.WriteLine("runner: starting game loop for '" + game_to_play.headline + "'");
Directory.CreateDirectory("matches/");
using (FileStream fs = File.Create("matches/broadcast." + broadcast_index + ".match"))
{
using (StreamWriter sw = new StreamWriter(fs))
{
Console.Write("[start]-");
while (game_to_play.ships.Count > 1 && game_to_play.frame < Game.frame_timeout)
{
Console.Write(game_to_play.frame + "-");
sw.WriteLine(game_to_play.ToString());
game_to_play.run_one();
Thread.Sleep(10);
}
Console.WriteLine("[end]");
}
}
if (game_to_play.ships.Count != 1) Console.WriteLine("runner: game '" + game_to_play.headline + "' complete, draw");
else Console.WriteLine("runner: game '" + game_to_play.headline + "' complete, winner '" + game_to_play.ships.ElementAt(0).agent.unique_name + "'");
Console.WriteLine("runner: game '" + game_to_play.headline + "' saved as 'matches/broadcast." + broadcast_index + ".match'");
broadcast_index++;
}
}
}
}
class Game
{
public const long frame_timeout = 1800; // 30 secs at 60fps
public const float arena_size = 100;
public String headline;
public HashSet<Ship> ships;
public List<Ship> graveyard;
public HashSet<Laser> lasers;
public long frame;
public void reset(HashSet<Agent> Agents)
{
headline = ""; for(int a = 0; a < Agents.Count; a++) headline += Agents.ElementAt(a).unique_name + (a != Agents.Count - 1 ? " vs " : "");
ships = new HashSet<Ship>();
graveyard = new List<Ship>();
lasers = new HashSet<Laser>() {};
frame = 0;
// load agents into ships, place ships at random locations in arena
for (int a = 0; a < Agents.Count; a++) ships.Add(new Ship(Program.random.Next(0, (int)arena_size), Program.random.Next(0, (int)arena_size), Agents.ElementAt(a)));
}
public void run_one()
{
HashSet<Ship> cull_ships = new HashSet<Ship>(); // reset cull ships list
HashSet<Laser> cull_lasers = new HashSet<Laser>(); // reset cull lasers list
for (int s = 0; s < ships.Count; s++) ships.ElementAt(s).logic(new Awareness(ships, lasers), this); // do ships logic
for (int l = 0; l < lasers.Count; l++) if (lasers.ElementAt(l).update(this)) cull_lasers.Add(lasers.ElementAt(l)); // update lasers, build laser cull list
for (int s = 0; s < ships.Count; s++) if (ships.ElementAt(s).update(this)) cull_ships.Add(ships.ElementAt(s)); // update ships, build ship cull list
for (int cs = 0; cs < cull_ships.Count; cs++) { ships.Remove(cull_ships.ElementAt(cs)); graveyard.Add(cull_ships.ElementAt(cs)); } // move culled ships to graveyard
for (int cl = 0; cl < cull_lasers.Count; cl++) lasers.Remove(cull_lasers.ElementAt(cl)); // just remove culled lasers
frame++;
}
public override string ToString()
{
string
ret = "{";
ret += "\"h\": \"" + headline + "\", ";
ret += "\"f\": " + frame + ", ";
ret += "\"shp\": [";
for (int s = 0; s < ships.Count; s++) ret += ships.ElementAt(s).ToString() + (s == ships.Count - 1 ? "" : ",");
ret += "], \"lsr\": [";
for (int l = 0; l < lasers.Count; l++) ret += lasers.ElementAt(l).ToString() + (l == lasers.Count - 1 ? "" : ",");
ret += "]}";
return ret;
}
}
class Game_Object
{
public float x;
public float y;
public float velocity_x;
public float velocity_y;
public const float velocity_maximum = 1;
public Game_Object(float X, float Y, float Velocity_X, float Velocity_Y)
{
x = X;
y = Y;
velocity_x = Velocity_X;
velocity_y = Velocity_Y;
}
public virtual bool update(Game game)
{
float velocity_attempted = magnitude(velocity_x, velocity_y);
if (velocity_attempted > velocity_maximum)
{
velocity_x /= velocity_attempted;
velocity_y /= velocity_attempted;
velocity_x *= velocity_maximum;
velocity_y *= velocity_maximum;
velocity_attempted = velocity_maximum;
}
x += velocity_x;
y += velocity_y;
bool collide_wall = false;
if (x < 0) { x = 0; collide_wall = true; }
if (x > Game.arena_size) { x = Game.arena_size; collide_wall = true; }
if (y < 0) { y = 0; collide_wall = true; }
if (y > Game.arena_size) { y = Game.arena_size; collide_wall = true; }
bool wall_collision_destroyed_object = false;
if (collide_wall) wall_collision_destroyed_object = collide_wall_response();
bool laser_collision_destroyed_object = false;
for (int l = 0; l < game.lasers.Count; l++)
{
if (this != game.lasers.ElementAt(l))
{
if (this is Laser)
{
if (this.is_colliding_with(game.lasers.ElementAt(l), 1))
{
laser_collision_destroyed_object = collide_laser_response();
}
}
else
{
if (this.is_colliding_with(game.lasers.ElementAt(l), 3))
{
laser_collision_destroyed_object = collide_laser_response();
}
}
}
}
bool ship_collision_destroyed_object = false;
for (int s = 0; s < game.ships.Count; s++)
{
if (this != game.ships.ElementAt(s))
{
if (this.is_colliding_with(game.ships.ElementAt(s), 3))
{
ship_collision_destroyed_object = collide_ship_response();
}
}
}
return wall_collision_destroyed_object || laser_collision_destroyed_object || ship_collision_destroyed_object;
}
public bool is_colliding_with(Game_Object candidate, float collide_range)
{
if (distance(this, candidate) <= collide_range) return true;
else return false;
}
public float magnitude(float a, float b)
{
return (float)Math.Sqrt((a * a) + (b * b));
}
public float distance(Game_Object a, Game_Object b)
{
return (float)Math.Sqrt(Math.Pow(b.x - a.x, 2) + Math.Pow(b.y - a.y, 2));
}
public virtual bool collide_wall_response() { return false; }
public virtual bool collide_laser_response() { return true; }
public virtual bool collide_ship_response() { return false; }
}
class Ship : Game_Object
{
public const float acceleration_scale = 0.01f;
public Agent agent;
public Ship(float X, float Y, Agent Agent)
: base(X: X, Y: Y, Velocity_X: 0, Velocity_Y: 0)
{
agent = Agent;
}
public void logic(Awareness awareness, Game game)
{
Action agent_action = agent.get_action(awareness);
if (agent_action.angle < 0 || agent_action.angle > 1 || float.IsInfinity(agent_action.angle) || float.IsNaN(agent_action.angle)) throw new Exception("Agent " + agent.unique_name + " requested an angle that is not between 0 and 1 (inclusive; meaning 0 and 1 are acceptable values)");
switch (agent_action.move_or_shoot_or_none)
{
default: throw new Exception("Agent " + agent.unique_name + " requested an action that does not exist, or was not recognized. Use Move_or_Shoot_or_None.Move or .Shoot or .None");
case Move_or_Shoot_or_None.Move:
velocity_x += (float)Math.Cos(agent_action.angle * Math.PI * 2) * acceleration_scale;
velocity_y += (float)Math.Sin(agent_action.angle * Math.PI * 2) * acceleration_scale;
break;
case Move_or_Shoot_or_None.Shoot:
Laser fired = new Laser(X: x + ((float)Math.Cos(agent_action.angle * Math.PI * 2) * 3), Y: y + ((float)Math.Sin(agent_action.angle * Math.PI * 2) * 3), Velocity_X: velocity_x +((float)Math.Cos(agent_action.angle * Math.PI * 2) * 0.5f), Velocity_Y: velocity_y + ((float)Math.Sin(agent_action.angle * Math.PI * 2) * 0.5f));
game.lasers.Add(fired);
break;
case Move_or_Shoot_or_None.None:
break;
}
}
public override string ToString() { return "{" + "\"t\": \"s\", \"a\": \"" + agent.unique_name + "\", \"c\": \"" + agent.color.Name + "\", \"x\": " + x + ", \"y\": " + y + ", \"vx\": " + velocity_x + ", \"vy\": " + velocity_y + "}"; }
}
class Laser : Game_Object
{
public Laser(float X, float Y, float Velocity_X, float Velocity_Y)
: base(X: X, Y: Y, Velocity_X: Velocity_X, Velocity_Y: Velocity_Y)
{
}
public override bool update(Game game)
{
velocity_x *= 1.002f;
velocity_y *= 1.002f;
return base.update(game);
}
public override bool collide_wall_response() { return true; }
public override bool collide_ship_response() { return true; }
public override string ToString() { return "{" + "\"t\": \"l\", \"x\": " + x + ", \"y\": " + y + ", \"vx\": " + velocity_x + ", \"vy\": " + velocity_y + "}"; }
}
class Awareness
{
public HashSet<Ship> ships;
public HashSet<Laser> lasers;
public Awareness(HashSet<Ship> Ships, HashSet<Laser> Lasers)
{
ships = Ships;
lasers = Lasers;
}
}
class Agent
{
public String unique_name = "test name" + Program.random.Next(0, 10).ToString();
public Color color = Color.FromArgb(Program.random.Next(0, 255), Program.random.Next(0, 255), Program.random.Next(0, 255));
public String source_code;
public String compiled_dll_path;
public Action get_action(Awareness awareness)
{
return new Action(Program.random.Next(0, 100) > 99 ? Move_or_Shoot_or_None.Shoot : Move_or_Shoot_or_None.Move, (float)Program.random.NextDouble());
}
}
enum Move_or_Shoot_or_None { Move, Shoot, None };
class Action
{
public Move_or_Shoot_or_None move_or_shoot_or_none = Move_or_Shoot_or_None.None;
public float angle = 0;
public Action(Move_or_Shoot_or_None Move_or_Shoot_or_None, float Angle)
{
move_or_shoot_or_none = Move_or_Shoot_or_None;
angle = Angle;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment