Source code for Road

# -*- coding: UTF-8 -*-
from Door import Door
from Tile import Tile
import copy, uuid

[docs]class Road(object): """ Road from door to door. Once instantiated, it is filled with Tile. """ def __init__(self, from_door, to_door): self.id = str(uuid.uuid4()) self.tiles = [] self.from_door = Door(from_door.x, from_door.y, from_door.direction) self.to_door = Door(to_door.x, to_door.y, to_door.direction) self._fill_road(from_door, to_door)
[docs] def get_tiles(self): """Get all tiles from Road. :rtype: List of Tile . :return: Return tiles. if it does not exist, return empty list. """ return self.tiles
[docs] def get_tile(self, x, y): """Get a tile from Road. :param x: potision x. :param y: potision y. :rtype: Tile class. :return: Return tile. if it does not exist, return None. """ for tile in self.tiles: if tile.x == x and tile.y == y: return tile else: return None
[docs] def set_tile(self, x, y, new_tile): """Set a tile to Road. :param x: potision x. :param y: potision y. :param new_tile: new Tile """ for index, tile in enumerate(self.tiles): if tile.x == x and tile.y == y: self.tiles[index] = new_tile
[docs] def may_have_tile(self, x, y): """Whether there is a possibility of holding the tile. :param x: potision x. :param y: potision y. :rtype: Booean :return: Return True, if there is a possibility. Otherwise Fasle. """ if (self.x <= x and x <= self.ax) and \ (self.y <= y and y <= self.ay): return True else: return False
def _fill_road(self, from_door, to_door): # 計算しやすいように、小さい座標の順から大きい座標の場所へ向かうようにする # 道が縦向きならY座標を基準に、横向きならX座標を基準にして判定する if from_door.is_vertical(): if from_door.y < to_door.y: self._set_inline_range(from_door, to_door, 0, 1) self._pave_road(from_door, to_door, 0, 1) else: self._set_inline_range(to_door, from_door, 0, 1) self._pave_road(to_door, from_door, 0, 1) else: if from_door.x < to_door.x: self._set_inline_range(from_door, to_door, 1, 0) self._pave_road(from_door, to_door, 1, 0) else: self._set_inline_range(to_door, from_door, 1, 0) self._pave_road(to_door, from_door, 1, 0) def _set_inline_range(self, from_door, to_door, col_add, row_add): #ドアを含まない道になりうる領域を四角形とみなして保持する x = from_door.x + col_add y = from_door.y + row_add ax = to_door.x - col_add ay = to_door.y - row_add if x < ax: self.x = x self.ax = ax else: self.x = ax self.ax = x if y < ay: self.y = y self.ay = ay else: self.y = ay self.ay = y def _pave_road(self, from_door, to_door, col_add, row_add): # ドアからドアまでの道を作る ax = from_door.x + col_add ay = from_door.y + row_add next1 = Tile(ax, ay, Tile.WAY) self.tiles.append(next1) if self._pave_middle_polyline(ax, ay, to_door.x, to_door.y, col_add): return bx = to_door.x - col_add by = to_door.y - row_add next2 = Tile(bx, by, Tile.WAY) self.tiles.append(next2) if self._pave_middle_polyline(ax, ay, bx, by, col_add): return # 道が埋まるまで再帰的に繰り返す self._pave_road(next1, next2, col_add, row_add) def _pave_middle_polyline(self, ax, ay, bx, by, vertical): #縦方向の道は横がそろうまで伸ばす if vertical == 0: # 同じY位置まできたらX側を埋める if ay == by: if ax < bx: start = ax end = bx else: start = bx end = ax for x in range(start, end): road = Tile(x, ay, Tile.WAY) self.tiles.append(road) return True #横方向の道は横がそろうまで伸ばす else: # 同じX位置にきたらY側を埋める if ax == bx: if ay < by: start = ay end = by else: start = by end = ay for y in range(start, end): road = Tile(ax, y, Tile.WAY) self.tiles.append(road) return True return False