summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremkael <emkael@tlen.pl>2020-02-18 17:08:58 +0100
committeremkael <emkael@tlen.pl>2020-02-18 17:08:58 +0100
commit4ca15ee0719bddd9311ca5941fe20375ae29d888 (patch)
treed0b04f15f1362208146ab053982a40443526f077
parenteb3e6c4116e9343e55594667200bb39e3a8ddd13 (diff)
LIN format support
-rw-r--r--dealconvert/formats/lin.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/dealconvert/formats/lin.py b/dealconvert/formats/lin.py
new file mode 100644
index 0000000..0c740c1
--- /dev/null
+++ b/dealconvert/formats/lin.py
@@ -0,0 +1,123 @@
+from collections import OrderedDict
+import re
+
+from . import DealFormat
+from .. import dto
+
+class LINFormat(DealFormat):
+
+ _qx_format = re.compile(r'^[oc](\d+)$')
+ _ah_format = re.compile(r'^[A-Za-z ]* (\d+)$')
+ _md_hand_format = re.compile(r'^S(.*)H(.*)D(.*)C(.*)$')
+ _suit_cards = 'AKQJT98765432'
+
+ @property
+ def suffix(self):
+ return '.lin'
+
+ def parse_content(self, content):
+ deals = OrderedDict()
+ event = ''
+ lines = [line.strip() for line in content.readlines()]
+ for line in lines:
+ chunks = line.split('|')
+ fields = {}
+ while len(chunks) > 1:
+ field_name = chunks.pop(0)
+ field_value = chunks.pop(0)
+ if field_name not in fields:
+ fields[field_name] = []
+ fields[field_name].append(field_value)
+ if 'vg' in fields:
+ event = fields['vg'][0].split(',')[0]
+ if 'md' in fields:
+ deal_number = None
+ for field in ['qx', 'ah']:
+ if field in fields:
+ match = getattr(
+ self, '_%s_format' % (field)).match(
+ fields[field][0])
+ if match:
+ deal_number = int(match.group(1))
+ break
+ if deal_number is not None:
+ layout = self._parse_md_field(fields['md'][0])
+ if layout:
+ if deal_number in deals:
+ if deals[deal_number] != layout:
+ print 'error, duplicate board number with differing layout'
+ deals[deal_number] = layout
+ else:
+ print 'layout not parsed: ' + fields['md'][0]
+ dealset = []
+ for number, layout in deals.iteritems():
+ deal = dto.Deal()
+ deal.event = event
+ deal.number = number
+ deal.hands = layout
+ deal.dealer = deal.get_dealer(deal.number)
+ deal.vulnerable = deal.get_vulnerability(deal.number)
+ dealset.append(deal)
+ return dealset
+
+ def _parse_md_field(self, value):
+ try:
+ first_hand = int(value[0])-1 # 0 = S, 1 = W, 2 = N, 3 = E
+ hands = value[1:].split(',')
+ layout = [[], [], [], []]
+ for i, hand in enumerate(hands):
+ layout[(first_hand+i+2)%4] = self._parse_md_hand(hand) # N <-> S, E <-> W
+ for j, single_hand in enumerate(layout):
+ if not sum([len(suit) for suit in single_hand]): # fill 4th hand if necessary
+ for k, suit in enumerate(single_hand):
+ layout[j][k] = ''.join([
+ c for c in self._suit_cards
+ if c not in ''.join([layout[h][k] for h in range(0, 4) if h != j])
+ ])
+ for j, single_hand in enumerate(layout):
+ for k, suit in enumerate(single_hand):
+ layout[j][k] = list(suit)
+ return layout
+ except:
+ return None
+
+ def _parse_md_hand(self, hand):
+ match = self._md_hand_format.match(hand)
+ if match:
+ return [''.join(sorted(
+ list(match.group(i)),
+ key=lambda c: self._suit_cards.index(c)))
+ for i in range(1, 5)]
+ return ['', '', '', '']
+
+ def output_content(self, out_file, dealset):
+ event_name = ([deal.event for deal in dealset if deal.event] or [''])[0]
+ first_deal = min([deal.number for deal in dealset])
+ last_deal = max([deal.number for deal in dealset])
+ lines = [
+ 'vg|%s,SEGMENT 1,I,%d,%d,HOME,0,AWAY,0|' % (event_name, first_deal, last_deal),
+ 'rs|,,,,,,,,,,,|',
+ 'pn|,,,,,,,|pg||'
+ ]
+ for deal in dealset:
+ dealer = (deal.dealer + 3) % 4 or 4
+ layout = ''
+ for i in range(0, 4):
+ for s, suit in enumerate(deal.hands[(i+dealer-3) % 4]):
+ layout += 'SHDC'[s]
+ layout += ''.join(suit)
+ if i < 3:
+ layout += ','
+ vulnerability = ('b' if deal.vulnerable['EW'] else 'n') \
+ if deal.vulnerable['NS'] \
+ else ('e' if deal.vulnerable['EW'] else '0')
+ for room in ['o', 'c']:
+ lines.append(
+ 'qx|%s%d|pn|,,,,,,,|md|%d%s|sv|%s|pg||' % (
+ room, deal.number,
+ dealer, layout,
+ vulnerability
+ )
+ )
+ for line in lines:
+ out_file.write(line + '\r\n')