summaryrefslogtreecommitdiff
path: root/dealconvert
diff options
context:
space:
mode:
authoremkael <emkael@tlen.pl>2019-05-23 00:08:20 +0200
committeremkael <emkael@tlen.pl>2019-05-23 00:08:20 +0200
commit2df6c48942bee2c6eae371a744a3c367e4cf8d68 (patch)
tree23a581734edadc2ed4065b5e693474bd3e3d8c0f /dealconvert
parent319330ef6f14708161a18d27fbaa1f7c5b239309 (diff)
DLM format support
Diffstat (limited to 'dealconvert')
-rw-r--r--dealconvert/formats/dlm.py104
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')