Created
November 24, 2012 14:43
-
-
Save adrianseeley/4139937 to your computer and use it in GitHub Desktop.
Valhalla :: a Snippet Bundle Containing The Current Valhalla Source
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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