home · contact · privacy
Don't generate objects at illegal positions. Plus, refactor.
[plomrogue2-experiments] / new / plomrogue / game.py
index e24edbb5404543e9c10a212556bd92972af152fd..da8fe1a49962928d10fec5424baab8669db8a2ba 100755 (executable)
@@ -1,15 +1,18 @@
-from plomrogue.tasks import Task_WAIT, Task_MOVE, Task_PICKUP, Task_DROP
-from plomrogue.errors import ArgError
-from plomrogue.commands import (cmd_GEN_WORLD, cmd_GET_GAMESTATE, cmd_MAP,
-                                cmd_MAP, cmd_THING_TYPE, cmd_THING_POS,
-                                cmd_THING_INVENTORY,
-                                cmd_TERRAIN_LINE, cmd_PLAYER_ID, cmd_TURN,
-                                cmd_SWITCH_PLAYER, cmd_SAVE)
+from plomrogue.tasks import (Task_WAIT, Task_MOVE, Task_PICKUP,
+                             Task_DROP, Task_EAT)
+from plomrogue.errors import ArgError, GameError
+from plomrogue.commands import (cmd_GEN_WORLD, cmd_GET_GAMESTATE,
+                                cmd_MAP, cmd_MAP, cmd_THING_TYPE,
+                                cmd_THING_POS, cmd_THING_INVENTORY,
+                                cmd_THING_HEALTH,
+                                cmd_GET_PICKABLE_ITEMS,
+                                cmd_TERRAIN_LINE, cmd_PLAYER_ID,
+                                cmd_TURN, cmd_SWITCH_PLAYER, cmd_SAVE)
 from plomrogue.mapping import MapHex
 from plomrogue.parser import Parser
 from plomrogue.io import GameIO
 from plomrogue.misc import quote, stringify_yx
 from plomrogue.mapping import MapHex
 from plomrogue.parser import Parser
 from plomrogue.io import GameIO
 from plomrogue.misc import quote, stringify_yx
-from plomrogue.things import Thing, ThingMonster, ThingHuman, ThingItem
+from plomrogue.things import Thing, ThingMonster, ThingHuman, ThingFood
 
 
 
 
 
 
@@ -30,6 +33,13 @@ class WorldBase:
             return t
         return None
 
             return t
         return None
 
+    def things_at_pos(self, yx):
+        things = []
+        for t in self.things:
+            if t.position == yx:
+                things += [t]
+        return things
+
 
 
 class World(WorldBase):
 
 
 class World(WorldBase):
@@ -37,6 +47,7 @@ class World(WorldBase):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.player_id = 0
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.player_id = 0
+        self.player_is_alive = True
 
     @property
     def player(self):
 
     @property
     def player(self):
@@ -60,7 +71,9 @@ class World(WorldBase):
         (after incrementing the world turn) all that come before the
         player; then the player's .proceed() is run, and if it does
         not finish his task, the loop starts at the beginning. Once
         (after incrementing the world turn) all that come before the
         player; then the player's .proceed() is run, and if it does
         not finish his task, the loop starts at the beginning. Once
-        the player's task is finished, the loop breaks.
+        the player's task is finished, or the player is dead, the loop
+        breaks.
+
         """
         while True:
             player_i = self.things.index(self.player)
         """
         while True:
             player_i = self.things.index(self.player)
@@ -70,7 +83,7 @@ class World(WorldBase):
             for thing in self.things[:player_i]:
                 thing.proceed()
             self.player.proceed(is_AI=False)
             for thing in self.things[:player_i]:
                 thing.proceed()
             self.player.proceed(is_AI=False)
-            if self.player.task is None:
+            if self.player.task is None or not self.player_is_alive:
                 break
 
     def make_new(self, yx, seed):
                 break
 
     def make_new(self, yx, seed):
@@ -78,8 +91,15 @@ class World(WorldBase):
 
         def add_thing(type_):
             t = self.game.thing_types[type_](self)
 
         def add_thing(type_):
             t = self.game.thing_types[type_](self)
-            t.position = (random.randint(0, yx[0] -1),
-                          random.randint(0, yx[1] - 1))
+            while True:
+                new_pos = (random.randint(0, yx[0] -1),
+                           random.randint(0, yx[1] - 1))
+                if self.map_[new_pos] != '.':
+                    continue
+                if len(self.things_at_pos(new_pos)) > 0:
+                    continue
+                break
+            t.position = new_pos
             self.things += [t]
             return t
 
             self.things += [t]
             return t
 
@@ -97,8 +117,10 @@ class World(WorldBase):
         self.player_id = player.id_
         add_thing('monster')
         add_thing('monster')
         self.player_id = player.id_
         add_thing('monster')
         add_thing('monster')
-        add_thing('item')
-        add_thing('item')
+        add_thing('food')
+        add_thing('food')
+        add_thing('food')
+        add_thing('food')
         return 'success'
 
 
         return 'success'
 
 
@@ -111,14 +133,17 @@ class Game:
         self.tasks = {'WAIT': Task_WAIT,
                       'MOVE': Task_MOVE,
                       'PICKUP': Task_PICKUP,
         self.tasks = {'WAIT': Task_WAIT,
                       'MOVE': Task_MOVE,
                       'PICKUP': Task_PICKUP,
+                      'EAT': Task_EAT,
                       'DROP': Task_DROP}
         self.commands = {'GEN_WORLD': cmd_GEN_WORLD,
                          'GET_GAMESTATE': cmd_GET_GAMESTATE,
                          'MAP': cmd_MAP,
                          'THING_TYPE': cmd_THING_TYPE,
                          'THING_POS': cmd_THING_POS,
                       'DROP': Task_DROP}
         self.commands = {'GEN_WORLD': cmd_GEN_WORLD,
                          'GET_GAMESTATE': cmd_GET_GAMESTATE,
                          'MAP': cmd_MAP,
                          'THING_TYPE': cmd_THING_TYPE,
                          'THING_POS': cmd_THING_POS,
+                         'THING_HEALTH': cmd_THING_HEALTH,
                          'THING_INVENTORY': cmd_THING_INVENTORY,
                          'TERRAIN_LINE': cmd_TERRAIN_LINE,
                          'THING_INVENTORY': cmd_THING_INVENTORY,
                          'TERRAIN_LINE': cmd_TERRAIN_LINE,
+                         'GET_PICKABLE_ITEMS': cmd_GET_PICKABLE_ITEMS,
                          'PLAYER_ID': cmd_PLAYER_ID,
                          'TURN': cmd_TURN,
                          'SWITCH_PLAYER': cmd_SWITCH_PLAYER,
                          'PLAYER_ID': cmd_PLAYER_ID,
                          'TURN': cmd_TURN,
                          'SWITCH_PLAYER': cmd_SWITCH_PLAYER,
@@ -128,7 +153,7 @@ class Game:
         self.thing_type = Thing
         self.thing_types = {'human': ThingHuman,
                             'monster': ThingMonster,
         self.thing_type = Thing
         self.thing_types = {'human': ThingHuman,
                             'monster': ThingMonster,
-                            'item': ThingItem}
+                            'food': ThingFood}
 
     def get_string_options(self, string_option_type):
         if string_option_type == 'direction':
 
     def get_string_options(self, string_option_type):
         if string_option_type == 'direction':
@@ -150,6 +175,9 @@ class Game:
             self.io.send('THING_TYPE %s %s' % (thing.id_, thing.type_))
             self.io.send('THING_POS %s %s' % (thing.id_,
                                               stringify_yx(thing.position)))
             self.io.send('THING_TYPE %s %s' % (thing.id_, thing.type_))
             self.io.send('THING_POS %s %s' % (thing.id_,
                                               stringify_yx(thing.position)))
+            if hasattr(thing, 'health'):
+                self.io.send('THING_HEALTH %s %s' % (thing.id_,
+                                                     thing.health))
         if len(self.world.player.inventory) > 0:
             self.io.send('PLAYER_INVENTORY %s' %
                          ','.join([str(i) for i in self.world.player.inventory]))
         if len(self.world.player.inventory) > 0:
             self.io.send('PLAYER_INVENTORY %s' %
                          ','.join([str(i) for i in self.world.player.inventory]))
@@ -183,6 +211,8 @@ class Game:
             return p
 
         def cmd_TASK_colon(task_name, game, *args):
             return p
 
         def cmd_TASK_colon(task_name, game, *args):
+            if not game.world.player_is_alive:
+                raise GameError('You are dead.')
             game.world.player.set_task(task_name, args)
             game.proceed()
 
             game.world.player.set_task(task_name, args)
             game.proceed()