Added player colors
authorW. Trevor King <wking@drexel.edu>
Sun, 28 Mar 2010 02:05:23 +0000 (22:05 -0400)
committerW. Trevor King <wking@drexel.edu>
Sun, 28 Mar 2010 02:05:23 +0000 (22:05 -0400)
pyrisk/graphics.py
share/templates/earth/player.col [new file with mode: 0644]

index 6e47f2a..32cc46e 100644 (file)
@@ -20,6 +20,7 @@ Creates SVG files by hand.  See the TemplateLibrary class for a
 description of map specification format.
 """
 
+import math
 import operator
 import os
 import os.path
@@ -31,11 +32,12 @@ class Template (NameMixin):
     """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.
@@ -45,10 +47,12 @@ class TemplateLibrary (object):
     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:
@@ -69,11 +73,15 @@ class TemplateLibrary (object):
                 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'):
@@ -355,12 +363,13 @@ class WorldRenderer (object):
         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"?>',
@@ -373,9 +382,14 @@ class WorldRenderer (object):
             '<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 = ''
@@ -411,6 +425,19 @@ class WorldRenderer (object):
                                            +(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):
@@ -477,6 +504,18 @@ class WorldRenderer (object):
         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
 
@@ -486,9 +525,14 @@ def test():
     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()
diff --git a/share/templates/earth/player.col b/share/templates/earth/player.col
new file mode 100644 (file)
index 0000000..8448977
--- /dev/null
@@ -0,0 +1,6 @@
+1      red
+2      blue
+3      green
+4      yellow
+5      grey
+6      black