File: robot.py

package info (click to toggle)
pyro4 4.82-2
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 2,528 kB
  • sloc: python: 17,736; makefile: 169; sh: 113; javascript: 62
file content (130 lines) | stat: -rw-r--r-- 4,066 bytes parent folder | download | duplicates (3)
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