All pastes #810420 Raw Edit

robertj

public text v1 · immutable
·published 2007-12-09 22:25 UTC
rendered paste body
from random import choiceimport pickleimport heapqfrom collections import defaultdictimport refrom time import time, sleepdef __init__(self):	self.write("Addon Loaded.")	reloadHooks(self)	self.world = world()	self.fighting = False	self.health_percent = .8	self.thinking = False	self.last_combat = 10	self.last_consider = 10	self.last_stats = 10	self.last_move = 10	self.buffer = ""	self.room = False	self.cooldowns = {}	self.action_queue = []def reloadHooks(self):	# do most of the work here on the fly so you don't have to keep reloading the plugin	#	#if not hasattr(self, "world"):	#	self.world = world()	passdef cooldown(self, cmd, duration):	if self.cooldowns.has_key(cmd):		if time() - self.cooldowns[cmd] > duration:			return True		else:			return False	else:		return Truedef popCooldown(self, cmd, duration):	if cooldown(self, cmd, duration):		self.cooldowns[cmd] = time()		self.send(cmd)class PathFind(object):    def __init__(self):        self.G = defaultdict(dict)        self.E = defaultdict(dict)    def addEdge(self, va, vb, cost, edge, way):        if way == -1: (vb, va) = (va, vb)        self.G [va][vb] = edge        if not way: self.G[vb][va] = edge        self.E[edge] = cost    def findPath(self, start, end):       def flatten(L):       # Flatten linked list of form [0,[1,[2,[]]]]         while len(L) > 0:           yield L[0]           L = L[1]       q = [(0, start, ())]  # Heap of (cost, path_head, path_rest).       visited = set()       # Visited vertices.       # Eliminate the dots pattern       push, pop, add = heapq.heappush, heapq.heappop, visited.add       G, E = self.G, self.E       while True:          (cost, v1, path) = pop(q)          if v1 not in visited:             add(v1)             path = (v1, path)             if v1 == end: return list(flatten(path))[::-1]             for (v2, e) in G[v1].iteritems():                 if v2 not in visited:                   push(q, (cost + E[e], v2, path))    def getEdges(self, path):        edges = []        for ix in xrange(len(path) - 1):            edges.append(self.G[path[ix]][path[ix + 1]])        return edgesdef findPath(rooms, x, y):	g = getPathFindFromRooms(rooms)	try:		return g.findPath(x, y)	except:		return Nonedef getEdges(rooms, x, y):	g = getPathFindFromRooms(rooms)		try:		h = g.findPath(x, y)		return g.getEdges(h)	except:		return Nonedef getPathFindFromRooms(rooms):	x = PathFind()	for rid in rooms:	    for d in rooms[rid].doors:		if d.destination is not False and d.closed is False:		    print "adding ", rooms[rid].name, " - ",  d.destination.name		    x.addEdge(rooms[rid], d.destination, 1, d, 1)	return xclass door:	def __init__(self, name, destination=False):		self.name = name		self.explored = False		# all doors start opened		# and we close them when we go through		# and reopen when we map the exit on the other side		self.closed = False		self.destination = destinationclass room:	def __init__(self, name):		self.name = name		self.doors = []		self.stuff = []		self.seen = 1class thing:	def __init__(self, name):		self.name = name		self.seen = 1		self.considered = False		self.danger = Falseclass world:	def __init__(self):		self.rooms = {}		self.bookmarks = {}def tick(self):	if self.fighting:		if time() - self.last_combat > 2:			self.write("------------------------Leaving battle.")			self.fighting = False	else:		if self.thinking:			if time () - self.last_stats > 2:				if self.health_percent < 1:					self.last_stats = time()					self.c.send("hp\n")	if self.thinking:		self.write("ACTION QUEUE: " + str(len(self.action_queue)) + " items.")		for fun, fargs in self.action_queue:			self.write(" * " + fun.__name__)		# if we have queued actiosn do them		if len(self.action_queue) > 0:			fun, fargs = self.action_queue.pop()			self.write("FARGS ARE " + str(fargs))			fun(self, *fargs)			self.write('sleeping')			sleep(5)		handleWalkAndKill(self)		# change below to False to stop after every thought		#self.thinking = False		for fun, fargs in self.action_queue:			tfargs = []			for x in fargs: tfargs.append(str(x.name))			self.write(fun.__name__ + " - " + ", ".join(tfargs))def handleWalkAndKill(self):	if not self.fighting:		if self.health_percent > .95:			if time() - self.last_move > .5:				cmdExplore(self)			else:				#self.write("CONSDIERING IN ROMM WITH " + str(len(self.room.stuff)))				if time() - self.last_consider > 2:					need_check = False					for x in self.room.stuff:						if not x.considered:							need_check = True					if need_check:						pass						#self.send("consider")					self.last_consider = time()					self.last_combat = time() + 1def serverText(self, txt):	self.buffer += txt	if self.buffer.endswith("\n> "):		handleServerChunk(self, self.buffer[:-3])		self.buffer = ""	handleStats(self, txt)	handleInCombatCheck(self, txt)	handleBadMoveCheck(self, txt)def handleServerChunk(self, txt):		#self.write("-------LOGGING --------")		#self.write(txt)		#f = open("/tmp/output.txt", "w")		#f.write(txt)		#f.close()		#self.write("---------------")		handleroomDesc(self, txt)		handleConsider(self, txt)def handleBadMoveCheck(self, txt):	x = re.compile(r"You cannot go (\S+).", re.MULTILINE)	for l in txt.splitlines():		r = x.match(l)		if r:			self.write("Bad move detected going " + r.group(1) + ", stopping thining.")			self.thinking = Falsedef handleStats(self, txt):	x = re.compile(r"\s+HP:\s+(\d+)/(\d+)", re.MULTILINE)	for l in txt.splitlines():		r = x.match(l)		if r:			self.health_percent = float(r.group(1)) / int(r.group(2))			if self.health_percent < 1:				if  popCooldown(self, "eat berry", 45) or popCooldown(self, "salve", 1.5):					pass			self.write("health percent " + str(self.health_percent))			self.last_stats = time()			def handleInCombatCheck(self, txt):	x = re.compile(r".*Attacking:.*", re.MULTILINE)	for l in txt.splitlines():		r = x.match(l)		if r:			self.last_combat = time()			self.last_move = time()			self.fighting = Truedef handleConsider(self, txt):	if self.fighting or not self.room:		return	needle = "consider "	if self.last_command == "consider":		t = self.last_command[len(needle):]	dangerous = 0	lines = txt.splitlines()	needle = "You size up "	for i in range(len(lines)):		if lines[i].startswith(needle):			mob_name = lines[i][len(needle):-1]			desc = lines[i+1].strip()			danger_dict = {}			danger_dict["You are a little stronger than they are."] = 4			danger_dict["Closest thing to a fair fight you've seen in a while."] = 5			danger_dict["This opponent may be a little tougher than you are."] = 6			if danger_dict.has_key(desc):				danger = danger_dict[desc]			else:				danger = 10			self.write("danger is " + str(danger))			# find stuff with the same mob_name			for x in self.room.stuff:				self.write(x.name + " VS " + mob_name)				if x.name.startswith(mob_name):					x.danger = danger					self.write("assigning danger to " + mob_name)			if self.health_percent > .9 and danger < 7:				#self.send("kill "+mob_name)				break	for x in self.room.stuff:		x.considered = True		def explore_door(door):	pass	#self.send(door.name)	# need to hook into future reads to confirm and then nav back to checkdef playerText(self, txt):	passdef cmdNewDoor(self, targs):	if targs:		d = door(targs)		self.room.doors.append(d)	else:		self.write("What is the exit name that leaves from this room?")def cmdCloseDoor(self, targs):	if targs:		for d in self.room.doors:			if d.name == targs:				self.write("closed door")				d.closed = True		self.room.doors.append(d)	else:		self.write("What door are you closing?")		rooms = self.world.rooms		for rid in rooms:			for door in rooms[rid].doors:				if not door.closed:					self.write(rooms[rid].name + " - " + door.name)def cmdOpenDoor(self, targs):	if targs:		for d in self.room.doors:			if d.name == targs:				self.write("opened door")				d.closed = False		self.room.doors.append(d)	else:		self.write("What door are you opening?")		rooms = self.world.rooms		for rid in rooms:			for door in rooms[rid].doors:				if door.closed:					self.write(rooms[rid].name + " - " + door.name)def cmdStuff(self):	self.write("stuff in " + self.room.name + ":")	for x in self.room.stuff:		self.write(x.name + " - " + str(x.danger))def cmdOpenDoor(self, targs):	if targs:		for d in self.room.doors:			if d.name == targs:				self.write("opened door")				d.closed = False		self.room.doors.append(d)	else:		self.write("What door are you opening?")		rooms = self.world.rooms		for rid in rooms:			for door in rooms[rid].doors:				if door.closed:					self.write(rooms[rid].name + " - " + door.name)def cmdStuff(self):	self.write("stuff in " + self.room.name + ":")	for x in self.room.stuff:		self.write(x.name + " - " + str(x.danger))def cmdExplore(self):	if not self.world.bookmarks.has_key("cot"):		self.write("can't explore no cot mark to use as home-base")		return False	elif not self.room:		self.write("you aren't in a room yet, can't do anything, try 'look'")		return False	else:		cot = self.world.bookmarks["cot"]		rooms = self.world.rooms		# make a list of unexplored rooms		unexplored_rooms = []		for rid in rooms:			room = rooms[rid]			for door in room.doors:				if not door.destination and not door.closed:					unexplored_rooms.append(room)					break		g = getPathFindFromRooms(rooms)				try:			here_to_cot = g.findPath(self.room, cot)		except:			here_to_cot = False		# get closest path from cot to unexplored		cot_to_unexplored = False		cot_to_unexplored_destination = False		for room in unexplored_rooms:			try:				path = g.findPath(cot, room)				if not cot_to_unexplored or len(path) < len(cot_to_unexplored):					cot_to_unexplored = path					cot_to_unexplored_destination = room				except:				pass		# get closest path from here to unexplored		here_to_unexplored = False		for room in unexplored_rooms:			try:				path = g.findPath(self.room, room)				if here_to_unexplored and len(path) > len(here_to_unexplored):					pass				else:					here_to_unexplored = path			except:				pass		# of our paths, figure out which is the best option		dest_path = None		if here_to_cot and cot_to_unexplored and here_to_unexplored:			if len(here_to_cot) - 3 > len(here_to_unexplored):				dest_path = g.findPath(self.room, cot_to_unexplored_destination)			else:				dest_path = here_to_unexplored		elif here_to_unexplored:			dest_path = here_to_unexplored		# if we picked a path go there, otherwise wander		if dest_path:			# pick out an unexplored door in destination room			for door in dest_path[-1].doors:				if not door.destination and not door.closed:					unexplored_door = door					break			# convert our path to a list of exits			path_doors = g.getEdges(dest_path)			self.write("start room is " + dest_path[0].name + ", going to explore " + unexplored_door.name + " in " + dest_path[-1].name)			for d in path_doors:				queue(self, goDoor, d)			queue(self, exploreDoor, unexplored_door)			return True		else:			queue(self, cmdWander)		return Falsedef queue(self, fun, *fargs):	self.action_queue.append((fun, fargs))def scriptText(self, txt):	self.write("\n-----------------------------------------------------")	x = txt.find(" ")	if x == -1:		targs = False		cmd = txt.strip()	else:		cmd = txt[0:x]		targs = txt[x+1:]	if txt.strip() == "":		cmdExplore(self)	elif txt.strip() == "think":		if self.thinking is True:			self.thinking = False		else:			self.action_queue = []			self.thinking = True	elif txt.strip() == "test_queue":		queue(self, cmdWander)	elif txt.strip() == "test_path":		x = PathFind()		rooms = self.world.rooms		for rid in rooms:		    for d in rooms[rid].doors:			if d.destination is not False:			    self.write("adding " + rooms[rid].name + " - " +  d.destination.name + " via " + d.name)			    x.addEdge(rooms[rid], d.destination, 1, d, 1)		for ax in rooms:			for bx in rooms:				a = rooms[ax]				b = rooms[bx]			try:				p = x.findPath(a,b)				ds = x.getEdges(p)				self.write(a.name+ " to "+ b.name)				for d in ds:					self.write( " - "+ d.name)			except:				self.write( "NO PATH "+ a.name+ " - "+ b.name)	elif txt.strip() == "rooms":		rooms = self.world.rooms		self.write("list of rooms:\n")		for rid in rooms:			#self.write(" - source is " + self.room.name + " dest is " + rooms[rid].name)			if rooms[rid] is not self.room:				p = getEdges(self.world.rooms,self.room,rooms[rid])				door_names = []				if p is not None:					for door in p:						door_names.append(door.name)					t = ", ".join(door_names)					self.write(rooms[rid].name + " - " + ", ".join(door_names))				else:					self.write(rooms[rid].name + " - no path")			else:				self.write(rooms[rid].name + " - you are here")	elif cmd == "newdoor": cmdNewDoor(self, targs)	elif cmd == "stuff": cmdStuff(self)	elif cmd == "closedoor": cmdCloseDoor(self, targs)	elif cmd == "opendoor": cmdOpenDoor(self, targs)	elif cmd == "explore": cmdExplore(self)	elif txt.strip() == "alldoors":		for rid in self.world.rooms:			room = self.world.rooms[rid]			self.write("doors in " + room.name)			for door in room.doors:				if door.destination is False:					desc = "Unexplored"				else:					desc = door.destination.name				self.write("---" + door.name + " - " + desc)	elif txt.strip() == "doors": cmdDoors(self)	elif txt.strip() == "saveworld":		pkl_file = open('data.pkl', 'wb')		pickle.dump(self.world, pkl_file)		pkl_file.close()	elif txt.strip() == "loadworld":		pkl_file = open('data.pkl', 'rb')		self.world = pickle.load(pkl_file)		for rid in self.world.rooms:			self.write(self.world.rooms[rid].name)			for d in self.world.rooms[rid].doors:				self.write("--- " + str(d.destination))		self.room = False		self.send("look")					pkl_file.close()	elif txt.strip().startswith("mark"):		s = txt.strip()		x = s.find(" ")		if x == -1:			self.write("Bookmarks: ")			for name in self.world.bookmarks:				p = getEdges(self.world.rooms,self.room,self.world.bookmarks[name])				door_names = []				if p is not None:					for door in p:						door_names.append(door.name)					t = ", ".join(door_names)					self.write(name + " - " + ", ".join(door_names))				else:					self.write(name + " - no path")		else:			m = s[x+1:]			if self.world.bookmarks.has_key(m):				dest = self.world.bookmarks[m]				p = getEdges(self.world.rooms, self.room, dest)				if p is not None:					self.write("going on path" + dest.name)					for d in p:						self.send(d.name)				else:					self.write("can't get there from here")			else:				self.world.bookmarks[m] = self.room				self.write("recorded as " + m)	elif txt.strip().startswith("resetmark"):		s = txt.strip()		x = s.find(" ")		if x == -1:			self.write("what mark do you want to clear?")		else:			m = s[x+1:]			if self.world.bookmarks.has_key(m):				del(self.world.bookmarks[m])				self.write("cleared")			else:				self.write("no mark by that name was set")	elif txt.strip() == "resetworld":		self.world = world()		self.room = False		self.send("look")		self.write("world reset.")	else:		self.send(txt)	self.write("-----------------------------------------------------")def exploreDoor(self, door):	if not door.destination:		door.closed = True	self.send(door.name)def goDoor(self, door):	self.send(door.name)def cmdDoors(self):	self.write("doors in " + self.room.name + ": \n")	for door in self.room.doors:		if door.destination is False:			desc = "Unexplored"		else:			desc = door.destination.name		if door.closed: desc += " - closed"		self.write(door.name + " - " + desc)def cmdWander(self):	room = self.room	if room:		unexplored_doors = []		for door in room.doors:			if door.explored is False:				unexplored_doors.append(door)		if len(unexplored_doors) > 0:			r = choice(unexplored_doors)			self.write("Exploring the unexplored.")			r.explored = True		else:			r = choice(room.doors)		self.write("Going to a random door " + r.name + ".")		self.last_move = time()		exploreDoor(self, r)	else:		self.write("Can't wander because you aren't in a room.")class roomDescription:	def isIndented(self, line):		return line[0:2] == "  "	def isStartOfDoors(self, line):		return line.find("obvious exit") > -1	def __init__(self, txt):		self.name = False		self.doors = False		self.stuff = False		self.description = False		self.txt = txt		self.debug_text = []		bits = txt.splitlines()		name_index = False		for i in range(len(bits)):			if bits[i].find("-*-") != -1:				name_index = i		parseType = 0		handler = {}		handler[0] = self.handleDescription		handler[1] = self.handleDoors		handler[2] = self.handleStuff		currentIndentStatus = False		if name_index:			self.name = bits[name_index].split("   ")[0]			self.debug_text.append("name - " + self.name)			for i in range(name_index+4, len(bits)):				if self.isIndented(bits[i]) != currentIndentStatus:					if parseType > 0 or self.isStartOfDoors(bits[i]): 						parseType += 1						currentIndentStatus = self.isIndented(bits[i])				handler[parseType](bits[i])	def handleDescription(self, txt):		if self.description is False:			self.description = ""		else:			self.description += "\n"		self.description += txt		self.debug_text.append("DESC - " + txt)	def handleDoors(self, txt):		if self.doors is False:			self.doors = []		for needle in ["obvious exit: ", "obvious exits: "]:			i = txt.find(needle)			if i != -1:				for d in txt[i + len(needle):].split(", "):					self.doors.append(d.strip())		self.debug_text.append("DOOR - " + txt)	def handleStuff(self, txt):		if self.stuff is False:			self.stuff = []		self.stuff.append(txt)		self.debug_text.append("STUFF - " + txt)def handleroomDesc(self, txt):	try:		d = roomDescription(txt)		doors = False		stuff = False		name = False		if d.name:			name = d.name		if d.doors:			doors = []			for dr in d.doors:				doors.append(door(dr))		if d.name and doors:			rid = d.name + d.description			if not self.world.rooms.has_key(rid):				r = room(name)				r.doors = doors				self.world.rooms[rid] = r				#self.write("CHARTING " + r.name + str(rid))			else:				r = self.world.rooms[rid]				r.seen += 1			# if we came from another room connect exits		if d.name and self.room:			#self.write("CAME FROM " + self.room.name + " via " + self.last_command.strip())			for dr in self.room.doors:				#self.write("Checking " + d.name + " against " + self.last_command.strip())				if self.last_command.strip() == dr.name:					self.write("FOUND MATCH DOOR " + dr.name)					if dr.destination is False:						self.write("CONNECTING THE DOORS")						dr.destination = r						dr.closed = False		self.room = r		self.last_move = time()		self.last_consider = 10		consider_sent = False		if d.stuff:			stuff = []			for x in d.stuff:				thing_name = x.strip()				found_thing = False				for t in self.room.stuff:					if t.name == thing_name:						found_thing = t				if found_thing:					found_thing.seen += 1				else:					t = thing(thing_name)					self.room.stuff.append(t)			for x in self.room.stuff:				if not x.considered:					if not consider_sent:						self.send("consider")						consider_sent = True					x.considered = True	except:		return		self.write("Couldn't parse room.\n")		self.write("--START----")		self.write(txt)		self.write("--END----")