From 732d3a0a0cf46cd041748d8b0f81d26e1e459a0a Mon Sep 17 00:00:00 2001 From: emkael Date: Sat, 17 Nov 2012 13:55:44 +0000 Subject: * code documentation git-svn-id: https://svn.emkael.info/an9k@19 05ec0d5d-773b-4d93-9e23-c81a7ac79feb --- Analizator9000/Analizator9000/Accumulator.cs | 67 ++++++++++ .../Analizator9000/Analizator9000.csproj | 3 +- Analizator9000/Analizator9000/BCalcWrapper.cs | 95 ++++++++++++++ Analizator9000/Analizator9000/Contract.cs | 21 +++ Analizator9000/Analizator9000/DealerParser.cs | 24 ++++ Analizator9000/Analizator9000/DealerWrapper.cs | 47 +++++++ Analizator9000/Analizator9000/Form1.Designer.cs | 1 - Analizator9000/Analizator9000/Form1.cs | 146 ++++++++++++++++++++- Analizator9000/Analizator9000/Utils.cs | 9 ++ 9 files changed, 407 insertions(+), 6 deletions(-) (limited to 'Analizator9000') diff --git a/Analizator9000/Analizator9000/Accumulator.cs b/Analizator9000/Analizator9000/Accumulator.cs index 64dde12..0b5c228 100644 --- a/Analizator9000/Analizator9000/Accumulator.cs +++ b/Analizator9000/Analizator9000/Accumulator.cs @@ -6,17 +6,50 @@ using System.IO; namespace Analizator9000 { + /// + /// Provided with a set of deals and contracts to check, conducts the actual statistics by gathering the results of BCalc analysis. + /// class Accumulator { + /// + /// Two-dimensional dictionary of accumulated analysis results (sample count, sample sum and sample square sum). + /// private Dictionary> sums; + /// + /// Number of deals already analyzed. + /// private long analyzed = 0; + /// + /// Total number of deals to analyze. + /// private long toAnalyze = 0; + /// + /// List (well, a stack) of deals to process. + /// private Stack deals; + /// + /// A back-reference to calling Form, for progress presentation purposes. + /// private Form1 form; + /// + /// List of contracts to analyze in BCalc notation (integers for denomination and declarer). + /// private Dictionary> contracts; + /// + /// Results file handle (version of StreamWriter initialized as synchronized). + /// private TextWriter outputFile; + /// + /// Filename for analysis output. + /// private String filename; + /// + /// Accumulator constructor. + /// + /// Array of deals to process, in BCalc's "NESW" format with prepended deal number for orientation. + /// List of denomination-declarer pairs (structures). + /// GUI instance. public Accumulator(String[] deals, List contracts, Form1 form) { this.deals = new Stack(deals); @@ -51,8 +84,19 @@ namespace Analizator9000 this.outputFile = TextWriter.Synchronized(File.AppendText(@"files\"+this.filename)); } + /// + /// Number of threads initially run (and, subsequently, a maximum number that *should* be retained throughout analysis). + /// private int portionSize = 10; + /// + /// Number of threads currently running. + /// private int threadsRunning = 0; + /// + /// Initiates the analysis of a portion of deals. + /// + /// Portion size. If set to 0, assumes the default/initial portion size. + /// Number of deals left to analyze. public int run(int portionSize = 0) { if (portionSize == 0) @@ -69,6 +113,10 @@ namespace Analizator9000 return this.deals.Count; } + /// + /// Worker method for a single deal. + /// + /// Deal in BCalc's "NESW" format, with deal number prepended. private void analyzeDeal(String deal) { try @@ -114,12 +162,22 @@ namespace Analizator9000 } } + /// + /// Flag stating whether the user aborted the analysis. + /// private bool abort = false; + /// + /// Analysis abort method. + /// public void abortAnalysis() { this.abort = true; } + /// + /// Callback method for worker threads, ends the single deal analysis, updates the total result and fires next analysis if necessary. + /// + /// Method invokation result from the worker method. private void endAnalyze(IAsyncResult methodResult) { ((Action)methodResult.AsyncState).EndInvoke(methodResult); @@ -143,6 +201,7 @@ namespace Analizator9000 } if (threadsRunning < this.portionSize) { + // Increasing the parameter would cause exponential thread creation rate. Funny. this.run(1); } } @@ -158,6 +217,10 @@ namespace Analizator9000 } } + /// + /// Presents the current analysis results in textual form. + /// + /// Text table containing means and std. deviations for distinct contracts. private String getString() { StringWriter sw = new StringWriter(); @@ -184,6 +247,10 @@ namespace Analizator9000 return sw.ToString(); } + /// + /// Feeds the overall results with chunks of data from single contract analysis. + /// + /// Result of BCalc analysis. private void update(BCalcResult result) { int tricks = result.tricks; diff --git a/Analizator9000/Analizator9000/Analizator9000.csproj b/Analizator9000/Analizator9000/Analizator9000.csproj index 89dafd7..321cce6 100644 --- a/Analizator9000/Analizator9000/Analizator9000.csproj +++ b/Analizator9000/Analizator9000/Analizator9000.csproj @@ -13,6 +13,7 @@ v3.5 Client 512 + false publish\ true Disk @@ -25,7 +26,6 @@ true 0 1.0.0.%2a - false false true @@ -48,6 +48,7 @@ prompt 4 true + bin\Release\Analizator9000.XML Icon1.ico diff --git a/Analizator9000/Analizator9000/BCalcWrapper.cs b/Analizator9000/Analizator9000/BCalcWrapper.cs index c176117..556b419 100644 --- a/Analizator9000/Analizator9000/BCalcWrapper.cs +++ b/Analizator9000/Analizator9000/BCalcWrapper.cs @@ -7,11 +7,26 @@ using System.Text.RegularExpressions; namespace Analizator9000 { + /// + /// Structure holding single deal analysis result. + /// struct BCalcResult { + /// + /// Trump denomination (N/S/H/D/C). + /// public char trumpSuit; + /// + /// Declaring player (N/E/S/W). + /// public char declarer; + /// + /// Number of tricks taken by the declaring side. + /// public int tricks; + /// + /// Deal number, parsed out from input string. + /// public long dealNo; public BCalcResult(char a, char b, int c, long d) { @@ -21,33 +36,98 @@ namespace Analizator9000 dealNo = d; } }; + /// + /// Wrapper class for libbcalcDDS.ddl. + /// class BCalcWrapper { + /// + /// Allocates new instance of BCalc solver. + /// + /// Deal format string. See the original documentation for details. + /// Card distribution. + /// Trump denomination, in numeric format. See the original documentation for details. + /// Player on lead, in numeric format. See the original documentation for details. + /// Pointer to solver instance. + /// Original documentation: http://bcalc.w8.pl/API_C/bcalcdds_8h.html#ab636045f65412652246b769e8e95ed6f + /// Enum/constants for trumps/players, definitely. [DllImport(@"bin\libbcalcdds.dll", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr bcalcDDS_new(IntPtr format, IntPtr hands, Int32 trump, Int32 leader); + /// + /// Conducts DD analysis. + /// + /// Pointer to solver instance. + /// Number of tricks to take by leading side. + /// Original documentation: http://bcalc.w8.pl/API_C/bcalcdds_8h.html#a369ce661d027bef3f717967e42bf8b33 [DllImport(@"bin\libbcalcdds.dll", CallingConvention = CallingConvention.Cdecl)] private static extern Int32 bcalcDDS_getTricksToTake(IntPtr solver); + /// + /// Checks for solver errors. + /// + /// Pointer to solver instance. + /// Error string or NULL if no error accured. + /// Original documentation: http://bcalc.w8.pl/API_C/bcalcdds_8h.html#a89cdec200cde91331d40f0900dc0fb46 [DllImport(@"bin\libbcalcdds.dll", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr bcalcDDS_getLastError(IntPtr solver); + /// + /// Frees allocated solver instance and cleans up after it. + /// + /// Pointer to solver instance. + /// Original documentation: http://bcalc.w8.pl/API_C/bcalcdds_8h.html#a4a68da83bc7da4663e2257429539912d [DllImport(@"bin\libbcalcdds.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void bcalcDDS_delete(IntPtr solver); + /// + /// Sets trump denomination and resets the analysis. + /// + /// Pointer to solver instance. + /// Trump denomination, in numeric format. See the original documentation for details. + /// Original documentation: http://bcalc.w8.pl/API_C/bcalcdds_8h.html#a88fba3432e66efa5979bbc9e1f044164 [DllImport(@"bin\libbcalcdds.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void bcalcDDS_setTrumpAndReset(IntPtr solver, Int32 trump); + /// + /// Sets leading player and resets the analysis. + /// + /// Pointer to solver instance. + /// Player on lead, in numeric format. See the original documentation for details. + /// Original documentation: http://bcalc.w8.pl/API_C/bcalcdds_8h.html#a616031c1e1d856c4aac14390693adb4c [DllImport(@"bin\libbcalcdds.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void bcalcDDS_setPlayerOnLeadAndReset(IntPtr solver, Int32 player); + /// + /// Translation table between player characters and numeric values. + /// public static String table = "NESW"; + /// + /// Translation table between denomination characters and numeric values. + /// public static String denominations = "CDHSN"; + /// + /// Pointer to solver instance. + /// private IntPtr solver; + /// + /// Deal distribution. + /// private String deal; + /// + /// Internal number of deal being analyzed. + /// private long dealNo; + /// + /// Trump suit, in numeric format. + /// private int trumps; + + /// + /// Constructor of class instance for single deal analysis. + /// + /// Deal distribution prefixed with deal number. public BCalcWrapper(String deal) { try @@ -67,6 +147,10 @@ namespace Analizator9000 this.errorCheck(); } + /// + /// Sets the trump denomination. + /// + /// Trump denomination, in numeric format. public void setTrump(int trumpSuit) { if (trumpSuit < 0) @@ -78,6 +162,11 @@ namespace Analizator9000 this.trumps = trumpSuit; } + /// + /// Runs the single contract analysis. + /// + /// Declaring player, in numeric format. + /// Result structur for the contract. public BCalcResult run(int declarer) { if (declarer < 0) @@ -92,10 +181,16 @@ namespace Analizator9000 return new BCalcResult(BCalcWrapper.denominations[this.trumps], BCalcWrapper.table[declarer], 13 - result, this.dealNo); } + /// + /// Releases the solver instaces. + /// public void destroy() { BCalcWrapper.bcalcDDS_delete(this.solver); } + /// + /// Checks for errors, throws exception if any occured. + /// private void errorCheck() { IntPtr error = BCalcWrapper.bcalcDDS_getLastError(this.solver); diff --git a/Analizator9000/Analizator9000/Contract.cs b/Analizator9000/Analizator9000/Contract.cs index f603ecd..0ef4fef 100644 --- a/Analizator9000/Analizator9000/Contract.cs +++ b/Analizator9000/Analizator9000/Contract.cs @@ -5,17 +5,38 @@ using System.Text; namespace Analizator9000 { + /// + /// Tuple describing contract parameters. Created only because .NET 3.5 doesn't have Tuple type yet. + /// class Contract: IEquatable { + /// + /// Trump denomination, in numeric format. + /// + /// public int Denomination; + /// + /// Declaring player, in numeric format. + /// + /// public int Declarer; + /// + /// Tuple constructor. + /// + /// Trump denomination. + /// Declaring player. public Contract(int denom, int decl) { this.Denomination = denom; this.Declarer = decl; } + /// + /// IEquatable method for comparing (checking equality) of two tuples. + /// + /// Tuple to compare to. + /// TRUE if both tuple components are equal. public bool Equals(Contract other) { return this.Denomination == other.Denomination && this.Declarer == other.Declarer; diff --git a/Analizator9000/Analizator9000/DealerParser.cs b/Analizator9000/Analizator9000/DealerParser.cs index 80031fd..1ed640c 100644 --- a/Analizator9000/Analizator9000/DealerParser.cs +++ b/Analizator9000/Analizator9000/DealerParser.cs @@ -7,13 +7,32 @@ 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(); + /// + /// 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); @@ -107,6 +126,11 @@ namespace Analizator9000 } } } + + /// + /// Compiles dealer input script from provided data. Assumes no overhead section and single action: printoneline. + /// + /// Input script contents. public String saveFile() { String filename = Utils.getFilename("dealer"); diff --git a/Analizator9000/Analizator9000/DealerWrapper.cs b/Analizator9000/Analizator9000/DealerWrapper.cs index 4184d8e..e538d5e 100644 --- a/Analizator9000/Analizator9000/DealerWrapper.cs +++ b/Analizator9000/Analizator9000/DealerWrapper.cs @@ -8,15 +8,42 @@ using System.Text.RegularExpressions; namespace Analizator9000 { + /// + /// Runs dealer generator and captures its output. + /// class DealerWrapper { + /// + /// Calling user interfaces instance. + /// private Form1 debugForm; + /// + /// Name of the input script file. + /// private String scriptname; + /// + /// Stream to the generation results output file. + /// private StreamWriter outputFile; + /// + /// Flag ensuring only one instance of dealer is running. + /// private bool running = false; + /// + /// Number of lines (deals) to produce. + /// private long produce = 0; + /// + /// Number of lines (deals) already produced. + /// private long lineCount = 0; + /// + /// Dealer wrapper class constructor. + /// + /// Input script file name. + /// Calling interface form. + /// Number of deals to produce. public DealerWrapper(String scriptname, Form1 debugForm, long produce) { if (!File.Exists(scriptname)) @@ -32,10 +59,19 @@ namespace Analizator9000 this.produce = produce; } + /// + /// Sends a single line to debug field of the calling form. + /// + /// Message to be appended to the debug output. private void debugWriteLine(String line) { this.debugForm.addStatusLine(line); } + /// + /// Processes a chunk of dealer output. + /// + /// Output string of dealer instance. + /// TRUE if dealer it still running, FALSE if null string arrived -> process ended. private bool handleData(string data) { if (data != null) @@ -59,12 +95,23 @@ namespace Analizator9000 return false; } + /// + /// Closes the output file stream. + /// public void closeFile() { this.outputFile.Close(); } + /// + /// Delegate for process end callback invocation. + /// + /// Output file name. private delegate void onEndDelegate(String filename); + /// + /// Worker method for dealer generating. + /// + /// Callback to the function which takes output file name as a parameter. public void run(Action onEnd) { if (!this.running) diff --git a/Analizator9000/Analizator9000/Form1.Designer.cs b/Analizator9000/Analizator9000/Form1.Designer.cs index 040df35..d08e3b1 100644 --- a/Analizator9000/Analizator9000/Form1.Designer.cs +++ b/Analizator9000/Analizator9000/Form1.Designer.cs @@ -1002,7 +1002,6 @@ this.MaximizeBox = false; this.Name = "Form1"; this.Text = "Analizator9000"; - this.Load += new System.EventHandler(this.Form1_Load); this.generateGroup.ResumeLayout(false); this.generateGroup.PerformLayout(); this.tableLayoutPanel1.ResumeLayout(false); diff --git a/Analizator9000/Analizator9000/Form1.cs b/Analizator9000/Analizator9000/Form1.cs index 14b33aa..aeaf56c 100644 --- a/Analizator9000/Analizator9000/Form1.cs +++ b/Analizator9000/Analizator9000/Form1.cs @@ -10,21 +10,40 @@ using System.IO; namespace Analizator9000 { + /// + /// Main application window control. + /// public partial class Form1 : Form { + /// + /// Dealer input scripts parser instance. + /// private DealerParser parser; + /// + /// Constructs the main window. + /// public Form1() { InitializeComponent(); this.parser = new DealerParser(); } + /// + /// "Select file" button click, opens file selection dialog for input script. + /// + /// + /// private void button1_Click(object sender, EventArgs e) { generateFileDialog.ShowDialog(); } + /// + /// Input script file selection event. Initiates input script parsing. + /// + /// + /// private void openFileDialog1_FileOk(object sender, CancelEventArgs e) { try @@ -70,10 +89,16 @@ namespace Analizator9000 } } + /// + /// "Generate" button click. Saves the input script file and runs deals generating. + /// + /// + /// private void generateButton_Click(object sender, EventArgs e) { generateGroup.Enabled = false; analyzeGroup.Enabled = false; + statusListBox.Items.Clear(); progressBar.Value = 0; try { @@ -118,7 +143,15 @@ namespace Analizator9000 } } + /// + /// Delegate for generating end method callback. + /// + /// private delegate void endDelegate(String filename); + /// + /// Generating end callback method. Prints out deal generating summary. + /// + /// Output (generated deals) file name. private void generateEnd(String filename) { if (this.InvokeRequired) @@ -138,7 +171,15 @@ namespace Analizator9000 } } + /// + /// Delegate for debug line addition method. + /// + /// private delegate void AddStatusDelegate(String line); + /// + /// Debug line addition method (thread-safe). + /// + /// String to be appended to the debug output. public void addStatusLine(String line) { if (line != null) @@ -155,7 +196,15 @@ namespace Analizator9000 } } + /// + /// Delegate for progress bar update method. + /// + /// Percentage of progress to set (0-100) private delegate void SetProgressDelegate(int progress); + /// + /// Progress bar update method (thread-safe). + /// + /// Percentage of progress to set (0-100) public void setProgress(int progress) { if (progressBar.InvokeRequired) @@ -168,26 +217,41 @@ namespace Analizator9000 } } - private void Form1_Load(object sender, EventArgs e) - { - } - + /// + /// Deals file selection event. Sets the deals file path in the text field. + /// + /// + /// private void analyzeFileDialog_FileOk(object sender, CancelEventArgs e) { analyzeFileNameTextBox.Text = analyzeFileDialog.FileName; } + /// + /// "Select file" button click for deals file selection. + /// + /// + /// private void button2_Click(object sender, EventArgs e) { analyzeFileDialog.ShowDialog(); } + /// + /// Instance of analysis summary class. + /// private Accumulator ac; + /// + /// "Analyze" button click. Runs the analysis. + /// + /// + /// private void analyzeButton_Click(object sender, EventArgs e) { analyzeGroup.Enabled = false; generateGroup.Enabled = false; abortButton.Enabled = true; + statusListBox.Items.Clear(); this.addStatusLine("Otwieram plik: " + analyzeFileNameTextBox.Text); try { @@ -220,7 +284,13 @@ namespace Analizator9000 } } + /// + /// Delegate for analysis end callback method. + /// private delegate void EndAnalysisDelegate(); + /// + /// Analysis end callback method. Cleans up visually after the analysis. + /// public void endAnalysis() { if (this.InvokeRequired) @@ -237,7 +307,15 @@ namespace Analizator9000 } } + /// + /// Delegate for result summary display method. + /// + /// Result summary string. private delegate void SetResultDelegate(String res); + /// + /// Displays analysis results summary. + /// + /// Result summary string. public void setResult(String res) { if (this.InvokeRequired) @@ -250,6 +328,11 @@ namespace Analizator9000 } } + /// + /// "Abort" button click event. + /// + /// + /// private void abortButton_Click(object sender, EventArgs e) { if (this.ac != null) @@ -258,6 +341,11 @@ namespace Analizator9000 } } + /// + /// Mass checkboxes within contract table layout toggle method. + /// + /// Set of x-coordinates for checkboxes to toggle. + /// Set of y-coordinates for checkboxes to toggle. private void toggleBoxes(IEnumerable xRange, IEnumerable yRange) { foreach (int x in xRange) @@ -270,51 +358,101 @@ namespace Analizator9000 } } + /// + /// Toggles all contract chackboxes. + /// + /// + /// private void button3_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(1, 5), Enumerable.Range(1, 4)); } + /// + /// Toggles the first column of checkboxes ("NT"). + /// + /// + /// private void label18_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(1, 1), Enumerable.Range(1, 4)); } + /// + /// Toggles the second column of checkboxes (spades). + /// + /// + /// private void label14_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(2, 1), Enumerable.Range(1, 4)); } + /// + /// Toggles the third column of checkboxes (hearts). + /// + /// + /// private void label15_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(3, 1), Enumerable.Range(1, 4)); } + /// + /// Toggles the fourth column of checkboxes (diamonds). + /// + /// + /// private void label16_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(4, 1), Enumerable.Range(1, 4)); } + /// + /// Toggles the fifth column of checkboxes (clubs). + /// + /// + /// private void label17_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(5, 1), Enumerable.Range(1, 4)); } + /// + /// Toggles the first row of checkboxes (North). + /// + /// + /// private void label19_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(1, 5), Enumerable.Range(1, 1)); } + /// + /// Toggles the second row of checkboxes (East). + /// + /// + /// private void label20_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(1, 5), Enumerable.Range(2, 1)); } + /// + /// Toggles the third row of checkboxes (South). + /// + /// + /// private void label21_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(1, 5), Enumerable.Range(3, 1)); } + /// + /// Toggles the fourth row of checkboxes (West). + /// + /// + /// private void label22_Click(object sender, EventArgs e) { this.toggleBoxes(Enumerable.Range(1, 5), Enumerable.Range(4, 1)); diff --git a/Analizator9000/Analizator9000/Utils.cs b/Analizator9000/Analizator9000/Utils.cs index eefaa9b..3fbd4ac 100644 --- a/Analizator9000/Analizator9000/Utils.cs +++ b/Analizator9000/Analizator9000/Utils.cs @@ -5,8 +5,17 @@ using System.Text; namespace Analizator9000 { + /// + /// Random utility class. + /// + /// Merge with Contract, probably. class Utils { + /// + /// Provides a timestamped filename in uniform format. + /// + /// Desired file extension. + /// Filename prefixed with program identificator, containing a timestamp for request. static public String getFilename(String extension) { return "an9k-" + DateTime.Now.ToString("yyyyMMddHHmmssFFF") + "." + extension; -- cgit v1.2.3