using DominionBase.Utilities; using System; using System.Diagnostics.Contracts; using System.Linq; using System.Reflection; using System.Xml; namespace DominionBase.Players.AI { public class RandomAI : Player, IComputerAI { public static string AIName => "Random"; public static string AIDescription => "Randomly chooses one of the other AIs to play as."; private Basic ActualPlayer = null; public string AIType { get { var myType = Phase == PhaseEnum.Endgame ? ActualPlayer.GetType() : GetType(); return (string)myType.GetProperty("AIName", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.FlattenHierarchy).GetValue(null, null); } } public RandomAI(Game game, string name) : base(game, name) { _PlayerType = PlayerType.Computer; var aiTypes = Assembly.GetExecutingAssembly().GetTypes().Where(x => (x == typeof(Basic) || x.IsSubclassOf(typeof(Basic))) && game.Settings.RandomAI_AllowedAIs.Contains(x.FullName) && (!game.Settings.RandomAI_Unique || !game.Players.Any(p => p.GetType() == x || (p.GetType() == typeof(RandomAI) && ((RandomAI)p).ActualPlayer.GetType() == x)))).ToList(); if (!aiTypes.Any()) throw new GameCreationException( $"Cannot find a fitting AI to choose for Random!{Environment.NewLine}Please check your game settings and verify that there are enough AIs to choose from"); var aiType = aiTypes.Choose(); ActualPlayer = (Basic)Activator.CreateInstance(aiType, game, name + " (R)", this); } public AIState State => ActualPlayer.State; public override void StartAsync() { ActualPlayer.StartAsync(); base.StartAsync(); } public override void Setup(IGame game) { base.Setup(game); ActualPlayer.Setup(game, this); } public override void Clear() { ActualPlayer.Clear(); base.Clear(); } public override void TearDown(IGame game) { ActualPlayer.TearDown(game); base.TearDown(game); } public override XmlNode GenerateXml(XmlDocument doc) { Contract.Requires(doc != null, "doc cannot be null"); var xnBase = base.GenerateXml(doc); var xe = doc.CreateElement("random_type"); xe.InnerText = ActualPlayer.GetType().ToString(); xnBase.AppendChild(xe); return xnBase; } internal override void Load(XmlNode xnPlayer) { base.Load(xnPlayer); var xnRandomType = xnPlayer.SelectSingleNode("random_type"); if (xnRandomType == null) return; var randomType = Type.GetType(xnRandomType.InnerText); ActualPlayer = (Basic)Activator.CreateInstance(randomType, _Game, Name + " (R)", this); } } }