description of map specification format.
"""
+import math
import operator
import os
import os.path
"""Setup regions for a particular world.
"""
def __init__(self, name, regions, continent_colors={},
- line_colors={}):
+ line_colors={}, player_colors=[]):
NameMixin.__init__(self, name)
self.regions = regions
self.continent_colors = continent_colors
self.line_colors = line_colors
+ self.player_colors = player_colors
class TemplateLibrary (object):
"""Create Templates on demand from a directory of template data.
def __init__(self, template_dir='share/templates/'):
self.template_dir = os.path.abspath(os.path.expanduser(template_dir))
def get(self, name):
- region_pointlists,route_pointlists,continent_colors,line_colors = \
+ region_pointlists,route_pointlists,continent_colors,line_colors, \
+ player_colors = \
self._get_data(name)
regions = self._generate_regions(region_pointlists, route_pointlists)
- return Template(name, regions, continent_colors, line_colors)
+ return Template(name, regions, continent_colors, line_colors,
+ player_colors)
def _get_data(self, name):
dirname = os.path.join(self.template_dir, name.lower())
try:
c = self._read_colors(path)
if name == 'continent':
continent_colors = c
- else:
- assert name == 'line', name
+ elif name == 'line':
line_colors = c
+ else:
+ assert name == 'player', name
+ player_colors = []
+ for k,v in sorted(c.items()):
+ player_colors.append(v)
return (region_pointlists, route_pointlists,
- continent_colors, line_colors)
+ continent_colors, line_colors, player_colors)
def _read_pointlist(self, filename):
pointlist = []
for line in open(filename, 'r'):
self.buf = buf
self.line_width = line_width
self.dpcm = dpcm
- def render(self, world):
+ self.army_scale = 3
+ def render(self, world, players):
template = self.template_lib.get(world.name)
if template == None:
template = self._auto_template(world)
- return self.render_template(world, template)
- def render_template(self, world, template):
+ return self.render_template(world, players, template)
+ def render_template(self, world, players, template):
region_pos,width,height = self._locate(template)
lines = [
'<?xml version="1.0" standalone="no"?>',
'<title>%s</title>' % template,
'<desc>A PyRisk world snapshot</desc>',
]
+ terr_regions = {}
drawn_rts = {}
for r in template.regions:
t = self._matching_territory(world, r)
+ if t.name in terr_regions:
+ terr_regions[t.name].append(r)
+ else:
+ terr_regions[t.name] = [r]
c_col = template.continent_colors[t.continent.name]
if template.line_colors['border'] == None:
b_col_attr = ''
+(0,height)) # shift back into bbox
for p in rt])
])
+ for t in world.territories():
+ regions = terr_regions[t.name]
+ center = self._territory_center(region_pos, regions)
+ radius = self.army_scale*math.sqrt(t.armies)
+ color = template.player_colors[players.index(t.player)]
+ if color == None:
+ continue
+ lines.extend([
+ '<circle title="%s / %s / %s" fill="%s"'
+ % (t, t.player, t.armies, color),
+ ' cx="%d" cy="%d" r="%.1f" />'
+ % (center[0], center[1]*-1+height, radius),
+ ])
lines.extend(['</svg>', ''])
return '\n'.join(lines)
def _locate(self, template):
assert t != None, 'No territory in %s associated with region %s' \
% (world, region)
return t
+ def _territory_center(self, region_pos, regions):
+ """Return the center of mass of a territory composed of regions.
+
+ Note: currently not CM, just averages outline points.
+ """
+ points = []
+ for r in regions:
+ for p in r.outline:
+ points.append(p + region_pos[id(r)])
+ average = Vector((int(sum([p[0] for p in points])/len(points)),
+ int(sum([p[1] for p in points])/len(points))))
+ return average
def _auto_template(self, world):
raise NotImplementedError
return failures
def render_earth():
- from .base import generate_earth
+ from .base import generate_earth,Player,Engine
+ players = [Player('Alice'), Player('Bob'), Player('Charlie'),
+ Player('Eve'), Player('Mallory'), Player('Zoe')]
+ world = generate_earth()
+ e = Engine(world, players)
+ e.setup()
r = WorldRenderer()
- print r.render(generate_earth())
+ print r.render(e.world, players)
#f = open('world.svg', 'w')
#f.write(r.render(generate_earth()))
#f.close()