""" world.py Copyright (C) 1998 Aloril This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. """ import whrandom from event import * from thing import thing from debug import debug import dictlist, wtime from misc import * class filter: def __init__(self): self.types={} def analyse(self,e): str=e.generate_type_string() self.types[str]=e.copy() def print_types(self): for t in self.types.keys(): print t,":" print "\t",self.types[t],"\n" #whole world class world: "whole world" def __init__(self): self.next_id=0 self.things={} self.time=wtime.world_time() self.events=[] self.event_dict={} self.id_dict={} self.filt=filter() self.debug=debug("world.log") self.illegal_thing=thing(name="illegal",place=None,xyz=(0,0,0)) self.id_dict['illegal']=self.illegal_thing self.new_events([event("make",what=self.illegal_thing)]) def get_id(self,name): self.next_id=self.next_id+1 return "_"+name+"_"+`self.next_id` def get_client_id(self): id=self.get_id("client") self.id_dict[id]="client" return id def add_thing(self,thing): "add thing to things list and assign it id" dictlist.add_value(self.things,thing.name,thing) id=self.get_id(thing.name) thing.id=id self.id_dict[id]=thing thing.w=self def remove_thing(self, thing): "remove thing from things list and set its id to illegal_thing" res=dictlist.remove_value(self.things, thing) self.id_dict[thing.id]=self.illegal_thing #reserve id indefinitely thing.w=None return res def get_thing_list(self): "return list of things" res=[] for tl in self.things.values(): res=res+tl return res def __str__(self): s=str(self.time)+"\n" for t in self.get_thing_list(): s=s+", "+`t` return s def __repr__(self): return `"world"` def destroy(self): for tl in self.things.values(): for t in tl: t.destroy() ## def look_all(self): ## res=[] ## for t in self.get_thing_list(): ## res.append(event('look',what=t.id,loc=t.get_xyz())) ## return res #event handling: #m has current thing, e is current event(=output) from that thing #may update self.events def make_event(self,e,m): t=e.what if not hasattr(t,"is_thing"): #it's ething if not hasattr(t,"type"): t.type="thing" tc=get_thing_class(t.type) t=apply(tc,(),t.kw) self.add_thing(t) e.what=t.get_ething() return [event("sight",what=e)] def destroy_event(self,e,m): if e.what.id!="_illegal": if self.remove_thing(e.what): return [event("sight",what=e)] ## def look_event(self,e,m): ## try: ## t=self.id_dict[e.what] ## self.events.append(event("look",source=m, ## what=ething(t.id,name=t.name,type=t.get_type()))) ## except KeyError: ## pass def time_event(self,e,m): return [event("time",what=str(self.time))] def debug_event(self,e,m): d=[str(self.time),[e],[]] if e.what=="on": self.debug.set(1) self.debug(d) else: self.debug(d) self.debug.set(0) def undefined_event(self,e,m): return [e] def filter_event(self,e): self.filt.analyse(e) def analyse_event(self,e,m=None): """m has current mind, e is current event(=output) from that mind may update self.event""" if not e.source: e.source=m if not e.time: e.time=self.time self.filter_event(e) return get_event_func(self,e)(e,m) def analyse_input(self,input,m=None): """m has current mind, e is current event(=output) from that mind may update self.event""" output=[] for e in input: res=self.analyse_event(e,m) if res: for o in res: self.filter_event(o) output.append(o) return output def new_events(self,input): output=self.analyse_input(input) self.debug(["new_events: "+str(self.time),input,output]) self.events=self.events+output return output def run_step(self): #age all things self.time.step() for tl in self.things.values(): for t in tl: t.age=t.age+self.time.stepseconds #add sight events about houses #CHEAT!: not effective and doesn't take into account range or obstacles for h in self.things.get('house',[]): self.events.append(event("sight",what=h)) #let minds think output=[] #separate targeted and non targeted events tevents={} events=[] for e in self.events: if e.target: if tevents.has_key(e.target.id): tevents[e.target.id].append(e) else: tevents[e.target.id]=[e] else: events.append(e) #fire events for t in self.get_thing_list(): elist=tevents.get(t.id,[])+events res=t.run_step(self.time,elist) if res: #optimize away null message lists output.append([t,res]) self.events=[] for (m,mo) in output: for e in mo: #m has current mind, e is current event(=output) from that mind res=self.analyse_event(e,m) if res: self.events=self.events+res self.debug([str(self.time),output,self.events]) return self.events