public static int Main(string[] args) { for (int i = 0; i < args.Length; i++) { if (string.Equals(args[i], "train", StringComparison.OrdinalIgnoreCase)) { // train the model var type = i + 1 < args.Length ? args[i + 1] : ""; var directory = i + 2 < args.Length ? args[i + 2] : ""; return(ModelBuilding.TrainAndEvaulate(type, directory)); } else if (string.Equals(args[i], "check", StringComparison.OrdinalIgnoreCase)) { // purge the input var type = i + 1 < args.Length ? args[i + 1] : ""; var directory = i + 2 < args.Length ? args[i + 2] : ""; return(ModelBuilding.Check(type, directory)); } else if (string.Equals(args[i], "purge", StringComparison.OrdinalIgnoreCase)) { // purge the input var directory = i + 1 < args.Length ? args[i + 1] : ""; var deleted = Purge.Execute(directory); if (deleted >= 0) { return(0); } } else if (string.Equals(args[i], "run", StringComparison.OrdinalIgnoreCase)) { // do a trial run var type = i + 1 < args.Length ? args[i + 1] : ""; return(Executor.Run(type)); } else if (string.Equals(args[i], "test", StringComparison.OrdinalIgnoreCase)) { float x1, y1; float xdelta, ydelta; foreach (var angle in new float[] { 0, 45, 90, 135, 180, 225, 270, 315, 359 }) { Collision.CalculateLineByAngle(0, 0, angle, 1, out x1, out y1, out xdelta, out ydelta); var sum = (float)(Math.Abs(xdelta) + Math.Abs(ydelta)); xdelta = xdelta / sum; ydelta = ydelta / sum; Console.WriteLine("0: {0} {1},{2}", angle, xdelta, ydelta); } foreach (var pair in new float[][] { new float[] { 1, 0 }, new float[] { 0, 1 }, new float[] { -1, 0 }, new float[] { 0, -1 }, new float[] { 0.5f, 0.5f }, new float[] { -0.5f, 0.5f }, new float[] { 0.5f, -0.5f }, new float[] { -0.5f, -0.5f } } ) { var angle = Collision.CalculateAngleFromPoint(0, 0, pair[0], pair[1]); Console.WriteLine("1: {0} {1},{2}", angle, pair[0], pair[1]); } return(0); } else if (string.Equals(args[i], "serialize", StringComparison.OrdinalIgnoreCase)) { var count = Convert.ToInt32(i + 1 < args.Length ? args[i + 1] : "0"); var type = i + 2 < args.Length ? args[i + 2] : ""; var directory = i + 3 < args.Length ? args[i + 3] : ""; return(ModelBuilding.Serialize(directory, type, count)); } } // the verb was not understood return(Usage()); }
public bool TakeAction(Player player, ref char key) { if (!(player is MooPlayer)) { return(false); } var mp = player as MooPlayer; switch (key) { case Constants.Space: // no longer able to use the space bar to get resources return(true); case '3': // craft wood block // check if there is enough wood materials if (mp.Wood < MooWoodBox.WoodCraftCost || mp.Level < MooWoodBox.LevelCraftCost) { return(FailedToCraft()); } // use wood to craft a box mp.Wood -= MooWoodBox.WoodCraftCost; // if there is room in the hand (put in hand) // else drop on the ground var wood = new MooWoodBox() { X = player.X, Y = player.Y }; // the health of this box increases with level if (mp.Level > MooPlayer.MaxLevel) { wood.Health += wood.Health; } else { wood.Health += wood.Health * ((float)mp.Level / (float)MooPlayer.MaxLevel); } if (!player.Take(wood)) { World.AddItem(wood); } return(true); case '4': // craft rock block // check if there is enough wood materials if (mp.Rock < MooRockBox.RockCraftCost || mp.Level < MooRockBox.LeelCraftCost) { return(FailedToCraft()); } // use rock to craft a box mp.Rock -= MooRockBox.RockCraftCost; // if there is room in the hand (put in hand) // else drop on the ground var rock = new MooRockBox() { X = player.X, Y = player.Y }; // the health of this box increases with level if (mp.Level > MooPlayer.MaxLevel) { rock.Health *= rock.Health; } else { rock.Health *= rock.Health * ((float)mp.Level / (float)MooPlayer.MaxLevel); } if (!player.Take(rock)) { World.AddItem(rock); } return(true); case '5': // craft bow or arrows if (mp.Primary is MooBow) { if (mp.Wood < MooBow.WoodCraftCost) { return(FailedToCraft()); } // add arrows mp.Wood -= MooBow.WoodCraftCost; (mp.Primary as MooBow).AddAmmo(MooBow.ArrowChunk); (mp.Primary as MooBow).Reload(); return(true); } // check if there is enough wood materials if (mp.Rock < MooBow.RockCraftCost || mp.Wood < MooBow.WoodCraftCost || mp.Level < MooBow.LevelCraftCost) { return(FailedToCraft()); } // use wood and rock to craft a bow mp.Rock -= MooBow.RockCraftCost; mp.Wood -= MooBow.WoodCraftCost; // if there is room in the hand (put in hand) // else drop on the ground var bow = new MooBow() { X = player.X, Y = player.Y }; if (!player.Take(bow)) { World.AddItem(bow); } return(true); case '6': // craft sword // check if there is enough wood materials if (mp.Rock < MooSword.RockCraftCost || mp.Wood < MooSword.WoodCraftCost || mp.Level < MooSword.LevelCraftCost) { return(FailedToCraft()); } // use wood and rock to craft a sword mp.Rock -= MooSword.RockCraftCost; mp.Wood -= MooSword.WoodCraftCost; // if there is room in the hand (put in hand) // else drop on the ground var sword = new MooSword() { X = player.X, Y = player.Y }; if (!player.Take(sword)) { World.AddItem(sword); } return(true); case '7': // craft turret // check if there is enough wood materials if (mp.Rock < MooTurret.RockCraftCost || mp.Wood < MooTurret.WoodCraftCost || mp.Food < MooTurret.FoodCraftCost || mp.Level < MooTurret.LevelCraftCost) { return(FailedToCraft()); } // use wood and rock to craft a turret mp.Rock -= MooTurret.RockCraftCost; mp.Wood -= MooTurret.WoodCraftCost; mp.Food -= MooTurret.FoodCraftCost; // place it directly on the ground here float x1, y1, x2, y2; Collision.CalculateLineByAngle(player.X, player.Y, player.Angle, player.Width, out x1, out y1, out x2, out y2); var turret = new MooTurret() { X = x2, Y = y2 }; World.AddItem(turret); return(true); case 'r': case 'R': // eat to increase health if (mp.Health < Constants.MaxHealth) { if (mp.Food > 0) { mp.Health += MooFood.HealthPerFood; mp.Food -= 1; } } return(true); case 'z': case 'Z': var rand = new Random(); var horde = MooZombie.HordeSize + ((MooZombie.HordeSize * MooZombie.HordeSize) * ((float)mp.Level / (float)MooPlayer.MaxLevel)); // only add so many zombies var current = World.Alive; var maxhorde = 1000; if (current > maxhorde) { return(true); } if (current + horde > maxhorde) { horde = maxhorde - current; } var minhealth = 25; var maxhealth = 50 * ((float)mp.Level / (float)MooPlayer.MaxLevel); if (maxhealth <= 0) { maxhealth = 1; } // span a zombie horde for (int i = 0; i < horde; i++) { var x = rand.Next() % World.Width; var y = rand.Next() % World.Height; float s = (float)(rand.Next() % 10) / 10f + 0.1f; float h = (float)(rand.Next() % maxhealth) + minhealth; var large = false; if (mp.Level > 10 && rand.Next() % 10 == 0) { s = s + s * 1.5f; h = Constants.MaxHealth; large = true; } var zombie = new MooZombie(Human) { X = x, Y = y, Speed = s, Health = h, IsLarge = large }; World.AddItem(zombie); } return(true); case Constants.LeftMouse: // place the block if (mp.Primary != null && mp.Primary is MooCraftable) { var item = mp.DropPrimary() as MooCraftable; item.Place(mp); World.AddItem(item); return(true); } break; } return(false); }
public void Paint() { // draw the map Background.Draw(Surface); // add center indicator if (Human.Z == Constants.Ground) { var centerAngle = Collision.CalculateAngleFromPoint(Human.X, Human.Y, Background.X, Background.Y); float x1, y1, x2, y2; var distance = Math.Min(Surface.Width, Surface.Height) * 0.9f; Collision.CalculateLineByAngle(Surface.Width / 2, Surface.Height / 2, centerAngle, (distance / 2), out x1, out y1, out x2, out y2); Surface.DisableTranslation(); { // draw an arrow var endX = x2; var endY = y2; x1 = endX; y1 = endY; Collision.CalculateLineByAngle(x1, y1, (centerAngle + 180) % 360, 50, out x1, out y1, out x2, out y2); Surface.Line(RGBA.Black, x1, y1, x2, y2, 10); x1 = endX; y1 = endY; Collision.CalculateLineByAngle(x1, y1, (centerAngle + 135) % 360, 25, out x1, out y1, out x2, out y2); Surface.Line(RGBA.Black, x1, y1, x2, y2, 10); x1 = endX; y1 = endY; Collision.CalculateLineByAngle(x1, y1, (centerAngle + 225) % 360, 25, out x1, out y1, out x2, out y2); Surface.Line(RGBA.Black, x1, y1, x2, y2, 10); } Surface.EnableTranslation(); } // draw all elements var hidden = new HashSet <int>(); var visiblePlayers = new List <Player>(); foreach (var elem in Map.WithinWindow(Human.X, Human.Y, Surface.Width * (1 / ZoomFactor), Surface.Height * (1 / ZoomFactor))) { if (elem.IsDead) { continue; } if (elem is Player) { visiblePlayers.Add(elem as Player); continue; } if (elem.IsTransparent) { // if the player is intersecting with this item, then do not display it if (Map.IsTouching(Human, elem)) { continue; } // check if one of the bots is hidden by this object for (int i = 0; i < Players.Length; i++) { if (Players[i].Id == Human.Id) { continue; } if (Map.IsTouching(Players[i], elem)) { hidden.Add(Players[i].Id); } } } elem.Draw(Surface); } // draw the players foreach (var player in visiblePlayers) { if (hidden.Contains(player.Id)) { continue; } player.Draw(Surface); } // add any ephemerial elements lock (Ephemerial) { var toremove = new List <EphemerialElement>(); var messageShown = false; foreach (var b in Ephemerial) { if (b is Message) { // only show one message at a time if (messageShown) { continue; } messageShown = true; } b.Draw(Surface); b.Duration--; if (b.Duration < 0) { toremove.Add(b); } } foreach (var b in toremove) { Ephemerial.Remove(b); } } // display the player counts Surface.DisableTranslation(); { Surface.Text(RGBA.Black, Surface.Width - 200, 10, string.Format("Alive {0} of {1}", Alive, Players.Length)); Surface.Text(RGBA.Black, Surface.Width - 200, 30, string.Format("Kills {0}", Human.Kills)); } Surface.EnableTranslation(); // show a menu if present if (Map.IsPaused) { if (Menu == null) { throw new Exception("Must initalize a menu to display"); } Menu.Draw(Surface); } }
public override ActionEnum Action(List <Element> elements, float angleToCenter, bool inZone, ref float xdelta, ref float ydelta, ref float angle) { var playerCount = 0; float playerX = 0; float playerY = 0; bool shouldMelee = false; // find proximity to all types var closest = AITraining.ComputeProximity(this, elements); // gather details about if there is a crowd foreach (var elem in elements) { if (elem.Id == Id) { continue; // found myself } if (!(elem is Player)) { continue; // only care about players } playerCount++; playerX += elem.X; playerY += elem.Y; } // calculate the average center (if there are players near by) if (playerCount >= 1) { playerX /= (float)playerCount; playerY /= (float)playerCount; } // choose an action - set the rules in reverse order in order to set precedence var action = ActionEnum.None; xdelta = ydelta = angle = 0; if (PreviousAngle < 0) { // choose an angle at random PreviousAngle = Rand.Next() % 360; } angle = PreviousAngle; // 3) Shield if (Shield < Constants.MaxShield) { ElementProximity helmet = null; if (closest.TryGetValue(typeof(Helmet), out helmet)) { // there is health either close or touching if (IsTouching(helmet, Width / 2)) { // choose to pickup action = ActionEnum.Pickup; // set direction via another decision PreviousPickupId = helmet.Id; } else { // choose action via another decision angle = helmet.Angle; } } } // 2) Health if (Health < Constants.MaxHealth) { ElementProximity bandage = null; if (closest.TryGetValue(typeof(Bandage), out bandage)) { // there is health either close or touching if (IsTouching(bandage, Width / 2)) { // choose to pickup action = ActionEnum.Pickup; // set direction via another decision PreviousPickupId = bandage.Id; } else { // choose action via another decision angle = bandage.Angle; } } } // 1) Have weapon if (Primary != null) { ElementProximity ammo = null; // need ammo if (Primary.Ammo < MinAmmo && closest.TryGetValue(typeof(Ammo), out ammo)) { // there is ammo either close or touching if (IsTouching(ammo, Width / 2)) { // choose to pickup action = ActionEnum.Pickup; // set direction via another decision PreviousPickupId = ammo.Id; } else { // choose action via another decision angle = ammo.Angle; } } // needs reload if (!Primary.RoundsInClip(out int rounds) && rounds == 0 && Primary.HasAmmo()) { // choose to reload action = ActionEnum.Reload; // choose direction via another decision } ElementProximity ak47 = null; // pick up ak47 if (!(Primary is AK47) && closest.TryGetValue(typeof(AK47), out ak47)) { // there is an AK47 either close or touching if (IsTouching(ak47, Width / 2)) { // choose to pickup action = ActionEnum.Pickup; // set direction via another decision PreviousPickupId = ak47.Id; } else { // choose action via another decision angle = ak47.Angle; } } ElementProximity player = null; // shoot a player if (Primary.CanShoot() && closest.TryGetValue(typeof(Player), out player)) { // choose to shoot action = ActionEnum.Attack; // move towards the player angle = player.Angle; } } // 0) No weapon if (Primary == null) { // AI does not have a weapon, so go ahead and melee (if no other action) shouldMelee = true; // 0.b if near a player, melee ElementProximity player = null; if (closest.TryGetValue(typeof(Player), out player)) { if (IsTouching(player, Fists.Distance)) { // choose to melee action = ActionEnum.Attack; // turn towards the player angle = player.Angle; } } // 0.a is there a weapon within view ElementProximity weapon = null; if (!closest.TryGetValue(typeof(AK47), out weapon)) { if (!closest.TryGetValue(typeof(Pistol), out weapon)) { if (!closest.TryGetValue(typeof(Shotgun), out weapon)) { } } } if (weapon != null) { // there is a weapon either close or touching if (IsTouching(weapon, Width / 2)) { // choose to pickup action = ActionEnum.Pickup; // set direction via another decision PreviousPickupId = weapon.Id; } else { // choose action via another decision angle = weapon.Angle; } } } // if there are too many players, then run away if (playerCount >= 5) { // choose an angle opposite from where the center of the other players are angle = Collision.CalculateAngleFromPoint(X, Y, playerX, playerY); // go the opposite way angle = (angle + 180) % 360; } // choose defaults if (action == ActionEnum.None) { // default to move action = ActionEnum.Move; } // check if we are in the Zone if (inZone) { // we should be moving towards the center if (action == ActionEnum.Move) { // eek we are in the zone, indicate that we should be moving towards the center angle = angleToCenter; } } // check if we seem to be stuck if (IsStuck()) { // take some corrective action if (ShowDiagnostics) { System.Diagnostics.Debug.WriteLine("AI seems stuck"); } // try something new angle = Rand.Next() % 360; CorrectiveAngle = 0; } // check if our last movement was obstructed float moveAngle = (angle + CorrectiveAngle) % 360; if (CorrectiveAngle > 0) { CorrectiveAngle -= 15; } if (CorrectiveAngle < 0) { CorrectiveAngle = 0; } // save angle for next time PreviousAngle = moveAngle; // set course float x1, y1, x2, y2; Collision.CalculateLineByAngle(X, Y, moveAngle, 1, out x1, out y1, out x2, out y2); xdelta = x2 - x1; ydelta = y2 - y1; // normalize var sum = (float)(Math.Abs(xdelta) + Math.Abs(ydelta)); xdelta = xdelta / sum; ydelta = ydelta / sum; if (Math.Abs(xdelta) + Math.Abs(ydelta) > 1.0001) { throw new Exception("Invalid xdelta,ydelta : " + xdelta + "," + ydelta); } if (ShowDiagnostics) { System.Diagnostics.Debug.WriteLine("AI {0} {1} {2} {3}", action, angle, xdelta, ydelta); } // if our action is to move... do a melee while moving if (action == ActionEnum.Move && shouldMelee) { return(ActionEnum.Attack); } else { return(action); } }