-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpm6.py
executable file
·136 lines (123 loc) · 4.76 KB
/
pm6.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#! /usr/bin/env python
# m6.py - calculate points costs of Mini-Six Characters in YAML.
import collections
import yaml
import json
import re
import sys
import os
import optparse;
line_of_equals = '=' * 43
class InvalidStat (Exception):
def __init__ (self, stat, msg):
self.stat = stat
self.msg = msg
pips_per_die = 3
dice_rx = re.compile (r"^([0-9]+)[Dd](\+([1-2]))?$")
def dice_to_cost (stat):
m = dice_rx.match (stat)
if m == None:
raise InvalidStat (stat, 'invalid stat')
dice = int (m.group (1))
pips = int (m.group (3)) if m.group (3) else 0
return (dice * pips_per_die) + pips
def cost_to_dice (cost):
dice = cost / pips_per_die
pips = cost % pips_per_die
return '%dd+%d' % (dice, pips)
def process_file (f, use_yaml):
s = f.read ()
if use_yaml:
characters = yaml.safe_load (s)
else:
characters = json.loads (s, object_pairs_hook=collections.OrderedDict)
i = 0
for character in characters:
i = i + 1
if i > 1:
print ("%s", line_of_equals)
calculate_character (character)
def process_filename (filename):
(root, ext) = os.path.splitext (filename)
with open (sys.argv[1], 'r') as f:
if ext == '.yaml':
process_file (f, True)
elif ext == '.json':
process_file (f, False)
else:
print ('m6.py: fatal error: unknown format "%s" in input filename "%s"' %
(ext, filename))
sys.exit (1)
def calculate_character (character):
if 'Name' in character:
print ('name: %s' % character['Name'])
if 'Description' in character:
print (' %s' % character['Description'])
if 'Player' in character:
print ('player: %s' % character['Player'])
if 'Statistics' in character:
statistics = character['Statistics']
else:
statistics = [ "Might", "Agility", "Wit", "Charm" ]
# TODO: Check what form skills are listed, relative or absolute.
# TODO: Check where skills listed, with stats or under 'skills'
#
# This works for absolute skills listed with stats.
total_stat_cost = 0
total_skill_cost = 0
for statname in statistics:
stat_and_skills = character[statname]
if len (stat_and_skills) < 1:
raise Exception ('Missing stat: %d' % statname)
stat = stat_and_skills[:1][0]
stat_cost = dice_to_cost (stat)
total_stat_cost += stat_cost
print ('%-30s (%3d points)' % ('%s: %s' % (statname, stat), stat_cost))
skills = stat_and_skills[1:]
skills = sorted (skills, key=lambda skill: skill[0])
for [name, dice] in skills:
skill_cost = dice_to_cost (dice)
relative_cost = skill_cost - stat_cost
relative_dice = cost_to_dice (relative_cost)
total_skill_cost += relative_cost
print (' %-19s %6s (%3d points)' % (
'%s: %s' % (name, dice),
'+' + relative_dice,
relative_cost))
total_stat_dice = cost_to_dice (total_stat_cost)
total_skill_dice = cost_to_dice (total_skill_cost)
total_skill_and_perk_cost = total_skill_cost
total_perk_cost = 0
if 'Perks' in character:
print ('Perks: ')
perk_count = 0
for [perk, perk_dice] in character['Perks']:
perk_cost = dice_to_cost (perk_dice)
perk_count = perk_count + 1
print (' %-26s (%3d points)' % ("%s: %s" % (perk, perk_dice), perk_cost))
# Perk cost is in dice
total_perk_cost += perk_cost
total_skill_and_perk_cost += perk_cost
total_perk_dice = cost_to_dice (total_perk_cost)
print
print ('total stat: %6s (%3d points)' %
(total_stat_dice, total_stat_cost))
print ('total skill: %6s (%3d points)' %
(total_skill_dice, total_skill_cost))
print ('total perk: %6s (%3d points)' %
(total_perk_dice, total_perk_cost))
total_skill_and_perk_dice = cost_to_dice (total_skill_and_perk_cost)
print ('total (skill + perk): %6s (%3d points)' %
(total_skill_and_perk_dice, total_skill_and_perk_cost))
total_cost = total_stat_cost + total_skill_cost + total_perk_cost
total_dice = cost_to_dice (total_cost)
print ('total: %6s (%3d points)' %
(total_dice, total_cost))
parser = optparse.OptionParser ()
(options, args) = parser.parse_args ()
if len (args) == 0:
process_file (sys.stdin, use_yaml)
else:
for filename in args:
process_filename (filename)
sys.exit (1)