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
|
from __future__ import print_function
import sys
import array
class Wall(object):
"""an obstructing static wall"""
def __init__(self, position):
self.x, self.y = position
def __getstate__(self):
return self.x, self.y
def __setstate__(self, state):
self.x, self.y = state
class Robot(object):
"""represents a robot moving on a grid."""
def __init__(self, name, grid_dimensions, position, direction=(0, 0), strength=5):
self.name = name
self.x, self.y = position
self.dx, self.dy = direction
self.gridw, self.gridh = grid_dimensions
self.strength = strength
def __str__(self):
return "ROBOT '%s'; pos(%d,%d); dir(%d,%d); strength %d" % (self.name, self.x, self.y, self.dx, self.dy, self.strength)
@staticmethod
def dict_to_robot(classname, data):
assert classname == "robot.Robot"
return Robot(data["name"], data["grid_dimensions"], data["position"], data["direction"], data["strength"])
@staticmethod
def robot_to_dict(robot):
return {
"__class__": "robot.Robot",
"name": robot.name,
"grid_dimensions": (robot.gridw, robot.gridh),
"position": (robot.x, robot.y),
"direction": (robot.dx, robot.dy),
"strength": robot.strength,
}
def move(self, world=None):
# minmax to avoid moving off the sides
x = min(self.gridw - 1, max(0, self.x + self.dx))
y = min(self.gridh - 1, max(0, self.y + self.dy))
if x == self.x and y == self.y:
return
if world and self.__process_collision(x, y, world):
return
self.x, self.y = x, y
def __process_collision(self, newx, newy, world):
other = world.collides(newx, newy)
if not other:
return False # we didn't hit anything
self.dx, self.dy = 0, 0 # come to a standstill when we hit something
if isinstance(other, Wall):
self.strength -= 1 # hit wall, decrease our strength
if self.strength <= 0:
print("[server] %s killed himself!" % self.name)
world.remove(self)
self.died(None, world)
else:
other.strength -= 1 # hit other robot, decrease other robot's strength
self.collision(other)
if other.strength <= 0:
world.remove(other)
other.died(self, world)
print("[server] %s killed %s!" % (self.name, other.name))
return True
def killed(self, victim, world):
"""you can override this to react on kills"""
pass
def collision(self, other):
"""you can override this to react on collisions between bots"""
pass
def emote(self, text):
"""you can override this"""
print("[server] %s says: '%s'" % (self.name, text))
class World(object):
"""the world the robots move in (Cartesian grid)"""
def __init__(self, width, height):
self.width = width
self.height = height
self.all = []
self.robots = []
def add_wall(self, wall):
self.all.append(wall)
def add_robot(self, bot):
self.all.append(bot)
self.robots.append(bot)
def collides(self, x, y):
for obj in self.all:
if obj.x == x and obj.y == y:
return obj
return None
def remove(self, obj):
self.all.remove(obj)
self.robots.remove(obj)
def dump(self):
line = ' ' * self.width
if sys.version_info >= (3, 0):
line = bytes(line, "ASCII")
grid = [array.array('b', line) for y in range(self.height)]
for obj in self.all:
grid[obj.y][obj.x] = ord('R') if isinstance(obj, Robot) else ord('#')
return grid
def __getstate__(self):
return self.width, self.height, self.all, self.robots
def __setstate__(self, state):
self.width, self.height, self.all, self.robots = state
|