Added Engine.fortify (previously fortification would break Engine)
authorW. Trevor King <wking@drexel.edu>
Sat, 27 Mar 2010 01:40:33 +0000 (21:40 -0400)
committerW. Trevor King <wking@drexel.edu>
Sat, 27 Mar 2010 01:40:33 +0000 (21:40 -0400)
Also moved adjacency check from Engine.attack_and_fortify to
Engine.attack and Engine.fortify.  This will make it easier for
subclasses to change the rules (e.g. non-adjacent fortifications).

Also reordered attack / conquer log messages:
  'attacked X from Y' -> 'X attacks Y'
which is shorter and makes the A:B ratios more clear.

pyrisk/base.py
pyrisk/log.py

index 38d3b23..7f9fcef 100644 (file)
@@ -673,9 +673,6 @@ class Engine (ID_CmpMixin):
                         target = self.world.territory_by_name(target_name)
                     except KeyError:
                         raise PlayerError('Invalid territory "%s"' % targer_name)
-                    if not source.borders(target):
-                        raise PlayerError('Cannot reach %s from %s to %s'
-                                          % (target, source, mode))
                     if mode == 'attack':
                         tplayer = target.player
                         capture = self.attack(source, target, armies)
@@ -698,6 +695,9 @@ class Engine (ID_CmpMixin):
         if armies >= source.armies:
             raise PlayerError('%s attacking %s with %d armies, but only %d are available.'
                               % (source, target, armies, source.armies-1))
+        if not source.borders(target):
+            raise PlayerError('Cannot reach %s from %s to attack'
+                              % (target, source))
         s_dice = sorted([random.randint(1, 6) for i in range(armies)],
                         reverse=True)
         t_dice = sorted([random.randint(1, 6) for i in range(min(2, target.armies))],
@@ -738,6 +738,21 @@ class Engine (ID_CmpMixin):
                     continue
             source.armies -= support
             target.armies += support
+    def fortify(self, source, target, armies):
+        if source.player != target.player:
+            raise PlayerError('%s (%s) cannot fortifiy %s (%s).'
+                              % (source, source.player, target, target.player))
+        if armies == 0:
+            return
+        if armies >= source.armies:
+            raise PlayerError('%s fortifying %s with %d armies, but only %d are available.'
+                              % (source, target, armies, source.armies-1))
+        if not source.borders(target):
+            raise PlayerError('Cannot reach %s from %s to fortify'
+                              % (target, source))
+        source.armies -= armies
+        target.armies += armies
+        self.log(Fortify(source, target, armies))
     def player_killed(self, player, killer):
         player.alive = False
         killer.hand.extend(player.hand)
index b629616..1cb7955 100644 (file)
@@ -140,8 +140,8 @@ class Attack (MoveArmies):
         self.t_dice = t_dice
         self.s_dead = s_dead
         self.t_dead = t_dead
-        self.message = 'attacked %s from %s with %d:%d.  Deaths %d:%d.  Remaining %d:%d' \
-            % (self.target, self.source, len(self.s_dice), len(self.t_dice),
+        self.message = '%s attacks %s with %d:%d.  Deaths %d:%d.  Remaining %d:%d' \
+            % (self.source, self.target, len(self.s_dice), len(self.t_dice),
                self.s_dead, self.t_dead,
                self.source.armies, self.target.armies)
 
@@ -149,13 +149,13 @@ class Conquer (Attack):
     def __init__(self, source, target, s_dice, t_dice, s_dead, t_dead):
         Attack.__init__(self, source, target, s_dice, t_dice, s_dead, t_dead,
                         armies=target.armies)
-        self.message = self.message.replace('attacked', 'conquered')
+        self.message = self.message.replace('attacks', 'conquers')
 
 class Fortify (MoveArmies):
-    def __init__(self, *arg, **kwarg):
-        MoveArmies.__init__(self, *arg, **kwarg)
-        self.message = 'fortifies %s from %s with %d' \
-            % (self.target, self.source, self.armies)
+    def __init__(self, source, target, armies):
+        MoveArmies.__init__(self, source.player, source, target, armies)
+        self.message = '%s fortifies %s with %d' \
+            % (self.source, self.target, self.armies)
 
 class Logger (list):
     """Log messages generated by risk.base.Engine.