From c2d53052e846fa2f8bbedcae9eb37ed607bb13ee Mon Sep 17 00:00:00 2001 From: emkael Date: Thu, 3 Sep 2015 12:58:13 +0200 Subject: * options for collecting play and bidding data --- Aktywator/Bws.cs | 26 ++++++++++++++++++++++++++ Aktywator/MainForm.Designer.cs | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/Aktywator/Bws.cs b/Aktywator/Bws.cs index 0be06df..20278e0 100644 --- a/Aktywator/Bws.cs +++ b/Aktywator/Bws.cs @@ -54,6 +54,8 @@ namespace Aktywator settings.Add(new Setting("BM2AutoBoardNumber", main.xAutoBoardNumber, this)); settings.Add(new Setting("BM2ResetFunctionKey", main.xResetFunctionKey, this)); settings.Add(new Setting("BM2ViewHandrecord", main.xViewHandrecord, this)); + settings.Add(new Setting("BM2RecordBidding", main.xCollectBidding, this)); + settings.Add(new Setting("BM2RecordPlay", main.xCollectPlay, this)); } public string sectionsForHandRecords() @@ -131,6 +133,8 @@ namespace Aktywator settings.Add(new Setting("BM2NameSource", "integer", "2")); settings.Add(new Setting("BM2ViewHandrecord", "bit", "false")); settings.Add(new Setting("BM2EnterHandrecord", "bit", "false")); + settings.Add(new Setting("BM2RecordBidding", "bit", "false")); + settings.Add(new Setting("BM2RecordPlay", "bit", "false")); settings.Add(new Setting("Name", "text(18)", "''", "PlayerNumbers")); settings.Add(new Setting("Updated", "bit", "false", "PlayerNumbers")); @@ -167,6 +171,28 @@ namespace Aktywator catch (OleDbException) { } + try + { + sql.query("CREATE TABLE PlayData (" + + "`ID` integer, `Section` integer, `Table` integer, `Round` integer, `Board` integer," + + "`Counter` integer, `Direction` text(2), `Card` text(10), `DateLog` datetime," + + "`TimeLog` datetime, `Erased` bit" + + ");"); + } + catch (OleDbException) + { + } + try + { + sql.query("CREATE TABLE BiddingData (" + + "`ID` integer, `Section` integer, `Table` integer, `Round` integer, `Board` integer," + + "`Counter` integer, `Direction` text(2), `Bid` text(10), `DateLog` datetime," + + "`TimeLog` datetime, `Erased` bit" + + ");"); + } + catch (OleDbException) + { + } } public void updateSettings() diff --git a/Aktywator/MainForm.Designer.cs b/Aktywator/MainForm.Designer.cs index 8a68b44..03a692f 100644 --- a/Aktywator/MainForm.Designer.cs +++ b/Aktywator/MainForm.Designer.cs @@ -105,6 +105,8 @@ this.bLoadHands = new System.Windows.Forms.Button(); this.timer = new System.Windows.Forms.Timer(this.components); this.openPBN = new System.Windows.Forms.OpenFileDialog(); + this.xCollectBidding = new System.Windows.Forms.CheckBox(); + this.xCollectPlay = new System.Windows.Forms.CheckBox(); this.groupBoxTop.SuspendLayout(); this.menu.SuspendLayout(); this.statusStrip1.SuspendLayout(); @@ -240,6 +242,8 @@ // // tabPage1 // + this.tabPage1.Controls.Add(this.xCollectPlay); + this.tabPage1.Controls.Add(this.xCollectBidding); this.tabPage1.Controls.Add(this.xViewHandrecord); this.tabPage1.Controls.Add(this.xResultsOverview); this.tabPage1.Controls.Add(this.bLoad); @@ -894,6 +898,26 @@ // this.openPBN.Filter = "PBN|*.pbn"; // + // xCollectBidding + // + this.xCollectBidding.AutoSize = true; + this.xCollectBidding.Location = new System.Drawing.Point(339, 115); + this.xCollectBidding.Name = "xCollectBidding"; + this.xCollectBidding.Size = new System.Drawing.Size(97, 17); + this.xCollectBidding.TabIndex = 30; + this.xCollectBidding.Text = "zbieraj licytację"; + this.xCollectBidding.UseVisualStyleBackColor = true; + // + // xCollectPlay + // + this.xCollectPlay.AutoSize = true; + this.xCollectPlay.Location = new System.Drawing.Point(339, 138); + this.xCollectPlay.Name = "xCollectPlay"; + this.xCollectPlay.Size = new System.Drawing.Size(146, 17); + this.xCollectPlay.TabIndex = 31; + this.xCollectPlay.Text = "zbieraj przebieg rozgrywki"; + this.xCollectPlay.UseVisualStyleBackColor = true; + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1008,6 +1032,8 @@ private System.Windows.Forms.Label label13; private System.Windows.Forms.Label label9; private System.Windows.Forms.TextBox eOomRounds; + public System.Windows.Forms.CheckBox xCollectPlay; + public System.Windows.Forms.CheckBox xCollectBidding; } } -- cgit v1.2.3 From 6f5d3a1d030fe7d66d56c71bdacb2534a9c98561 Mon Sep 17 00:00:00 2001 From: emkael Date: Sat, 14 Nov 2015 10:55:05 +0100 Subject: * autonumber IDs in bidding/play tables --- Aktywator/Bws.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Aktywator/Bws.cs b/Aktywator/Bws.cs index 20278e0..8884868 100644 --- a/Aktywator/Bws.cs +++ b/Aktywator/Bws.cs @@ -174,7 +174,7 @@ namespace Aktywator try { sql.query("CREATE TABLE PlayData (" - + "`ID` integer, `Section` integer, `Table` integer, `Round` integer, `Board` integer," + + "`ID` autoincrement, `Section` integer, `Table` integer, `Round` integer, `Board` integer," + "`Counter` integer, `Direction` text(2), `Card` text(10), `DateLog` datetime," + "`TimeLog` datetime, `Erased` bit" + ");"); @@ -185,7 +185,7 @@ namespace Aktywator try { sql.query("CREATE TABLE BiddingData (" - + "`ID` integer, `Section` integer, `Table` integer, `Round` integer, `Board` integer," + + "`ID` autoincrement, `Section` integer, `Table` integer, `Round` integer, `Board` integer," + "`Counter` integer, `Direction` text(2), `Bid` text(10), `DateLog` datetime," + "`TimeLog` datetime, `Erased` bit" + ");"); -- cgit v1.2.3 From be59baaa024f8c5f02ec14fe34155e736548046b Mon Sep 17 00:00:00 2001 From: emkael Date: Wed, 9 Nov 2016 13:29:55 +0100 Subject: * BCDD code for parsing PBN files added --- Aktywator/Aktywator.csproj | 3 + Aktywator/DDTable.cs | 107 +++++++++++++++++++++++ Aktywator/PBN.cs | 36 ++++---- Aktywator/PBNBoard.cs | 205 +++++++++++++++++++++++++++++++++++++++++++++ Aktywator/PBNFile.cs | 46 ++++++++++ README.md | 4 + 6 files changed, 379 insertions(+), 22 deletions(-) create mode 100644 Aktywator/DDTable.cs create mode 100644 Aktywator/PBNBoard.cs create mode 100644 Aktywator/PBNFile.cs diff --git a/Aktywator/Aktywator.csproj b/Aktywator/Aktywator.csproj index b153254..14bb190 100644 --- a/Aktywator/Aktywator.csproj +++ b/Aktywator/Aktywator.csproj @@ -81,6 +81,7 @@ ChooseTournament.cs + Form @@ -96,6 +97,8 @@ MysqlSettings.cs + + diff --git a/Aktywator/DDTable.cs b/Aktywator/DDTable.cs new file mode 100644 index 0000000..38e0fbd --- /dev/null +++ b/Aktywator/DDTable.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; + +namespace Aktywator +{ + class DDTableInvalidException : FieldNotFoundException + { + public DDTableInvalidException() : base() { } + public DDTableInvalidException(String msg) : base(msg) { } + } + + class DDTable + { + public static char[] DENOMINATIONS = { 'C', 'D', 'H', 'S', 'N' }; + public static char[] PLAYERS = { 'N', 'E', 'S', 'W' }; + + private PBNBoard board; + + private int[,] getEmptyTable() + { + int[,] result = new int[4, 5]; + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 5; j++) + { + result[i, j] = -1; + } + } + return result; + } + + private int[,] validateTable(int[,] table) + { + foreach (int t in table) + { + if (t > 13 || t < 0) + { + throw new DDTableInvalidException("Invalid number of tricks: " + t.ToString()); + } + } + return table; + } + + public DDTable(PBNBoard board) + { + this.board = board; + } + + public int[,] GetJFRTable() + { + int[,] result = this.getEmptyTable(); + String ability = this.board.GetAbility(); + MatchCollection abilities = this.board.ValidateAbility(ability); + foreach (Match playerAbility in abilities) + { + char player = playerAbility.Groups[1].Value[0]; + int playerID = Array.IndexOf(PLAYERS, player); + int denomID = 4; + foreach (char tricks in playerAbility.Groups[2].Value.ToCharArray()) + { + result[playerID, denomID] = (tricks > '9') ? (tricks - 'A' + 10) : (tricks - '0'); + denomID--; + } + } + return this.validateTable(result); + } + + public int[,] GetPBNTable() + { + List table = this.board.GetOptimumResultTable(); + List parsedTable = this.board.ValidateOptimumResultTable(table); + int[,] result = this.getEmptyTable(); + foreach (Match lineMatch in parsedTable) + { + char player = lineMatch.Groups[1].Value[0]; + char denom = lineMatch.Groups[2].Value[0]; + int tricks = Int16.Parse(lineMatch.Groups[3].Value); + int playerID = Array.IndexOf(PLAYERS, player); + int denomID = Array.IndexOf(DENOMINATIONS, denom); + result[playerID, denomID] = tricks; + } + return this.validateTable(result); + } + + public int[,] GetDDTable() + { + try + { + return this.GetJFRTable(); + } + catch (FieldNotFoundException) + { + try + { + return this.GetPBNTable(); + } + catch (FieldNotFoundException) + { + return null; + } + } + } + } +} diff --git a/Aktywator/PBN.cs b/Aktywator/PBN.cs index ad7ac99..f6d5393 100644 --- a/Aktywator/PBN.cs +++ b/Aktywator/PBN.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Text; using System.IO; +using System.Windows.Forms; namespace Aktywator { class PBN { public HandRecord[] handRecords; + public DDTable[] ddTables; protected int lowBoard; protected int highBoard; private int _count; @@ -19,33 +21,23 @@ namespace Aktywator public PBN(string filename, int lowBoard, int highBoard) { this.handRecords = new HandRecord[highBoard + 1]; + this.ddTables = new DDTable[highBoard + 1]; - StreamReader f = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)); - try + this.lowBoard = lowBoard; + this.highBoard = highBoard; + + this._count = 0; + PBNFile pbn = new PBNFile(filename); + foreach (PBNBoard board in pbn.Boards) { - int board = lowBoard; - bool canBeRead = false; - _count = 0; - while (!f.EndOfStream && (board <= highBoard)) + int boardNo = Int32.Parse(board.GetNumber()); + if (lowBoard <= boardNo && boardNo <= highBoard) { - string line = f.ReadLine(); - if (line.Trim() == "[Board \"" + board + "\"]") - canBeRead = true; - else if (canBeRead && (line.Substring(0, 6) == "[Deal ")) - { - line = line.Substring(line.IndexOf(':') + 1); - line = line.Substring(0, line.IndexOf('"')); - handRecords[board] = new HandRecord(line); - canBeRead = false; - _count++; - board++; - } + this.handRecords[boardNo] = new HandRecord(board.GetLayout()); + this.ddTables[boardNo] = new DDTable(board); + this._count++; } } - finally - { - f.Close(); - } } } diff --git a/Aktywator/PBNBoard.cs b/Aktywator/PBNBoard.cs new file mode 100644 index 0000000..605630c --- /dev/null +++ b/Aktywator/PBNBoard.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace Aktywator +{ + + class PBNField + { + public String Key; + public String Value; + public String RawField; + + public PBNField() { } + + public PBNField(String key, String value) + { + this.Key = key; + this.Value = value; + this.RawField = String.Format("[{0} \"{1}\"]", this.Key, this.Value); + } + + public PBNField(String rawData) + { + this.RawField = rawData; + } + } + + class FieldNotFoundException : Exception + { + public FieldNotFoundException() : base() { } + public FieldNotFoundException(String msg) : base(msg) { } + } + + class PBNBoard + { + public List Fields; + + private bool? hasOptimumResultTable = null; + private bool? hasAbility = null; + + private static Regex linePattern = new Regex(@"\[(.*) ""(.*)""\]"); + private static Regex abilityPattern = new Regex(@"\b([NESW]):([0-9A-D]{5})\b"); + private static Regex optimumResultTablePattern = new Regex(@"^([NESW])\s+([CDHSN])T?\s+(\d+)$"); + + public PBNBoard(List lines) + { + this.Fields = new List(); + foreach (String line in lines) + { + PBNField field = new PBNField(); + field.RawField = line; + Match lineParse = PBNBoard.linePattern.Match(line); + if (lineParse.Success) + { + field.Key = lineParse.Groups[1].Value; + field.Value = lineParse.Groups[2].Value; + } + this.Fields.Add(field); + } + } + + public bool HasField(String key) + { + foreach (PBNField field in this.Fields) + { + if (key.Equals(field.Key)) + { + return true; + } + } + return false; + } + + public String GetField(String key) + { + foreach (PBNField field in this.Fields) + { + if (key.Equals(field.Key)) + { + return field.Value; + } + } + throw new FieldNotFoundException(key + " field not found"); + } + + public String GetLayout() + { + return this.GetField("Deal"); + } + + public String GetNumber() + { + return this.GetField("Board"); + } + + public String GetVulnerable() + { + return this.GetField("Vulnerable"); + } + + public String GetDealer() + { + return this.GetField("Dealer"); + } + + public MatchCollection ValidateAbility(String ability) + { + MatchCollection matches = PBNBoard.abilityPattern.Matches(ability); + if (matches.Count != 4) + { + this.hasAbility = false; + throw new DDTableInvalidException("Invalid Ability line: " + ability); + } + List players = new List(); + foreach (Match match in matches) + { + if (players.Contains(match.Groups[1].Value)) + { + this.hasAbility = false; + throw new DDTableInvalidException("Duplicate entry in Ability: " + match.Groups[0].Value); + } + else + { + players.Add(match.Groups[1].Value); + } + } + this.hasAbility = true; + return matches; + } + + public String GetAbility() + { + return this.GetField("Ability"); + } + + public String GetOptimumResult() + { + return this.GetField("OptimumResult"); + } + + public List ValidateOptimumResultTable(List table) + { + List matches = new List(); + List duplicates = new List(); + foreach (String line in table) + { + Match match = PBNBoard.optimumResultTablePattern.Match(line); + if (!match.Success) + { + this.hasOptimumResultTable = false; + throw new DDTableInvalidException("Invalid OptimumResultTable line: " + line); + } + String position = match.Groups[1].Value + " - " + match.Groups[2].Value; + if (duplicates.Contains(position)) + { + this.hasOptimumResultTable = false; + throw new DDTableInvalidException("Duplicate OptimumResultTable line: " + line); + } + else + { + duplicates.Add(position); + } + matches.Add(match); + } + this.hasOptimumResultTable = true; + return matches; + } + + public List GetOptimumResultTable() + { + bool fieldFound = false; + List result = new List(); + foreach (PBNField field in this.Fields) + { + if ("OptimumResultTable".Equals(field.Key)) + { + fieldFound = true; + } + else + { + if (fieldFound) + { + if (field.Key == null) + { + result.Add(field.RawField); + } + else + { + break; + } + } + } + } + if (!fieldFound) + { + this.hasOptimumResultTable = false; + throw new FieldNotFoundException("OptimumResultTable field not found"); + } + return result; + } + + } +} diff --git a/Aktywator/PBNFile.cs b/Aktywator/PBNFile.cs new file mode 100644 index 0000000..044630a --- /dev/null +++ b/Aktywator/PBNFile.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Aktywator +{ + class PBNFile + { + public List Boards; + + private String filename; + + public PBNFile(String filename) + { + this.filename = filename; + this.Boards = new List(); + String[] fileContents = File.ReadAllLines(this.filename); + List contents = new List(); + foreach (String line in fileContents) { + contents.Add(line.Trim()); + } + List lines = new List(); + foreach (String line in contents) + { + if (line.Length == 0) + { + if (lines.Count > 0) + { + this.Boards.Add(new PBNBoard(lines)); + lines = new List(); + } + } + else + { + lines.Add(line); + } + } + if (lines.Count > 0) + { + this.Boards.Add(new PBNBoard(lines)); + } + } + + } +} diff --git a/README.md b/README.md index b801265..034b115 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,7 @@ Więcej info: http://michzimny.pl/aktywator Nie jestem dumny z tego kodu, ale działa i dostałem prośby o udostępnienie źródeł, więc udostępniam. + +Program zawiera część kodu źródłowego projektu BCDD: http://github.com/emkael/bcdd +Ta część źródeł udpostępniana jest w uproszczonej licencji BSD: https://opensource.org/licenses/BSD-2-Clause, kompatybilnej z licencją GPL reszty programu. + -- cgit v1.2.3 From 3fd493b395d27749749587518d76a4e5d648920c Mon Sep 17 00:00:00 2001 From: emkael Date: Wed, 9 Nov 2016 14:20:32 +0100 Subject: * PBN double-dummy data support for HandEvaluation table --- Aktywator/Bws.cs | 34 ++++++++++++++++++++++++++++++++++ Aktywator/DDTable.cs | 9 ++++++--- Aktywator/PBNBoard.cs | 3 ++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Aktywator/Bws.cs b/Aktywator/Bws.cs index 0be06df..eda99a1 100644 --- a/Aktywator/Bws.cs +++ b/Aktywator/Bws.cs @@ -104,6 +104,8 @@ namespace Aktywator return false; if (!sql.checkTableExists("HandRecord")) return false; + if (!sql.checkTableExists("HandEvaluation")) + return false; return true; } @@ -167,6 +169,19 @@ namespace Aktywator catch (OleDbException) { } + try + { + sql.query("CREATE TABLE HandEvaluation (`Section` integer, `Board` integer, " + + "NorthSpades integer,NorthHearts integer,NorthDiamonds integer,NorthClubs integer,NorthNotrump integer," + + "EastSpades integer,EastHearts integer,EastDiamonds integer,EastClubs integer,EastNotrump integer," + + "SouthSpades integer,SouthHearts integer,SouthDiamonds integer,SouthClubs integer,SouthNotrump integer," + + "WestSpades integer,WestHearts integer,WestDiamonds integer,WestClubs integer,WestNotrump integer," + + "NorthHcp integer,EastHcp integer,SouthHcp integer,WestHcp integer" + + ");"); + } + catch (OleDbException) + { + } } public void updateSettings() @@ -377,6 +392,7 @@ namespace Aktywator public void loadHandRecords(PBN pbn) { sql.query("DELETE FROM HandRecord"); + sql.query("DELETE FROM HandEvaluation"); for (int i = 0; i < pbn.handRecords.Length; i++) if (pbn.handRecords[i] != null) for (int section = 1; section <= highSection(); section++) @@ -403,6 +419,24 @@ namespace Aktywator str.Append(b.west[2]); str.Append("','"); str.Append(b.west[3]); str.Append("')"); sql.query(str.ToString()); + int[,] ddTable = pbn.ddTables[i].GetDDTable(); + if (ddTable != null) + { + StringBuilder ddStr = new StringBuilder(); + ddStr.Append("INSERT INTO HandEvaluation VALUES("); + ddStr.Append(section); ddStr.Append(","); + ddStr.Append(i); ddStr.Append(","); + for (int player = 0; player < 4; player++) + { + for (int denom = 0; denom < 5; denom++) + { + ddStr.Append(ddTable[player, denom]); + ddStr.Append(","); + } + } + ddStr.Append("0,0,0,0)"); // HCP not supported yet + sql.query(ddStr.ToString()); + } } } } diff --git a/Aktywator/DDTable.cs b/Aktywator/DDTable.cs index 38e0fbd..5de9c3b 100644 --- a/Aktywator/DDTable.cs +++ b/Aktywator/DDTable.cs @@ -14,7 +14,8 @@ namespace Aktywator class DDTable { - public static char[] DENOMINATIONS = { 'C', 'D', 'H', 'S', 'N' }; + public static char[] DENOMINATIONS = { 'S', 'H', 'D', 'C', 'N' }; + private static char[] JFR_DENOMS = {'N', 'S', 'H', 'D', 'C'}; public static char[] PLAYERS = { 'N', 'E', 'S', 'W' }; private PBNBoard board; @@ -58,11 +59,13 @@ namespace Aktywator { char player = playerAbility.Groups[1].Value[0]; int playerID = Array.IndexOf(PLAYERS, player); - int denomID = 4; + int denomID; + int denom = 0; foreach (char tricks in playerAbility.Groups[2].Value.ToCharArray()) { + denomID = Array.IndexOf(DENOMINATIONS, JFR_DENOMS[denom]); result[playerID, denomID] = (tricks > '9') ? (tricks - 'A' + 10) : (tricks - '0'); - denomID--; + denom++; } } return this.validateTable(result); diff --git a/Aktywator/PBNBoard.cs b/Aktywator/PBNBoard.cs index 605630c..fadfd22 100644 --- a/Aktywator/PBNBoard.cs +++ b/Aktywator/PBNBoard.cs @@ -87,7 +87,8 @@ namespace Aktywator public String GetLayout() { - return this.GetField("Deal"); + string[] dealParts = this.GetField("Deal").Split(':'); + return dealParts[dealParts.Length - 1]; } public String GetNumber() -- cgit v1.2.3 From 0cfcb31daea464584315263225381ba53c24a9eb Mon Sep 17 00:00:00 2001 From: emkael Date: Wed, 9 Nov 2016 14:25:56 +0100 Subject: * HCP support for HandEvaluation table --- Aktywator/Bws.cs | 10 +++++++++- Aktywator/HandRecord.cs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Aktywator/Bws.cs b/Aktywator/Bws.cs index eda99a1..87c9081 100644 --- a/Aktywator/Bws.cs +++ b/Aktywator/Bws.cs @@ -434,7 +434,15 @@ namespace Aktywator ddStr.Append(","); } } - ddStr.Append("0,0,0,0)"); // HCP not supported yet + for (int j = 0; j < 4; j++) + { + ddStr.Append(b.hpcs[j]); + if (j < 3) + { + ddStr.Append(","); + } + } + ddStr.Append(")"); sql.query(ddStr.ToString()); } } diff --git a/Aktywator/HandRecord.cs b/Aktywator/HandRecord.cs index bd0e9f9..199e94f 100644 --- a/Aktywator/HandRecord.cs +++ b/Aktywator/HandRecord.cs @@ -10,6 +10,7 @@ namespace Aktywator public string[] east; public string[] south; public string[] west; + public int[] hpcs; public HandRecord() { @@ -19,6 +20,31 @@ namespace Aktywator west = new string[4]; } + private int _hpcFromHand(string hand) + { + int hpc = 0; + foreach (char c in hand) + { + if (c == 'a' || c == 'A') + { + hpc += 4; + } + if (c == 'k' || c == 'K') + { + hpc += 3; + } + if (c == 'q' || c == 'Q') + { + hpc += 2; + } + if (c == 'j' || c == 'J') + { + hpc += 1; + } + } + return hpc; + } + public HandRecord(string pbnString) { string[] hand = pbnString.Split(' '); @@ -26,6 +52,11 @@ namespace Aktywator east = hand[1].Split('.'); south = hand[2].Split('.'); west = hand[3].Split('.'); + hpcs = new int[4]; + for (int i = 0; i < 4; i++) + { + hpcs[i] = this._hpcFromHand(hand[i]); + } } } } -- cgit v1.2.3