-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathants.jl
159 lines (129 loc) · 4.67 KB
/
ants.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
using Plots
using ProgressBars
steps = 200
dims = 100
ants = 200
wander = 0.5
speed = 1
global dirs = [-pi/4, 0, pi/4]
ph = zeros(Float64, dims, dims)
ant = Vector{Float64}[Float64[dims/2, dims/2, rand()*2*pi] for _ in 1:ants]
prev_ant = Vector{Float64}[Float64[dims/2, dims/2, rand()*2*pi] for _ in 1:ants]
holding_food = fill(false, ants)
food = zeros(Float64, dims, dims)
space = fill(true, dims, dims)
hive = [trunc(Int, dims/2), trunc(Int, dims/2)]
food_cache = [zeros(Float64, dims, dims) for _ in 1:steps]
ph_cache = [zeros(Float64, dims, dims) for _ in 1:steps]
ant_cache = [zeros(Float64, dims, dims) for _ in 1:steps]
# Patches of food
food[35:40, 35:40] .= 1.0
food[20:30, 80:90] .= 1.0
food[60:65, 60:65] .= 1.0
function walk(a::Vector{Float64}, ph, strength = 0.2)
# Check in front, right and left
ant[3] += dirs[findmax([ph[togrid(a[1] + cos(a[3] + dir) * speed), togrid(a[2] + sin(a[3] + dir) * speed)]
for dir in dirs])] * strength
return a
end
function togrid(coord::Float64)
return round(Int, coord)
end
function update(a::Vector{Float64})
return [
a[1] + cos(a[3]) * speed,
a[2] + sin(a[3]) * speed,
a[3]]
end
function grabfood(a::Int, holding_food)
if !holding_food[a]
# check around
end # if
return a
end
#==
for i in ProgressBar(1:steps)
global prev_ant
# reduce all pheremone levels
if i % 50 == 0
for x in 1:length(ph)
ph[x] = max(ph[x] - 0.1, 0.0)
end # for
end # if
_ant_alt = deepcopy(ant)
for a in range(1,length(eachrow(ant)))
# If next to food and not holding food, pick up food
found_food = false
if !holding_food[a]
for d in go
if get(food, (ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]), 0.0) > 0.0
holding_food[a] = true
food[ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]] -= 0.2
found_food = true
break
end # if
end # for
end # if
if holding_food[a]
# If next to hive, drop food
for d in go
if [ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]] == hive
holding_food[a] = false
break
end # If
# Lay pheremones around
if get(space, (ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]), false)
ph[ant[a,1] + d[1][1], ant[a,2] + d[1][2]] += 0.1
end # if
end # If
# Lay pheremones on current squiare
ph[ant[a, 1], ant[a, 2]] = min(ph[ant[a, 1], ant[a, 2]] + 0.1, 1.0)
# If holding food, move to hive
#dir_home = ((ant[a, 1] - hive[1])^2 + (ant[a, 2] - hive[2])^2)^(1/2)
# deeply sad way of getting home
if ant[a, 1] != hive[1] &&
!([ant[a, 1] + sign(hive[1] - ant[a, 1]), ant[a, 2]] in collect(eachrow(ant)))
ant[a, 1] += sign(hive[1] - ant[a, 1])
elseif ant[a, 2] != hive[2] &&
!([ant[a, 1], ant[a, 2] + sign(hive[2] - ant[a, 2])] in collect(eachrow(ant)))
ant[a, 2] += sign(hive[2] - ant[a, 2])
end # if
else
# look around at pheremone levels
go = [d[1] => get(ph, (ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]), -Inf) for d in go]
# move in that direction
sorted = all([d[2] <= 0.0 for d in go]) ? sort(go, by=x -> rand()) : sort(go, by=x -> x[2])
for d in sorted
global prev_ant
if ant[a, 1] + d[1][1] < dims && ant[a, 1] + d[1][1] > 0 &&
ant[a, 2] + d[1][2] < dims && ant[a, 2] + d[1][2] > 0 &&
!([ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]] in collect(eachrow(ant))) &&
collect(eachrow(prev_ant))[a] != [ant[a, 1] + d[1][1], ant[a, 2] + d[1][2]]
ant[a, 1] += d[1][1]
ant[a, 2] += d[1][2]
break
end # if
end # for
end # if
end # for
prev_ant = deepcopy(_ant_alt)
food_cache[i] = deepcopy(food)
ph_cache[i] = deepcopy(ph)
for a in eachrow(ant)
ant_cache[i][a[1], a[2]] = true
end # for
end # for
==#
println("Rendering...")
anim = @animate for i in ProgressBar(1:steps)
heatmap(ant_cache[i], clim=(0,1))
end
gif(anim, "ants.gif", fps = 20)
anim1 = @animate for i in ProgressBar(1:steps)
heatmap(ph_cache[i], clim=(0,1))
end
gif(anim1, "ph.gif", fps = 20)
anim2 = @animate for i in ProgressBar(1:steps)
heatmap(food_cache[i], clim=(0,1))
end # for
gif(anim2, "food.gif", fps= 100)