from Tkinter import * from whrandom import * colors = [ "light slate gray", "navy", "blue", "dark green", "lime green", "rosy brown", "red", "purple", "goldenrod", "maroon" ] class app: def __init__(self, x, y): #init variables self.x_max, self.y_max = x, y self.walls = [] self.robots = [] self.draw_items = [] self.clans = [] self.run = 1 #create windows self.root = Tk() self.root.title('eRobot 0.1') self.root.protocol("WM_DELETE_WINDOW", self.main_exit) self.c = Canvas(self.root, bg="white", width=x*14+120, height=y*14+1) self.c.pack() #create and draw walls for i in range(x): self.walls.append(wall(i,0)) self.walls.append(wall(i,y-1)) for i in range(y): self.walls.append(wall(0,i)) self.walls.append(wall(x-1,i)) for i in range(round(y/2)): self.walls.append(wall(round(x/2),i+round(y/4))) for w in self.walls: self.c.create_rectangle(w.x*14+3, w.y*14+3, w.x*14+15, w.y*14+15, fill="dimgray", width=0, outline="dimgray") def main(self): #main loop while self.run == 1: self.redraw() self.compute() self.root.update() def main_exit(self): #exit function, called when windows is closed self.run = 0 self.c.destroy() self.root.destroy() def redraw(self): #draw all robots apply(self.c.delete, self.draw_items) self.draw_items = [] for r in self.robots: self.draw_items.append( self.c.create_rectangle(r.x*14+3, r.y*14+3, r.x*14+15, r.y*14+15, fill=colors[r.clan.id], width=0, outline=colors[r.clan.id]) ) self.draw_items.append( self.c.create_text(r.x*14+9, r.y*14+9, text=r.id, fill="white") ) def new(self, name, robot): #create a new clan and the first robot of the clan, the creation of the robot is handled by the clan if len(self.clans) < 10: c = clan(name, len(self.clans), robot, self.look, self.get_robots) while 1==1: x = randint(0,self.x_max-1) y = randint(0,self.y_max-1) if self.look(x,y)==None: r = c.add(x, y) break self.c.create_text(self.x_max*14+60, len(self.clans)*14+9, text=name, fill=colors[c.id]) self.clans.append(c) self.robots.append(r) def compute(self): #compute the actions of all robots for r in self.robots: action_type, action_param = r.compute() if action_type not in ("move", "make"): continue if action_param == "left": pdx, pdy = -1, 0 elif action_param == "right": pdx, pdy = 1, 0 elif action_param == "up": pdx, pdy = 0, -1 elif action_param == "down": pdx, pdy = 0, 1 else: continue for i in range(1, self.x_max + self.y_max): dx, dy = i*pdx, i*pdy target = self.look(r.x+dx, r.y+dy ) if target == None: break elif isinstance( target, wall ): break elif target.clan is not r.clan: break if isinstance( target, wall ): continue if action_type == "move": if target != None: me, you = 0, 0 for s in self.robots: if (abs( s.x-(r.x+dx) ) <= 1) and (abs( s.y-(r.y+dy) ) <= 1) : if s.clan is target.clan: you = you+1 elif s.clan is r.clan: me = me+1 if me <= you: dx, dy = 0, 0 else: self.robots.remove(target) r.x, r.y = r.x+dx, r.y+dy elif action_type == "make": if target == None: new = r.clan.add(r.x+dx, r.y+dy) if new != None: self.robots.append(new) def look(self, x, y): #return robot, wall or None for r in self.robots + self.walls: if r.x==x and r.y==y: return r return None def get_robots(self): #return list of all robots return self.robots class wall: def __init__(self, x_loc, y_loc): self.x, self.y = x_loc, y_loc class clan: def __init__(self, name_loc, id_loc, robot_loc, look_loc, get_robots_local): self.name = name_loc self.id = id_loc self.first_robot = robot_loc self.look = look_loc self.get_robots = get_robots_local self.count = 0 def add(self, x_loc, y_loc): if self.count < 10: r = (self.first_robot)(x_loc, y_loc, str(self.id)+ str(self.count), self.look, self.get_robots, self) self.count = self.count + 1 return r else: return None class robot_base: def __init__(self, x_loc, y_loc, id_loc, look_loc, get_robots_loc, clan_loc ): self.x, self.y = x_loc, y_loc self.id = id_loc self.look = look_loc self.get_robots = get_robots_loc self.clan = clan_loc