/src/mine.py
Python | 186 lines | 145 code | 26 blank | 15 comment | 48 complexity | 80e6cfe6b84b1306e6ce79690cd45283 MD5 | raw file
- # coding=utf-8
- import sys
- import copy
- from cell import *
- # cell objects
- EMPTY_CELL = EmptyCell()
- WALL_CELL = WallCell()
- ROCK_CELL = RockCell()
- EARTH_CELL = EarthCell()
- GOLD_CELL = GoldCell()
- ROBOT_CELL = RobotCell()
- def decode_cell(c):
- if c == 'R':
- return ROBOT_CELL
- if c == '@':
- return WALL_CELL # really it's a higher order lambda
- if c == 'W':
- return WALL_CELL # really it's a Wadler's Beard
- if c == '#':
- return WALL_CELL
- if c == '*':
- return ROCK_CELL
- if c == '.':
- return EARTH_CELL
- if c == '!':
- return EARTH_CELL # really it's a Hutton's Razor
- if c == '\\':
- return GOLD_CELL
- if c == 'O':
- return LiftCell(True)
- if c == 'L':
- return LiftCell(False)
- if c in "ABCDEFGHI":
- return TeleportCell(c)
- if c in "123456789":
- return TargetCell(c)
- return EMPTY_CELL
- class Mine:
- def __init__(self):
- self.rows = []
- self.height = 0
- self.width = 0
- self.water = 0
- self.flooding = 0
- self.waterproof = 10
- self.robot_position = None
- self.gold = 0
- self.teleports = {}
- def clone(self):
- return copy.deepcopy(self)
-
- def update(self, otherMine):
- self.rows = otherMine.rows
-
- def xy_to_rc(self, xy):
- return (self.height - xy[1], xy[0] - 1)
-
- def rc_to_xy(self, rc):
- return (rc[1] + 1, self.height - rc[0])
-
- def __getitem__(self, xy):
- return self.at(xy)
-
- def __setitem__(self, xy, value):
- (r, c) = self.xy_to_rc(xy)
- if r < 0 or r >= self.height or c < 0 or c >= self.width:
- raise Exception("Invalid coordinates")
- self.rows[r][c] = value
-
- def at(self, xy):
- (r, c) = self.xy_to_rc(xy)
-
- if r < 0 or r >= self.height or c < 0 or c >= self.width:
- return WALL_CELL
- if c >= len(self.rows[r]):
- return EMPTY_CELL
- return self.rows[r][c]
-
- def dump(self):
- from cStringIO import StringIO
- file_str = StringIO()
-
- for row in self.rows:
- for cell in row:
- file_str.write(cell.show())
- file_str.write("\n")
- file_str.write("\n")
-
- if self.water > 0 or self.flooding > 0 or self.waterproof != 10:
- file_str.write("Water %d\n" % self.water)
- file_str.write("Flooding %d\n" % self.flooding)
- file_str.write("Waterproof %d\n" % self.waterproof)
-
- if self.teleports:
- for ts in self.teleports.keys():
- file_str.write("Trampoline %(s)s targets %(t)s\n" % \
- {"s" : ts, "t" : self.teleports[ts]})
- return file_str.getvalue()
-
- def update_positions(self, teleports):
- sources = {}
- targets = {}
-
- x = 1
- y = self.height
- for row in self.rows:
- for cell in row:
- cell_type = cell.type()
- if cell_type == Cell.GOLD:
- self.gold += 1
- elif cell_type == Cell.ROBOT:
- self.robot_position = (x, y)
- elif cell_type == Cell.TELEPORT:
- cell.position = (x, y)
- sources[cell.label] = cell
- elif cell_type == Cell.TARGET:
- cell.position = (x, y)
- targets[cell.label] = cell
- x += 1
- x = 1
- y = y - 1
-
- for tp in teleports.keys():
- source = sources[tp]
- target = targets[teleports[tp]]
- source.set_target(target)
- target.add_source(source)
-
- def parse(self, lines):
- teleports = {}
- reading_mine = True
- for line in lines:
- line = line.rstrip()
- if reading_mine:
- if line != "":
- self.rows.append([decode_cell(c) for c in line])
- self.height = self.height + 1
- columns = len(line)
- if columns > self.width:
- self.width = columns
- else:
- reading_mine = False
- else:
- if line == "":
- continue
- words = line.split()
- if words[0] == "Water":
- self.water = int(words[1])
- elif words[0] == "Flooding":
- self.flooding = int(words[1])
- elif words[0] == "Waterproof":
- self.waterproof = int(words[1])
- elif words[0] == "Trampoline":
- teleports[words[1]] = words[3]
-
- self.update_positions(teleports)
- self.teleports = teleports
- print(self.teleports)
-
- if __name__ == "__main__":
- import fileinput
- mine = Mine()
- mine.parse(fileinput.input())
-
- print(mine.dump())
-
- #~ for y in range(1, mine.height + 1):
- #~ for x in range(1, mine.width + 1):
- #~ sys.stdout.write(mine[x, mine.height + 1 - y].show())
- #~ sys.stdout.write('\n')
- #~
- #~ if mine.has_teleports():
- #~ for t in mine.teleports.viewvalues():
- #~ print("teleport " + t.label + " to " + t.target.label)
- #~
- #~ print(mine.lifts.keys())
- #~ print(mine.golds.keys())
- #~ print(mine.rocks.keys())
- #~ print(mine.robot_position)