using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Xml; using DominionBase.Cards; namespace DominionBase.Players.AI { public class Opening { private Boolean _IsValid = true; private float _Skill = 0; private float _Accuracy = 0; private CardCollection _Cards = new CardCollection(); public Boolean IsValid { get { return _IsValid; } } public float Skill { get { return _Skill; } private set { _Skill = value; } } public float Accuracy { get { return _Accuracy; } private set { _Accuracy = value; } } public float SkillFloor { get { return this.Skill - this.Accuracy; } } public float SkillCeiling { get { return this.Skill + this.Accuracy; } } public CardCollection Cards { get { return _Cards; } } public Opening() { } public Opening(float skill, float accuracy, CardCollection cards) { _Skill = skill; _Accuracy = accuracy; _Cards = cards; } public Opening(String skill, String accuracy, String cardNames, String cardCosts, CardCollection cardDB) { float.TryParse(skill, out _Skill); float.TryParse(accuracy, out _Accuracy); foreach (String cardName in cardNames.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries)) { Card foundCard = cardDB.SingleOrDefault(c => c.Name.Equals(cardName.Trim(), StringComparison.CurrentCultureIgnoreCase)); if (foundCard != null) _Cards.Add(foundCard); else // We weren't able to find a card, so the opening isn't valid for us _IsValid = false; } } public override string ToString() { return String.Format("{0:0.000} ± {1:0.000}: {2}", this.Skill, this.Accuracy, String.Join(" / ", this.Cards.Select(c => c.Name))); } } public class OpeningCollection : List { public IEnumerable FilterFor(IEnumerable cards) { return this.Where(o => o.Cards.All(c => cards.Any(ic => ic.CardType == c.CardType))); } internal static String Filename { get { return System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "openings.xml"); } } public void Save() { try { XmlDocument xdFile = new XmlDocument(); XmlElement xeOpenings = xdFile.CreateElement("Openings"); xdFile.AppendChild(xeOpenings); foreach (Opening opening in this) { // Skip any invalid ones (e.g. cards not implemented) // Also skip any ones that are useless if (!opening.IsValid || opening.SkillFloor < 0) continue; XmlElement xeOpening = xdFile.CreateElement("Opening"); xeOpenings.AppendChild(xeOpening); XmlElement xeSkill = xdFile.CreateElement("Skill"); xeSkill.InnerText = opening.Skill.ToString(); xeOpening.AppendChild(xeSkill); XmlElement xeAccuracy = xdFile.CreateElement("Accuracy"); xeAccuracy.InnerText = opening.Accuracy.ToString(); xeOpening.AppendChild(xeAccuracy); XmlElement xeCards = xdFile.CreateElement("Cards"); xeOpening.AppendChild(xeCards); foreach (Card card in opening.Cards) { XmlElement xeCard = xdFile.CreateElement("Card"); xeCard.InnerText = card.Name; xeCards.AppendChild(xeCard); } } xdFile.Save(OpeningCollection.Filename); } catch (IOException) { } } public void Load(CardCollection cardDB) { try { XmlDocument xdFile = new XmlDocument(); xdFile.Load(OpeningCollection.Filename); foreach (XmlNode xnOpening in xdFile.SelectNodes("Openings/Opening")) { StringBuilder sbCardNames = new StringBuilder(); foreach (XmlNode xnCard in xnOpening.SelectNodes("Cards/Card")) { if (sbCardNames.Length > 0) sbCardNames.Append("/"); sbCardNames.Append(xnCard.InnerText); } Opening newOpening = new Opening( xnOpening.SelectSingleNode("Skill").InnerText, xnOpening.SelectSingleNode("Accuracy").InnerText, sbCardNames.ToString(), String.Empty, cardDB); if (newOpening.IsValid) this.Add(newOpening); } } catch (IOException) { } } } }