# # El laberint del minotaure (Versio bots) # Gener de 2010 # http://josep.valls.name # import math import random import Tkinter from Tkinter import * from bot_ai import * import os def distance(a,b): return math.sqrt((a.x-b.x)**2+(a.y-b.y)**2) class Point(): def __init__(self,x,y): self.x = x self.y = y def copy(self): return Point(self.x,self.y) class Node(): def __init__(self,p,id): self.p = p self.id = id self.c = 'green' self.friends = {} def addfriend(self,key,friend): self.friends[key]=friend class Friend(): def __init__(self,c,node): self.c = c self.node = node class Path(): def __init(self): self.cost = 0 self.nodes = [] class Grid(): def __init__(self,size,center,faces): self.size = size self.faces = faces self.center = center self.totalnodes = faces**2 self.initnodes() self.name = "Grid" def initnodes(self): self.nodes = {} key = 0 cost = 1 step = (self.size+1.0)/(self.faces-1) for i in xrange(self.faces): for j in xrange(self.faces): node = Node(Point(i*step+self.center.x,j*step+self.center.y),key) if j > 0: node.addfriend(key-1,Friend(cost,self.nodes[key-1])) self.nodes[key-1].addfriend(key,Friend(cost,node)) if i > 0: node.addfriend(key-self.faces,Friend(cost,self.nodes[key-self.faces])) self.nodes[key-self.faces].addfriend(key,Friend(cost,node)) self.nodes[key] = node key = key +1 self.selected = key-1 def removenode(self,key): if key in self.nodes: node = self.nodes[key] for friend in node.friends.values(): del friend.node.friends[key] del self.nodes[key] else: print "node not found" def distance(self,a,b): return distance(self.nodes[a].p,self.nodes[b].p) def moverules(self,pos): moves = [] if pos % self.faces < self.faces-1: moves.append(1) if pos % self.faces >0: moves.append(2) if pos < self.totalnodes - self.faces: moves.append(3) if pos >= self.faces: moves.append(4) return moves class Painter(): def __init__(self): self.win = Tkinter.Tk() self.win.title("El laberint del minotaure (Versio bots) - http://josep.valls.name") self.canvas = Tkinter.Canvas(self.win, width=900, height=600, background='black') self.canvas.pack() self.tasks = [] self.colors=['red','blue','green','yellow','magenta','cyan','orange','purple','sea green','pink'] def drawgrid(self,grid): step = 1.0*grid.size/(grid.faces-1) for i in xrange(grid.faces): self.drawline(Point(grid.center.x,grid.center.y+step*i),Point(grid.center.x+grid.size,grid.center.y+step*i),"yellow",1) self.drawline(Point(grid.center.x+step*i,grid.center.y),Point(grid.center.x+step*i,grid.center.y+grid.size),"yellow",1) def labelnodes(self,graph): for key,node in graph.nodes.items(): self.drawnode(node,0,1) def plotnodes(self,graph): for key,node in graph.nodes.items(): self.drawnode(node,1,0) def drawtiles(self,graph): #pass for key,node in graph.nodes.items(): self.drawtile(node.p,graph.size/graph.faces) def drawline(self,a,b,color,tickness): self.canvas.create_line(a.x,a.y,b.x,b.y, fill = color, width = tickness) def drawtile(self,p,size): size = size * 1.1 self.canvas.create_rectangle(p.x-size/2,p.y-size/2,p.x+size/2,p.y+size/2,fill = "#655", outline = '#333') if random.random()>0.2: self.canvas.create_line(p.x-size/2,p.y-size/2+random.random()*size,p.x-size/2+random.random()*size,p.y-size/2, fill = '#544', width = random.randint(1,3)) if random.random()>0.4: self.canvas.create_line(p.x+size/2,p.y-size/2+random.random()*size,p.x-size/2+random.random()*size,p.y+size/2, fill = '#544', width = random.randint(1,3)) if random.random()>0.6: self.canvas.create_line(p.x-size/2+random.random()*size,p.y-size/2+random.random()*size,p.x-size/2+random.random()*size,p.y-size/2+random.random()*size, fill = '#544', width = random.randint(1,3)) def drawnode(self,node,drawpoint,drawtext): pointsize = 6 textoffset = 5 if drawpoint: self.drawpoint(node.p,pointsize,node.c) if drawtext: self.canvas.create_text(node.p.x+textoffset,node.p.y+textoffset, tag = 'nodelabel', text = node.id, fill="blue") def drawpoint(self,p,pointsize,color): self.canvas.create_oval(p.x-pointsize/2, p.y-pointsize/2, p.x+pointsize/2, p.y+pointsize/2, fill = color) def drawgoal(self,p): pointsize = 25 self.canvas.create_oval(p.x-pointsize/2, p.y-pointsize/2, p.x+pointsize/2, p.y+pointsize/2, fill = "white", tag = "goal") def drawenemy(self,p): pointsize = 25 self.canvas.create_oval(p.x-pointsize/2, p.y-pointsize/2, p.x+pointsize/2, p.y+pointsize/2, fill = "black", outline = 'white',tag = "goal") def drawplayer(self,player,p,color): pointsize = 16 text = "%s %d" % (player.ai.name, player.score) self.canvas.create_oval(p.x-pointsize/2, p.y-pointsize/2, p.x+pointsize/2, p.y+pointsize/2, fill = color, tag = "player") self.canvas.create_text(p.x, p.y+pointsize/1.5, text = text, fill = color, tag = "player") def drawlabel(self,a,text): self.canvas.create_text(a.x+5,a.y+5, tag = 'debugtext', text = text, fill='blue') def mainloop(self): self.win.mainloop() class Player(): def __init__(self,g,ai): self.pos = g.nodes.keys()[0] self.g = g self.ai = ai self.score = 0 def nodemoverules(self,pos): moves = [0] if (pos+1) in self.g.nodes[pos].friends.keys(): moves.append(1) if (pos-1) in self.g.nodes[pos].friends.keys(): moves.append(2) if (pos+self.g.faces) in self.g.nodes[pos].friends.keys(): moves.append(3) if (pos-self.g.faces) in self.g.nodes[pos].friends.keys(): moves.append(4) return moves def move(self,sensors): moves = self.nodemoverules(self.pos) move = self.ai.move(moves,sensors) if not move in moves: return if move == 0: pass elif move == 1: self.pos = self.pos+1 elif move == 2: self.pos = self.pos-1 elif move == 3: self.pos = self.pos + self.g.faces elif move == 4: self.pos = self.pos - self.g.faces class GameController(): def __init__(self,g,startplayer,startenemy,startgoal): self.players = [Player(g,AI0()),Player(g,AI1()),Player(g,AI2()),Player(g,AI3()),Player(g,AI4()),Player(g,AI5()),Player(g,AI6()),Player(g,AI7()),Player(g,AI8()),Player(g,AI9())] #self.players.append(Player(g,AI0())) self.g = g self.goal = startgoal self.enemy = startenemy self.resetplayers(startplayer) if startenemy==0:self.createenemy() if startgoal==0: self.creategoal() def update(self): if self.goal>=0: p.drawgoal(self.g.nodes[self.goal].p) if self.enemy>=0: p.drawenemy(self.g.nodes[self.enemy].p) for (i,player) in enumerate(self.players): sensors = [] sensors.append(self.g.distance(player.pos,self.enemy) if self.enemy>=0 else 100000) sensors.append(self.g.distance(player.pos,self.goal) if self.goal>=0 else 100000) player.move(sensors) p.drawplayer(player,self.g.nodes[player.pos].p,p.colors[i]) self.checkgoal() def checkgoal(self): goalfound = 0 for (i,player) in enumerate(self.players): if player.pos == self.goal: player.score = player.score + 1 goalfound = 1 if player.pos == self.enemy: player.score = player.score - 1 player.ai.enemy() if goalfound: for (i,player) in enumerate(self.players): if player.pos == self.goal: player.ai.win() else: player.ai.lose() self.creategoal() def creategoal(self): freenodes = self.g.nodes.keys() for player in self.players: if player.pos in freenodes: freenodes.remove(player.pos) if self.enemy in freenodes: freenodes.remove(self.enemy) self.goal = freenodes[random.randint(1,len(freenodes)-1)] def createenemy(self): freenodes = self.g.nodes.keys() for player in self.players: if player.pos in freenodes: freenodes.remove(player.pos) self.enemy = freenodes[random.randint(1,len(freenodes)-1)] def resetplayers(self,pos): for player in self.players: player.pos = pos if pos else self.g.nodes.keys()[random.randint(1,len(self.g.nodes.keys())-1)] def scoreboard(self): for (i,player) in enumerate(self.players): print player.ai.name, player.score p = Painter() minotaure = 1 if not minotaure: g1 = Grid(260,Point(20,20),8) g2 = Grid(260,Point(320,20),12) g3 = Grid(260,Point(620,20),18) for i in (6,18,30,42,54,66,78,90,102,138,74,75,76,77,79,80,81,117,118,119,33,34,35,120,121,122,123): g2.removenode(i) for i in xrange(g3.totalnodes/20): g3.removenode(random.randint(g3.totalnodes/2,g3.totalnodes)) x = GameController(g1,1,0,0) y = GameController(g2,1,0,0) z = GameController(g3,1,0,0) p.drawgrid(g1) p.plotnodes(g2) p.plotnodes(g3) p.plotnodes(g1) #p.labelnodes(g3) else: g1 = Grid(560,Point(170,20),35) for i in (1189,1188,1187,1185,1181,1180,1179,1178,1177,1176,1175,1174,1173,1172,1171,1170,1169,1168,1167,1166,1165,1164,1163,1162,1161,1160,1159,1158,1157,1156,1154,1152,1151,1150,1146,1128,1125,1121,1111,1109,1108,1107,1106,1105,1104,1103,1101,1100,1099,1098,1097,1096,1095,1093,1092,1088,1086,1084,1076,1074,1068,1060,1058,1055,1051,1049,1048,1047,1046,1045,1041,1039,1037,1036,1035,1033,1032,1031,1030,1029,1028,1027,1025,1023,1022,1018,1006,1004,1002,998,992,990,988,985,981,979,971,969,967,965,964,963,962,961,960,959,957,955,953,952,948,944,943,942,941,940,936,934,932,930,924,922,920,918,915,911,901,899,897,895,893,891,889,885,883,882,878,874,873,872,871,870,866,864,862,860,858,857,856,854,852,850,848,845,841,837,835,831,829,827,825,819,817,816,815,813,812,808,804,803,802,801,800,796,794,792,790,789,788,786,785,784,782,780,778,775,771,761,757,753,749,747,743,742,738,733,732,731,730,726,724,722,721,720,718,717,716,714,712,710,708,705,701,699,691,689,685,679,677,675,673,672,668,663,662,661,660,656,654,652,651,650,649,648,646,645,644,642,640,638,635,631,621,619,617,607,605,603,602,598,586,584,582,580,578,576,574,572,570,568,565,561,551,549,548,547,545,543,542,541,539,537,536,535,533,532,528,516,512,510,508,504,502,500,498,495,491,481,479,477,475,473,471,469,468,467,463,462,458,446,444,442,440,436,434,432,430,428,425,421,411,409,405,403,401,397,395,393,392,388,376,374,372,371,370,368,366,364,362,360,358,355,351,341,339,337,335,334,333,331,329,328,327,325,323,322,318,306,304,302,300,298,296,294,292,290,288,285,281,271,269,267,265,263,261,259,257,255,253,252,248,236,234,232,230,224,222,220,218,215,211,201,199,197,187,185,183,182,178,166,164,150,148,145,141,131,129,128,127,126,125,119,118,117,116,115,113,112,108,106,96,75,71,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36): g1.removenode(i) x = GameController(g1,136,612,892) p.drawtiles(g1) while 1: p.canvas.delete("player") p.canvas.delete("goal") x.update() if not minotaure: y.update() z.update() #raw_input('Press Enter...') if 1: os.system("cls") #en linux heu de canviar aquesta linia i posar #os.system("clear") print "==========" print x.g.name x.scoreboard() print "==========" print y.g.name y.scoreboard() print "==========" print z.g.name z.scoreboard() p.canvas.update() p.canvas.after(10) p.mainloop()