summaryrefslogtreecommitdiff
path: root/src/BoardLayout.cs
diff options
context:
space:
mode:
authorMichał Klichowicz <emkael@tlen.pl>2026-09-12 01:22:03 +0200
committerMichał Klichowicz <emkael@tlen.pl>2026-09-12 01:22:03 +0200
commit5bb8e3d3863a7fd0cffecc7186254ca038fbc49e (patch)
tree3b7ef141d961d27182f8edac6341dc35789123b8 /src/BoardLayout.cs
parent7f34ea7410125e0ab74e7aa647ec68e2ec75db32 (diff)
Board layout validation and error reporting
Diffstat (limited to 'src/BoardLayout.cs')
-rw-r--r--src/BoardLayout.cs84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/BoardLayout.cs b/src/BoardLayout.cs
new file mode 100644
index 0000000..74c9d0d
--- /dev/null
+++ b/src/BoardLayout.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace BCDD
+{
+ class InvalidLayoutException : Exception
+ {
+ public InvalidLayoutException() : base() { }
+ public InvalidLayoutException(String msg) : base(msg) { }
+ }
+
+ class BoardLayout
+ {
+ public Dictionary<String, Dictionary<String, List<String>>> Hands;
+
+ public BoardLayout() { }
+ public BoardLayout(String pbnLayout)
+ {
+ this.parsePBNLayout(pbnLayout);
+ }
+
+ public void parsePBNLayout(string pbnLayout)
+ {
+ this.Hands = new Dictionary<String, Dictionary<String, List<String>>>();
+
+ // split first player designation from hands
+ string[] deal = pbnLayout.Split(':');
+ if (deal.Length < 2)
+ {
+ throw new InvalidLayoutException(String.Format("First hand undefined in PBN layout: {0}", pbnLayout));
+ }
+ if (deal[0].Length != 1 || !BCalcWrapper.PLAYERS.Contains(deal[0][0]))
+ {
+ throw new InvalidLayoutException(String.Format("Invalid first hand designation: {0}", deal[0]));
+ }
+
+ // determine order of players for hands
+ int handLetterIndex = Array.IndexOf(BCalcWrapper.PLAYERS, deal[0][0]);
+ char[] handLetters = new char[4];
+ Array.Copy(BCalcWrapper.PLAYERS, handLetterIndex, handLetters, 0, 4 - handLetterIndex);
+ Array.Copy(BCalcWrapper.PLAYERS, 0, handLetters, 4 - handLetterIndex, handLetterIndex);
+
+ // split cards into hands
+ string[] playerHands = deal[1].Split(' ');
+ if (playerHands.Length != 4)
+ {
+ throw new InvalidLayoutException(String.Format("Deal does not contain four hands: {0}", deal[1]));
+ }
+
+ // split each hand into suits
+ for (int playerIndex = 0; playerIndex < playerHands.Length; playerIndex++)
+ {
+ Dictionary<String, List<String>> hand = new Dictionary<string, List<String>>();
+ string[] cards = playerHands[playerIndex].Split('.');
+ if (cards.Length != 4)
+ {
+ throw new InvalidLayoutException(String.Format("Hand does not contain four suits: {0}", playerHands[playerIndex]));
+ }
+ int playerCardCount = 0;
+ for (int suitIndex = 0; suitIndex < cards.Length; suitIndex++)
+ {
+ List<String> currentHand = new List<String>();
+ foreach (String card in Regex.Split(cards[suitIndex], string.Empty))
+ {
+ if (card.Length > 0)
+ {
+ currentHand.Add(card);
+ playerCardCount++;
+ }
+ }
+ hand[(BCalcWrapper.DENOMINATIONS[3 - suitIndex]).ToString()] = currentHand;
+ }
+ if (playerCardCount != 13)
+ {
+ throw new InvalidLayoutException(String.Format("Hand does not contain 13 cards: {0}", playerHands[playerIndex]));
+ }
+ this.Hands[(handLetters[playerIndex]).ToString()] = hand;
+ }
+ }
+ }
+}