diff options
author | emkael <emkael@tlen.pl> | 2019-05-23 00:08:20 +0200 |
---|---|---|
committer | emkael <emkael@tlen.pl> | 2019-05-23 00:08:20 +0200 |
commit | 2df6c48942bee2c6eae371a744a3c367e4cf8d68 (patch) | |
tree | 23a581734edadc2ed4065b5e693474bd3e3d8c0f /dealconvert | |
parent | 319330ef6f14708161a18d27fbaa1f7c5b239309 (diff) |
DLM format support
Diffstat (limited to 'dealconvert')
-rw-r--r-- | dealconvert/formats/dlm.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/dealconvert/formats/dlm.py b/dealconvert/formats/dlm.py index 7486a65..4fbd371 100644 --- a/dealconvert/formats/dlm.py +++ b/dealconvert/formats/dlm.py @@ -1,6 +1,110 @@ +import sys + from . import DealFormat +from .. import dto class DLMFormat(DealFormat): @property def suffix(self): return '.dlm' + + def parse_content(self, content): + lines = [line.strip() for line in content.readlines()] + if lines[0] != '[Document]': + print 'ERROR: .dlm header not detected: %s' % (lines[0]) + sys.exit() + fields = {} + for line in lines[1:]: + try: + fields[line.split('=')[0]] = line.split('=')[1] + except IndexError: + print 'WARNING: unable to parse .dlm line: %s' % (line) + try: + boards = range(int(fields['From board']), int(fields['To board'])+1) + except (ValueError, IndexError): + print 'ERROR: unable to parse .dlm board number data' + sys.exit() + checksum = len(boards) + if fields['Status'] == 'Show': + checksum ^= 1 + if checksum != int(fields['Checksum']): + print 'WARNING: .dlm checksum does not match: %d/%s' % ( + checksum, fields['Checksum']) + dealset = [] + for board in boards: + try: + board_str = fields['Board %02d' % (board)] + except IndexError: + print 'WARNING: board %d not found in .dlm' % (board) + continue + try: + checksum = board + str_checksum = int(board_str[26:]) + values = [] + for char in board_str[0:26]: + checksum ^= ord(char) + value = ord(char) - 97 + values.append(value / 4) + values.append(value % 4) + if checksum != str_checksum: + print 'WARNING: .dlm board checksum mismatch: %s (%d)' % ( + board_str, checksum) + deal = dto.Deal() + deal.number = board + deal.dealer = deal.get_dealer(board) + deal.vulnerable = deal.get_vulnerability(board) + for suit in range(0, 4): + for card in range(0, 13): + deal.hands[values[suit*13+card]][suit].append( + self.cards[card]) + dealset.append(deal) + except: + print 'WARNING: malformed .dlm data: %s' % (board_str) + return dealset + + def output_content(self, out_file, dealset): + dealset = dealset[0:99] + board_numbers = [deal.number for deal in dealset] + first_board = min(board_numbers) + board_count = len(dealset) + for board in range(first_board, first_board+board_count): + if board not in board_numbers: + print 'ERROR: .dlm format requires consequent board numbers' + sys.exit() + header = [] + header.append('[Document]') + header.append('Headline=Generated by deal-converter.py') + header.append('Status=Show') + header.append('Duplicates=1') + header.append('From board=%d' % (first_board)) + header.append('To board=%d' % (first_board+board_count-1)) + header.append('Next board to duplimate=0') + header.append('PrintOuts=0') + header.append('Crypto key=0') + header.append('Checksum=%d' % (board_count^1)) + lines = ['', ''] * 99 + for i in range(1, first_board) + range(first_board+board_count, 100): + lines[(i-1)*2] = 'Duplicates %02d=0' % (i) + lines[(i-1)*2+1] = 'Board %02d=aaaaaabffffffkkkkkklpppppp%03d' % ( + i, i^14) + for board in range(first_board, first_board+board_count): + deal = dealset[board - first_board] + lines[(board-1)*2] = 'Duplicates %02d=0' % (board) + values = [None] * 52 + for i, hand in enumerate(deal.hands): + for suit, cards in enumerate(hand): + for card in cards: + try: + values[suit*13+self.cards.index(card)] = i + except IndexError: + print 'ERROR: invalid card: %s' % (card) + line = 'Board %02d=' % (board) + checksum = board + for i in range(0, 26): + value = values[i*2]*4 + values[i*2+1] + checksum ^= 97+value + line += chr(97+value) + line += '%03d' % (checksum) + lines[(board-1)*2+1] = line + for line in header+lines: + out_file.write(line + '\r\n') |