Мартина обнови решението на 15.05.2013 15:56 (преди над 11 години)
+class Vec2D:
+ def __init__(self, x, y):
+ self.x, self.y = x, 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 __neg__(self):
+ return Vec2D(-self.x, -self.y)
+
+ def __mul__(self, scalar):
+ if not isinstance(scalar, Vec2D):
+ return Vec2D(self.x*scalar, self.y*scalar)
+
+ def __eq__(self, other):
+ return self.x == other.x and self.y == other.y
+
+ def __ne__(self, other):
+ return self.x != other.x or self.y != other.y
+
+ def __iter__(self):
+ for i in [self.x, self.y]:
+ yield i
+
+
+class Death(Exception):
+ pass
+
+
+class World:
+ def __init__(self, width):
+ self.width = width
+ self.board = [[Cell(None) for x in range(width)] for y in range(width)]
+
+ def __getitem__(self, coord):
+ if coord < 0 or coord >= self.width:
+ raise IndexError("Invalid Index")
+ else:
+ return self.board[coord]
+
+ def __len__(self):
+ return self.width
+
+
+class Cell:
+ def __init__(self, contents=None):
+ if contents and not isinstance(contents, WorldObject):
+ raise TypeError("Invalid error")
+ else:
+ self.contents = contents
+
+ def contents(self):
+ return self.contents
+
+ def is_empty(self):
+ if self.contents is None:
+ return True
+ else:
+ return False
+
+
+class WorldObject:
+ pass
+
+
+class Food(WorldObject):
+
+ def __init__(self, energy=0):
+ self.energy = energy
+
+
+class PythonPart(WorldObject):
+ def __init__(self, coords):
+ self.coords = coords
+
+
+class PythonHead(PythonPart):
+ def __init__(self, coords):
+ self.coords = coords
+
+
+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.energy = 0
+ self.size = size
+ self.direction = direction
+
+ self.python_head = PythonHead(coords)
+ self.world[coords.x][coords.y] = Cell(self.python_head)
+ self.python_body = [self.python_head]
+ for i in range(1, size+1):
+ position = coords-direction*i
+ if position.x < len(world) or position.y < len(world):
+ part = PythonPart(position)
+ self.world[position.x][position.y] = Cell(part)
+ self.python_body.append(part)
+
+ self.python_body.reverse()
+
+ def move(self, direction):
+ old_coords = self.python_head.coords
+ new_position = old_coords + direction
+ if self._out_of_world(new_position):
+ raise Death
+
+ new_cell = self.world[new_position.x][new_position.y]
+ cell_contents = new_cell.contents
+
+ if cell_contents and isinstance(cell_contents, PythonPart):
+ raise Death
+ elif self._move_back(new_position):
+ raise ValueError("Move back!")
+ else:
+ old_x, old_y = old_coords
+ self.world[old_x][old_y] = Cell(PythonPart(old_coords))
+ self.python_head = PythonHead(new_position)
+ head_x, head_y = new_position
+ self.world[head_x][head_y] = Cell(self.python_head)
+ self.python_body.append(self.python_head)
+ self.direction = direction
+
+ if cell_contents and isinstance(cell_contents, Food):
+ food = cell_contents
+ self.energy = self.energy + food.energy
+ else:
+ remove_part = self.python_body.pop(0)
+ x, y = remove_part.coords
+ self.world[x][y] = Cell()
+
+ def _out_of_world(self, position):
+ if position.x > len(self.world) or position.y > len(self.world)\
+ or position.x < 0 or position.y < 0:
+ return True
+ else:
+ return False
+
+ def _move_back(self, direction):
+ vector = self.direction + direction
+ if vector == Vec2D(0, 0):
+ return True
+ else:
+ return False