SHOW:
|
|
- or go back to the newest paste.
1 | import Image, ImageDraw,math, ImageFilter, random | |
2 | # needs PIL to run | |
3 | # WIP | |
4 | ||
5 | class Ant: | |
6 | def __init__(self): | |
7 | self.pos = (256,256) | |
8 | # potentialEnergy is used to calculate how far it should move | |
9 | self.potentialEnergy = 10.0 | |
10 | # angle is for the current directional heading | |
11 | self.angle=45.0 | |
12 | # size is the radius of the ant (used for sensing pheromones | |
13 | self.size = 5 | |
14 | #this method does not nessecarily go to the destination | |
15 | # instead it goes in the direction of the destination | |
16 | # based off of how much potentialEnergy is left | |
17 | def head_to(self, destination): | |
18 | # find a direction to head | |
19 | angle = math.tan( destination[1]-pos[1]/destination[0]-pos[0]) | |
20 | self.ydifference = math.sin(angle)*potentialEnergy | |
21 | self.xdifference = math.cos(angle)*potentialEnergy | |
22 | pos = (round(pos[0]+self.xdifference),round(pos[1]+self.ydifference)) | |
23 | return | |
24 | ||
25 | # returns a touple of values at the sensor locations (left,right) | |
26 | def sense(self): | |
27 | # set up the sensors as 15 degrees off of the angle at a given distance | |
28 | self.Langle = self.angle + math.pi/12.0 | |
29 | self.Rangle = self.angle - math.pi/12.0 | |
30 | self.Lpos = (math.cos(self.Langle)*self.size,math.sin(self.Langle)*self.size) | |
31 | self.Rpos = (math.cos(self.Rangle)*self.size,math.sin(self.Rangle)*self.size) | |
32 | self.leftResult = self.sVal(self.Lpos) | |
33 | self.rightResult = self.sVal(self.Rpos) | |
34 | return (self.leftResult,self.rightResult) | |
35 | # used in the above method, to return a decent value from a location | |
36 | def sVal(self,where): | |
37 | self.x = round(where[0]) | |
38 | self.y = round(where[1]) | |
39 | try: | |
40 | return play.im.getpixel((self.x,self.y)) | |
41 | except: | |
42 | return 255 | |
43 | ||
44 | #similar to head_to, but instead moves in the direction of the current angle | |
45 | # uses potentialEnergy to determine distance | |
46 | def move_in(self,heading): | |
47 | self.ydifference = math.sin(heading)*self.potentialEnergy | |
48 | self.xdifference = math.cos(heading)*self.potentialEnergy | |
49 | playing.draw.line((self.pos,(self.pos[0]+self.xdifference,self.pos[1]+self.ydifference)),width=1) | |
50 | self.pos = (round(self.pos[0]+self.xdifference),round(self.pos[1]+self.ydifference)) | |
51 | return | |
52 | def blur(self,howMuch): | |
53 | for i in int(howMuch): | |
54 | im = im.filter(ImageFilter.BLUR) | |
55 | ||
56 | # works in degrees | |
57 | def rotate(self,heading): | |
58 | heading = heading * 0.017453 | |
59 | self.angle=heading+self.angle | |
60 | ||
61 | def wander(self, num_steps): | |
62 | self.angle_towards_p() | |
63 | for i in range(0,num_steps): | |
64 | self.rotate(random.randint(-20,20)) | |
65 | self.move_in(self.angle) | |
66 | ||
67 | def turn_this_ant_around(self): | |
68 | # right this minute, and I mean it this time | |
69 | self.angle = self.angle+math.pi | |
70 | ||
71 | def try_a_significantly_new_angle(self): | |
72 | self.rotate(random.randint(-45,45)) | |
73 | ||
74 | # this function steers the ant towards the pheromone trail | |
75 | # currently it is a binary steering operation | |
76 | # see if elif state ment, have the ant turn based on a gradient | |
77 | # might work much better. | |
78 | def angle_towards_p(self): | |
79 | sensing_result = self.sense() | |
80 | # the signs are the way they are cause we are going towards darkness (0) away from light (255) | |
81 | if sensing_result[0]<sensing_result[1] - 3: | |
82 | self.rotate(-35) | |
83 | elif sensing_result[0]>sensing_result[1] + 3: | |
84 | self.rotate(35) | |
85 | ||
86 | #def handle_edge(self): | |
87 | # if self.pos[0]>worldSize[0] | |
88 | ||
89 | ||
90 | class Player: | |
91 | def __init__(self): | |
92 | self.number_of_ants=25 | |
93 | self.number_of_turns = 5 | |
94 | self.ant_list = [] | |
95 | self.worldSize = (512,512) | |
96 | self.im = Image.new("L",self.worldSize,"white") | |
97 | self.draw = ImageDraw.Draw(self.im) | |
98 | for k in range(0,self.number_of_ants): | |
99 | self.ant_list.append(Ant()) | |
100 | def play(self): | |
101 | for self.NT in range(0,int(self.number_of_turns)): | |
102 | # there is something weird about this modulo behavior | |
103 | # it seems to be triggering to often. | |
104 | if self.NT % 6 == 0: | |
105 | self.im.show("pre-blur") | |
106 | self.im = self.im.filter(ImageFilter.GaussianBlur(radius = 2.0)) | |
107 | for j in range(0,self.number_of_ants): | |
108 | self.ant_list[j].wander(16) | |
109 | if self.NT % 50 == 0: | |
110 | self.ant_list[j].try_a_significantly_new_angle() | |
111 | ||
112 | ||
113 | ||
114 | ||
115 | #print im.getpixel((21,21)) | |
116 | #print math.pi | |
117 | #draw.line(((0,0),(50,50)),width=2) | |
118 | #ant = Ant() | |
119 | playing = Player() | |
120 | playing.play() | |
121 | ||
122 | ||
123 | playing.im.show() | |
124 |