Александър обнови решението на 13.05.2013 22:39 (преди над 11 години)
+class Vec2D(tuple):
+
+ def __new__(klass, x, y):
+ return tuple.__new__(klass, (x, y))
+
+ def __getattr__(self, attr):
+ if attr == 'x':
+ return self[0]
+ elif attr == 'y':
+ return self[1]
+ else:
+ raise AttributeError
+
+ def __neg__(self):
+ return Vec2D(-self.x, -self.y)
+
+ def __add__(self, other):
+ return Vec2D(self.x + other.x, self.y + other.y)
+
+ def __sub__(self, other):
+ return Vec2D(self.x - other.x, self.y - other.y)
+
+ def __mul__(self, other):
+ return Vec2D(self.x * other, self.y * other)
+
+ def __rmul__(self, other):
+ return Vec2D(self.x * other, self.y * other)
+
+
+class Death(Exception):
+ pass
+
+
+class WorldObject:
+ pass
+
+
+class Food(WorldObject):
+
+ def __init__(self, energy=0):
+ self.energy = energy
+
+ def __str__(self):
+ return ':3'
+
+
+class Cell:
+
+ def __init__(self, contents=None):
+ if contents and not issubclass(type(contents), WorldObject):
+ raise TypeError
+ else:
+ self.contents = contents
+
+ def is_empty(self):
+ return self.contents is None
+
+ def __setattr__(self, name, value):
+ if name == 'contents':
+ if value and not issubclass(type(value), WorldObject):
+ raise TypeError
+ else:
+ self.__dict__[name] = value
+
+ def __str__(self):
+ if self.is_empty():
+ return '..'
+ else:
+ return str(self.contents)
+
+
+class World:
+
+ def __init__(self, size):
+ self.size = size
+ self._world = []
+ for x in range(0, self.size):
+ self._world.append([])
+ for y in range(0, self.size):
+ self._world[x].append(Cell())
+
+ def __getitem__(self, key):
+ if key in range(0, self.size):
+ return self._world[key]
+ else:
+ raise IndexError
+
+ def __setitem__(self, key, value):
+ if key in range(0, self.size):
+ self._world[key] = value
+ else:
+ raise IndexError
+
+ def __len__(self):
+ return self.size
+
+ def __str__(self):
+ string = ''
+ for y in range(0, self.size):
+ for x in range(0, self.size):
+ string += str(self._world[x][y])
+ string += '\n'
+ return string
+
+
+class PythonPart(WorldObject):
+
+ def __str__(self):
+ return '##'
+
+
+class PythonHead(PythonPart):
+
+ def __str__(self):
+ return '@@'
+
+
+class Python:
+
+ LEFT = Vec2D(-1, 0)
+ RIGHT = Vec2D(1, 0)
+ UP = Vec2D(0, -1)
+ DOWN = Vec2D(0, 1)
+
+ def __init__(self, world, coords, size, direction):
+ self.world = world
+ self.head_pos = coords
+ self.part_pos = []
+ self.direction = direction
+ self.size = size
+ self.energy = 0
+
+ for part_index in range(1, size+1):
+ self.part_pos.append(self.head_pos + part_index*(-direction))
+ for part_pos in self.part_pos:
+ self.world[part_pos.x][part_pos.y].contents = PythonPart()
+ self.world[coords.x][coords.y].contents = PythonHead()
+
+ def move(self, direction):
+ new_head_pos = self.head_pos + direction
+
+ if new_head_pos.x < 0 or new_head_pos.x >= len(self.world):
+ raise Death
+
+ if new_head_pos.y < 0 or new_head_pos.y >= len(self.world):
+ raise Death
+
+ new_contents = self.world[new_head_pos.x][new_head_pos.y].contents
+
+ if issubclass(type(new_contents), PythonPart):
+ raise Death
+
+ if direction == -self.direction:
+ raise ValueError
+
+ last_part_pos = self.part_pos[self.size-1]
+
+ for part_index in range(self.size-1, 0, -1):
+ self.part_pos[part_index] = self.part_pos[part_index-1]
+ self.part_pos[0] = self.head_pos
+
+ if type(new_contents) == Food:
+ energy = new_contents.energy
+ self.energy += energy
+ self.part_pos.append(last_part_pos)
+ self.size += 1
+ else:
+ self.world[last_part_pos.x][last_part_pos.y].contents = None
+
+ self.world[self.head_pos.x][self.head_pos.y].contents = PythonPart()
+ self.world[new_head_pos.x][new_head_pos.y].contents = PythonHead()
+ self.head_pos = new_head_pos
Опита за вървене назад трябва да хвърля ValueError
Кода на 153-154 ред не прави ли точно това ?
Трябва да го преместиш преди Death