using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Text.RegularExpressions; namespace Analizator9000 { /// /// Parsers dealer script files into fileds used by the application and compiles deler script files from them. /// class DealerParser { /// /// Contents of 'condition' section of dealer input script. /// public String condition = ""; /// /// Limit of deals to generate, 'generate' section of input script. /// public long generate = -1; /// /// Limit of deals to produce, 'produce' section of input script. /// public long produce = -1; /// /// Pre-dealt cards, indexed by player. Compiles into 'predeal' section of onput script. /// public Dictionary predeal = new Dictionary(); /// /// "Actions" for Dealer to the check average value of. /// public List actions = new List(); /// /// Loads the input script file and parses it. Parses out everything outside of predeal/condition/produce/generate/action sections. /// /// Filename of the script. public void loadFile(String file) { String[] contents = File.ReadAllLines(file); Dictionary keyLines = new Dictionary(); String[] keywords = {"predeal", "condition", "generate", "produce", "action"}; for (int i = 0; i < contents.Length; i++) { String line = contents[i]; int lineNo = Array.IndexOf(keywords, line.Trim()); if (lineNo >= 0) { keyLines.Add(keywords[lineNo], i); } } keyLines = keyLines.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value); for (int i = 0; i < keyLines.Count; i++) { KeyValuePair keyline = keyLines.ElementAt(i); String[] section = new String[contents.Length - keyline.Value]; if (i + 1 < keyLines.Count) { Array.Copy(contents, keyline.Value, section, 0, keyLines.ElementAt(i + 1).Value - keyline.Value); } else { Array.Copy(contents, keyline.Value, section, 0, contents.Length - keyline.Value); } section[0] = Regex.Replace(section[0], "^"+keyline.Key, "").Trim(); section = section.Where(str => str != null && str.Trim().Length > 0).ToArray(); switch (keyline.Key) { case "predeal": String[] players = { "north", "east", "south", "west" }; char[] suits = { 'S', 'H', 'D', 'C' }; foreach (String l in section) { String line = l.Trim(); int player = Array.IndexOf(players, line.Substring(0, line.IndexOf(' '))); if (player >= 0) { String[] chunks = Regex.Replace(line, "^" + players[player], "").Split(','); String[] hand = new String[4]; foreach (String chunk in chunks) { int suit = Array.IndexOf(suits, chunk.Trim().ToUpper()[0]); if (suit >= 0) { hand[suit] = chunk.Trim().Substring(1); } } this.predeal.Add(players[player], hand); } } break; case "condition": this.condition = section.Aggregate((a, b) => a + "\n" + b); break; case "generate": if (section.Length > 1) { throw new Exception(Form1.GetResourceManager().GetString("DealerParser_errorTooManyGenerate", Form1.GetCulture())); } if (section.Length == 1) { try { this.generate = Convert.ToInt64(section[0]); } catch (OverflowException) { throw new Exception(Form1.GetResourceManager().GetString("DealerParser_errorGenerateOverflow", Form1.GetCulture())); } } break; case "produce": if (section.Length > 1) { throw new Exception(Form1.GetResourceManager().GetString("DealerParser_errorTooManyProduce", Form1.GetCulture())); } if (section.Length == 1) { try { this.produce = Convert.ToInt64(section[0]); } catch (OverflowException) { throw new Exception(Form1.GetResourceManager().GetString("DealerParser_errorProduceOverflow", Form1.GetCulture())); } } break; case "action": Regex pattern = new Regex(@"(?,)|(?\()|(?\))|(?[^,\(\)]*)"); MatchCollection matches = pattern.Matches(section.Aggregate((a, b) => a + b)); List tokens = new List(); foreach (Match match in matches) { int groupNo = 0; foreach (Group group in match.Groups) { if (group.Success && groupNo > 0) { tokens.Add(group.Value); } groupNo++; } } int open = 0; List actions = new List(); String currentAction = ""; foreach (String token in tokens) { switch (token) { case "(": open++; currentAction += token; break; case ")": open--; currentAction += token; break; case ",": if (open == 0) { actions.Add(currentAction.Trim()); currentAction = ""; } else { currentAction += token; } break; default: currentAction += token; break; } } actions.Add(currentAction.Trim()); this.actions = actions.Where(s => s.StartsWith("average")).ToList(); break; } } } /// /// Compiles dealer input script from provided data. Assumes no overhead and action "printoneline" on top of all the declared "average" events. /// /// Input script name. public String saveFile() { if (!Directory.Exists("files")) { Directory.CreateDirectory("files"); } String filename = Utils.getFilename("dealer"); StreamWriter file = new StreamWriter(@"files\" + filename); String predealStr = ""; String suitLetters = "SHDC"; foreach (KeyValuePair pre in this.predeal) { List hand = new List(); for (int i = 0; i < pre.Value.Length; i++) { if (pre.Value[i].Trim().Length > 0) { hand.Add(suitLetters[i] + pre.Value[i].Trim()); } } if (hand.Count > 0) { predealStr += pre.Key + " " + hand.Aggregate((a, b) => a + ", " + b) + "\n"; } } if (predealStr.Length > 0) { file.WriteLine("predeal"); file.Write(predealStr); } if (this.condition.Trim().Length > 0) { file.WriteLine("condition"); file.WriteLine(this.condition); } file.WriteLine("generate"); file.WriteLine(this.generate); file.WriteLine("produce"); file.WriteLine(this.produce); file.WriteLine("action"); file.Write("printoneline"); foreach (String action in this.actions) { if (action.Trim().Length > 0) { file.WriteLine(","); file.Write("average " + action); } } file.WriteLine(); file.Close(); return filename; } } }