Ejemplo n.º 1
0
class SpringdroidInterface:
	def __init__(self, file_str):
		self.computer = IntcodeComputer(file_str, echo=False)

	def run(self):
		# Easier instructions to assemble
		not1j = 'NOT A J'
		not2j = 'NOT B J'
		not3j = 'NOT C J'
		not4j = 'NOT D J'
		andtj = 'AND T J'
		walk = 'WALK\n'

		# Example: jump if a thre-tile-wide hole is detected
		# NOT A J - NOT 1 J
		# NOT B T - NOT 2 T
		# AND T J - AND T J
		# NOT C T - NOT 3 T
		# AND T J - AND T J
		# AND D J - AND 4 J

		# GOAL: (!C && D) || A

		# Translate instructions into ASCII
		instructions = ['NOT C J', 'AND D J', 'NOT A T', 'OR T J']
		instructions.append(walk)
		input_str = '\n'.join([step for step in instructions])
		print(input_str)
		
		# Input instructions and run computer
		# Print output
		self.computer.read_ascii(input_str)
		output = self.computer.get_output()
		# output = ''.join([chr(char) for char in self.computer.get_output()[:-1]])

		print(''.join([chr(char) for char in self.computer.get_output()[:-1]]))
		print(output[-1])
Ejemplo n.º 2
0
class SpringdroidInterface:
	def __init__(self, file_str):
		self.computer = IntcodeComputer(file_str, echo=False)

	def run(self):
		walk = 'WALK\n'
		run = 'RUN\n'

		# Example: jump if a thre-tile-wide hole is detected
		# NOT A J
		# NOT B T
		# AND T J
		# NOT C T
		# AND T J
		# AND D J

		# GOAL: (!C && D & (E || H)) || A || (!B && !E)

		# Translate instructions into ASCII
		instructions = ['NOT C J', 'AND D J', 'NOT H T', 'NOT T T', 'OR E T', 'AND T J', 'NOT A T', 'OR T J', 'NOT B T', 'NOT T T', 'OR E T', 'NOT T T', 'OR T J']
		instructions.append(run)
		input_str = '\n'.join([step for step in instructions])
		print(input_str)
		
		# Input instructions and run computer
		# Print output
		self.computer.read_ascii(input_str)
		output = self.computer.get_output()
		# output = ''.join([chr(char) for char in self.computer.get_output()[:-1]])

		for char in output:
			if char > 255:
				break
			print(chr(char), end='')
		print('\n', end='')
		print(output[-1])
Ejemplo n.º 3
0
class RescueBot:
	def __init__(self, file_str):
		self.computer = IntcodeComputer(file_str, echo=False)
		self.running = False

		self.rooms = {}		# name(str): room(Room)
		self.items = {}		# name(str): room(Room)
		self.directions = []		# e.g. ['north', 'west', 'west', 'south']

		self.cur_room = None
		self.last_room = None
		self.last_dir = None

	def run(self):
		self.running = True
		self.computer.run()
		while self.running:
			output = self.computer.get_output()
			output = ''.join([chr(char) for char in output])
			# print(output)

			# Find/Create Room
			self.last_room = self.cur_room
			room_name = self.get_name_from_output(output)
			if re.search('You can\'t go that way.', output):
				print(output)
			elif room_name in self.rooms:
				self.cur_room = self.rooms[room_name]
			else:
				self.cur_room = self.get_room_from_output(output)
				self.rooms[room_name] = self.cur_room

				print('New Room:')
				self.cur_room.print()
				# print(self.cur_room.text)

			# Link the rooms if they are not already
			if self.last_room and self.last_room is not self.cur_room:
				print('Linking: %s and %s' % (self.cur_room.name, self.last_room.name))
				if self.last_room.edges[self.last_dir] is None:
					self.last_room.edges[self.last_dir] = self.cur_room.name

				if self.last_dir == 'north':
					inv_last_dir = 'south'
				elif self.last_dir == 'south':
					inv_last_dir = 'north'
				elif self.last_dir == 'east':
					inv_last_dir = 'west'
				elif self.last_dir == 'west':
					inv_last_dir = 'east'
				if inv_last_dir in self.cur_room.edges and self.cur_room.edges[inv_last_dir] is None:
					self.cur_room.edges[inv_last_dir] = self.last_room.name

				# self.cur_room.print()
				# self.last_room.print()

			print(output)
			command = self.get_command()
			print('####################')
			print('Current Room: %s' % self.cur_room.name)
			print('Command: %s' % command)
			print('####################')

			if command in ('north', 'south', 'east', 'west'):
				self.last_dir = command

			if command is None:
				self.running = False
				break

			ascii_command = [ord(char) for char in command]
			ascii_command.append(ord('\n'))
			self.computer.read_input(ascii_command)

	def get_command(self):
		if self.directions:
			return self.directions.pop(0)
		elif self.cur_room.has_unknown_edge():
			for dir, name in self.cur_room.edges.items():
				if name is None:
					return dir
			print('Unknown Edge not found')
		else:
			dest = self.find_nearest_unexplored()
			self.directions = self.get_directions_to_room(self.cur_room.name, dest)

			if self.directions is not None:
				return self.directions.pop(0)
			else:
				print('Directions not found')
				self.running = False
				return None

	def find_nearest_unexplored(self):
		for name, room in self.rooms.items():
			print(name)
			for dir, edge in room.edges.items():
				if edge is None:
					return name
		return None

	def get_directions_to_room(self, start_room, stop_room):
		if start_room not in self.rooms:
			print('Error: "%s" not in rooms to path.' % start_room)
			return None
		if stop_room not in self.rooms:
			print('Error: "%s" not in rooms to path.' % stop_room)
			return None

		print('Finding directions from %s to %s' % (start_room, stop_room))

		parents = {start_room: None}
		distances = {start_room: 0}
		node_list = [start_room]

		while len(node_list) > 0:
			node_name = node_list.pop(0)
			if node_name == stop_room:
				break

			node_room = self.rooms[node_name]
			node_edges = node_room.edges
			node_dist = distances[node_name]

			for dir, edge in node_edges.items():
				if edge is not None and edge not in parents:
					parents[edge] = (node_name, dir)
					distances[edge] = node_dist + 1
					node_list.append(edge)

		directions = []
		path_par = parents[stop_room]
		while path_par is not None:
			directions.insert(0, path_par[1])
			path_par = parents[path_par[0]]

		return directions

	def get_name_from_output(self, output):
		# Room Name
		name_match = re.search('== ([a-zA-Z ]+) ==', output)
		if name_match:
			name = name_match.group(1)
			# print('Room Name: %s' % name)
			return name
		else:
			# print('Error: Name not found')
			# print(output)
			return None

	def get_room_from_output(self, output):
		new_room = Room()
		new_room.text = output

		# Room Name
		name_match = re.search('== ([a-zA-Z ]+) ==', output)
		if name_match:
			name = name_match.group(1)
			new_room.name = name
			# print('Room Name: %s' % name)

		# Adding edge rooms
		dir_match = re.search('Doors here lead:\n(- north)?\n?(- east)?\n?(- south)?\n?(- west)?', output)
		if dir_match:
			if dir_match.group(1):
				# print('north found')
				new_room.edges['north'] = None

			if dir_match.group(3):
				# print('south found')
				new_room.edges['south'] = None

			if dir_match.group(2):
				# print('east found')
				new_room.edges['east'] = None

			if dir_match.group(4):
				# print('west found')
				new_room.edges['west'] = None

		return new_room

		# Handling Items
		# item_str_match = re.search('Items here:\n', output)
		# if item_str_match:
		# 	before, keyword, items = output.partition('Items here:\n')
		# 	items_match = re.findall('- [a-z ]+', items)
		# 	# print(items_match)
		# 	new_room.items = items_match

		# 	for item in items_match:
		# 		self.items[item[2:]] = pos

	def find_room_by_name(self, name):
		for room in self.rooms:
			if room.name == name:
				return room

		return None

	def find_closest_unexplored_room(self):
		min_dist = -1
		closest = None

		for pos in self.unexplored:
			pos_x, pos_y = pos
			dist = abs(self.x - pos_x) + abs(self.y - pos_y)

			if not closest or dist < min_dist:
				closest = pos
				min_dist = dist

		return closest