Решение на Питоните хапят! от Милан Миланов

Обратно към всички решения

Към профила на Милан Миланов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 13 успешни тест(а)
  • 0 неуспешни тест(а)

Код

from collections import deque
class World:
def __init__(self, width):
self.width = width
self.cells = [CellRow(self.width) for repeat in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
class Death(Exception):
pass
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
self.world = world
self.size = size
self.energy = 0
self.direction = direction
self._place_python_head(coords)
self._place_python_body(self.head_coords)
def move(self, direction):
if direction == -self.direction:
raise ValueError
self.direction = direction
new_coords = self.head_coords + direction
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
head_pos_x = self.head_coords.get_x()
head_pos_y = self.head_coords.get_y()
self.world[head_pos_x][head_pos_y].contents = PythonPart()
self.body.appendleft(self.head_coords)
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
self.size += 1
else:
if len(self.body):
last_part = self.body.pop()
last_x = last_part.get_x()
last_y = last_part.get_y()
self.world[last_x][last_y].contents = None
self._place_python_head(new_coords)
def _place_python_head(self, position):
self.head_coords = position
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = self.head
def _place_python_body(self, position):
self.body = deque()
for repeat in range(self.size):
position = position - self.direction
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
self.body.append(position)

Лог от изпълнението

.............
----------------------------------------------------------------------
Ran 13 tests in 0.034s

OK

История (7 версии и 1 коментар)

Милан обнови решението на 13.05.2013 16:33 (преди над 11 години)

+from collections import deque
+
+
+class World:
+
+ def __init__(self, width):
+ self.width = width
+ self.cells = [CellRow(self.width) for _ in range(self.width)]
+
+ def __getitem__(self, x):
+ World.check_index_validity(x, self.width)
+ return self.cells[x]
+
+ def __len__(self):
+ return self.width
+
+ @staticmethod
+ def check_index_validity(index, max_index):
+ if not 0 <= index < max_index:
+ raise IndexError
+
+
+class Cell:
+
+ def __init__(self, contents=None):
+ if contents is not None and not isinstance(contents, WorldObject):
+ raise TypeError
+ self.contents = contents
+
+ def is_empty(self):
+ return self.contents is None
+
+ def contents(self):
+ return self.contents
+
+
+class CellRow:
+
+ def __init__(self, width):
+ self.width = width
+ self.row = [Cell() for repeat in range(self.width)]
+
+ def __getitem__(self, y):
+ World.check_index_validity(y, self.width)
+ return self.row[y]
+
+ def __setitem__(self, index, item):
+ World.check_index_validity(index, self.width)
+ self.row[index] = item
+
+
+class Vec2D(tuple):
+
+ def __new__(cls, a, b):
+ return tuple.__new__(cls, (a, b))
+
+ def get_x(self):
+ return self[0]
+
+ def get_y(self):
+ return self[1]
+
+ def __add__(self, other):
+ return Vec2D(self.get_x() + other.get_x(),
+ self.get_y() + other.get_y())
+
+ def __sub__(self, other):
+ return Vec2D(self.get_x() - other.get_x(),
+ self.get_y() - other.get_y())
+
+ def __mul__(self, other):
+ return Vec2D(self.get_x() * other, self.get_y() * other)
+
+ def __neg__(self):
+ return Vec2D(-self.get_x(), -self.get_y())
+
+
+class WorldObject:
+ pass
+
+
+class Food(WorldObject):
+
+ def __init__(self, energy=0):
+ self.energy = energy
+
+
+class PythonPart(WorldObject):
+ pass
+
+
+class PythonHead(PythonPart):
+ pass
+
+
+class Python:
+
+ LEFT = Vec2D(0, -1)
+ RIGHT = Vec2D(0, 1)
+ UP = Vec2D(-1, 0)
+ DOWN = Vec2D(1, 0)
+
+ def __init__(self, world, coords, size, direction):
+ self.head = PythonHead()
+ self.head_coords = coords
+
+ self.world = world
+ self.world[coords.get_x()][coords.get_y()].contents = self.head
+
+ self.energy = 0
+ self.direction = direction
+
+ self.body = deque()
+ if size > 0:
+ self._place_python_body(size)
+
+ def move(self, direction):
+ if direction == -self.direction:
+ raise ValueError
+
+ new_coords = self.head_coords + direction
+
+ try:
+ new_position = self.world[new_coords.get_x()][new_coords.get_y()]
+ except IndexError:
+ raise Death
+
+ if isinstance(new_position.contents, PythonPart):
+ raise Death
+
+ self.direction = direction
+ self.world[self.head_coords.get_x()][
+ self.head_coords.get_y()].contents = PythonPart()
+ self.body.appendleft(self.head_coords)
+ self.head_coords = new_coords
+
+ if isinstance(new_position.contents, Food):
+ self.energy += new_position.contents.energy
+ else:
+ last_part = self.body.pop()
+ self.world[last_part.get_x()][last_part.get_y()] = Cell()
+
+ new_position.contents = self.head
+
+ def _place_python_body(self, size):
+ opposite_direction = -self.direction
+ position = self.head_coords
+
+ for repeat in range(size):
+ position = position + opposite_direction
+
+ pos_x = position.get_x()
+ pos_y = position.get_y()
+ self.world[pos_x][pos_y].contents = PythonPart()
+
+ self.body.append(position)
+
+
+class Death(Exception):
+ pass

Милан обнови решението на 13.05.2013 19:18 (преди над 11 години)

from collections import deque
class World:
def __init__(self, width):
self.width = width
self.cells = [CellRow(self.width) for _ in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
self.head_coords = coords
self.world = world
self.world[coords.get_x()][coords.get_y()].contents = self.head
+ self.size = size
self.energy = 0
self.direction = direction
self.body = deque()
- if size > 0:
- self._place_python_body(size)
+ if self.size > 0:
+ self._place_python_body()
def move(self, direction):
if direction == -self.direction:
raise ValueError
new_coords = self.head_coords + direction
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
self.direction = direction
self.world[self.head_coords.get_x()][
self.head_coords.get_y()].contents = PythonPart()
self.body.appendleft(self.head_coords)
self.head_coords = new_coords
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
+ self.size += 1
else:
last_part = self.body.pop()
self.world[last_part.get_x()][last_part.get_y()] = Cell()
new_position.contents = self.head
- def _place_python_body(self, size):
+ def _place_python_body(self):
opposite_direction = -self.direction
position = self.head_coords
- for repeat in range(size):
+ for repeat in range(self.size):
position = position + opposite_direction
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
self.body.append(position)
class Death(Exception):
pass

Милан обнови решението на 13.05.2013 19:20 (преди над 11 години)

from collections import deque
class World:
def __init__(self, width):
self.width = width
self.cells = [CellRow(self.width) for _ in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
self.head_coords = coords
self.world = world
self.world[coords.get_x()][coords.get_y()].contents = self.head
self.size = size
self.energy = 0
self.direction = direction
self.body = deque()
if self.size > 0:
self._place_python_body()
def move(self, direction):
if direction == -self.direction:
raise ValueError
new_coords = self.head_coords + direction
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
self.direction = direction
- self.world[self.head_coords.get_x()][
- self.head_coords.get_y()].contents = PythonPart()
+ head_pos_x = self.head_coords.get_x()
+ head_pos_y = self.head_coords.get_y()
+ self.world[head_pos_x][head_pos_y].contents = PythonPart()
+
self.body.appendleft(self.head_coords)
self.head_coords = new_coords
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
self.size += 1
else:
last_part = self.body.pop()
self.world[last_part.get_x()][last_part.get_y()] = Cell()
new_position.contents = self.head
def _place_python_body(self):
opposite_direction = -self.direction
position = self.head_coords
for repeat in range(self.size):
position = position + opposite_direction
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
self.body.append(position)
class Death(Exception):
pass

Милан обнови решението на 14.05.2013 00:10 (преди над 11 години)

from collections import deque
class World:
def __init__(self, width):
self.width = width
- self.cells = [CellRow(self.width) for _ in range(self.width)]
+ self.cells = [CellRow(self.width) for repeat in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
self.head_coords = coords
-
self.world = world
self.world[coords.get_x()][coords.get_y()].contents = self.head
-
self.size = size
self.energy = 0
self.direction = direction
-
self.body = deque()
+
if self.size > 0:
self._place_python_body()
def move(self, direction):
if direction == -self.direction:
raise ValueError
new_coords = self.head_coords + direction
-
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
self.direction = direction
head_pos_x = self.head_coords.get_x()
head_pos_y = self.head_coords.get_y()
self.world[head_pos_x][head_pos_y].contents = PythonPart()
-
self.body.appendleft(self.head_coords)
self.head_coords = new_coords
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
self.size += 1
else:
last_part = self.body.pop()
self.world[last_part.get_x()][last_part.get_y()] = Cell()
new_position.contents = self.head
def _place_python_body(self):
opposite_direction = -self.direction
position = self.head_coords
for repeat in range(self.size):
position = position + opposite_direction
-
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
-
self.body.append(position)
class Death(Exception):
pass

Милан обнови решението на 15.05.2013 00:30 (преди над 11 години)

from collections import deque
class World:
def __init__(self, width):
self.width = width
self.cells = [CellRow(self.width) for repeat in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
+class Death(Exception):
+ pass
+
+
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
self.head_coords = coords
self.world = world
- self.world[coords.get_x()][coords.get_y()].contents = self.head
self.size = size
self.energy = 0
self.direction = direction
- self.body = deque()
- if self.size > 0:
- self._place_python_body()
+ self._place_python_head(self.head_coords)
+ self._place_python_body(self.head_coords)
def move(self, direction):
if direction == -self.direction:
raise ValueError
+ self.direction = direction
+
new_coords = self.head_coords + direction
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
- self.direction = direction
head_pos_x = self.head_coords.get_x()
head_pos_y = self.head_coords.get_y()
self.world[head_pos_x][head_pos_y].contents = PythonPart()
self.body.appendleft(self.head_coords)
self.head_coords = new_coords
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
self.size += 1
else:
- last_part = self.body.pop()
- self.world[last_part.get_x()][last_part.get_y()] = Cell()
+ if len(self.body):
+ last_part = self.body.pop()
+ last_x = last_part.get_x()
+ last_y = last_part.get_y()
+ self.world[last_x][last_y].contents = None
- new_position.contents = self.head
+ self._place_python_head(new_coords)
- def _place_python_body(self):
- opposite_direction = -self.direction
- position = self.head_coords
+ def _place_python_head(self, position):
+ pos_x = position.get_x()
+ pos_y = position.get_y()
+ self.world[pos_x][pos_y].contents = self.head
+ def _place_python_body(self, position):
+ self.body = deque()
+
for repeat in range(self.size):
- position = position + opposite_direction
+ position = position - self.direction
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
self.body.append(position)
-
-
-class Death(Exception):
- pass

Милан обнови решението на 15.05.2013 00:32 (преди над 11 години)

from collections import deque
class World:
def __init__(self, width):
self.width = width
self.cells = [CellRow(self.width) for repeat in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
class Death(Exception):
pass
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
self.head_coords = coords
self.world = world
self.size = size
self.energy = 0
self.direction = direction
self._place_python_head(self.head_coords)
self._place_python_body(self.head_coords)
def move(self, direction):
if direction == -self.direction:
raise ValueError
- self.direction = direction
-
+ self.direction = direction
new_coords = self.head_coords + direction
+
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
head_pos_x = self.head_coords.get_x()
head_pos_y = self.head_coords.get_y()
self.world[head_pos_x][head_pos_y].contents = PythonPart()
self.body.appendleft(self.head_coords)
self.head_coords = new_coords
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
self.size += 1
else:
if len(self.body):
last_part = self.body.pop()
last_x = last_part.get_x()
last_y = last_part.get_y()
self.world[last_x][last_y].contents = None
self._place_python_head(new_coords)
def _place_python_head(self, position):
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = self.head
def _place_python_body(self, position):
self.body = deque()
for repeat in range(self.size):
position = position - self.direction
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
self.body.append(position)

Милан обнови решението на 15.05.2013 00:37 (преди над 11 години)

from collections import deque
class World:
def __init__(self, width):
self.width = width
self.cells = [CellRow(self.width) for repeat in range(self.width)]
def __getitem__(self, x):
World.check_index_validity(x, self.width)
return self.cells[x]
def __len__(self):
return self.width
@staticmethod
def check_index_validity(index, max_index):
if not 0 <= index < max_index:
raise IndexError
class Cell:
def __init__(self, contents=None):
if contents is not None and not isinstance(contents, WorldObject):
raise TypeError
self.contents = contents
def is_empty(self):
return self.contents is None
def contents(self):
return self.contents
class CellRow:
def __init__(self, width):
self.width = width
self.row = [Cell() for repeat in range(self.width)]
def __getitem__(self, y):
World.check_index_validity(y, self.width)
return self.row[y]
def __setitem__(self, index, item):
World.check_index_validity(index, self.width)
self.row[index] = item
class Vec2D(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
def get_x(self):
return self[0]
def get_y(self):
return self[1]
def __add__(self, other):
return Vec2D(self.get_x() + other.get_x(),
self.get_y() + other.get_y())
def __sub__(self, other):
return Vec2D(self.get_x() - other.get_x(),
self.get_y() - other.get_y())
def __mul__(self, other):
return Vec2D(self.get_x() * other, self.get_y() * other)
def __neg__(self):
return Vec2D(-self.get_x(), -self.get_y())
class WorldObject:
pass
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
class PythonPart(WorldObject):
pass
class PythonHead(PythonPart):
pass
class Death(Exception):
pass
class Python:
LEFT = Vec2D(0, -1)
RIGHT = Vec2D(0, 1)
UP = Vec2D(-1, 0)
DOWN = Vec2D(1, 0)
def __init__(self, world, coords, size, direction):
self.head = PythonHead()
- self.head_coords = coords
self.world = world
self.size = size
self.energy = 0
self.direction = direction
- self._place_python_head(self.head_coords)
+ self._place_python_head(coords)
self._place_python_body(self.head_coords)
def move(self, direction):
if direction == -self.direction:
raise ValueError
self.direction = direction
new_coords = self.head_coords + direction
try:
new_position = self.world[new_coords.get_x()][new_coords.get_y()]
except IndexError:
raise Death
if isinstance(new_position.contents, PythonPart):
raise Death
head_pos_x = self.head_coords.get_x()
head_pos_y = self.head_coords.get_y()
self.world[head_pos_x][head_pos_y].contents = PythonPart()
self.body.appendleft(self.head_coords)
- self.head_coords = new_coords
if isinstance(new_position.contents, Food):
self.energy += new_position.contents.energy
self.size += 1
else:
if len(self.body):
last_part = self.body.pop()
last_x = last_part.get_x()
last_y = last_part.get_y()
self.world[last_x][last_y].contents = None
self._place_python_head(new_coords)
def _place_python_head(self, position):
+ self.head_coords = position
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = self.head
def _place_python_body(self, position):
self.body = deque()
for repeat in range(self.size):
position = position - self.direction
pos_x = position.get_x()
pos_y = position.get_y()
self.world[pos_x][pos_y].contents = PythonPart()
self.body.append(position)