Робот-перфекционист.
Автор
"""
# type Room
- Julia version: 1.10.4
- Author: joseph
- Date: 2024-08-31
# Examples
```jldoctest
julia>
```
"""
mutable struct Room
version
name
width
height
plane
z
set_walls
draw
frame1
floodfill
animatedfloodfill
make_labirinth
generate_start_point
generate_zero_plane
robot
function Room(name, width, height)
plane = zeros(width, height);
plane[[1, width], :] .= 1;
plane[:, [1, height]] .= 1;
function set_walls(r)
println("Setting walls. ", "width: ", string(r.width), "height: ", string(r.height))
for i in 1:(r.width / 2)
x1 = rand(1:r.width)
y1 = rand(1:r.height)
y2 = rand(1:r.height)
if y1 < y2
for j in y1:y2
r.plane[x1, j] = 1
end
end
end
for i in 1:(r.height / 2)
x1 = rand(1:r.width)
x2 = rand(1:r.width)
y1 = rand(1:r.height)
if x1 < x2
for j in x1:x2
r.plane[j, y1] = 1
end
end
end
end
function floodfill(r::Room, x, y, animated::Bool=false, A=0)
if (x < 1 || x > r.width || y < 1 || y > r.height) return; end;
if (r.plane[x, y] != 0 || r.z[x, y] != 0) return; end;
r.z[x, y] = 0.5
if animated
if r.robot != 0
heatmap((RGB.(r.robot.known_plane, r.z, r.z) + RGB.(r.z, r.plane, r.z))', cbar = :none, c = :blues)
heatmap!(title = "V" * r.version * " " * r.name * " Start point: " * "(" * string(r.robot.start_x) * "," * string(r.robot.start_y) * ")")
else
heatmap(RGB.(r.z, r.plane, r.z), cbar = :none, c = :blues)
heatmap!(title = "V" * r.version * " " * r.name)
end
frame(A)
end
floodfill(r, x - 1, y, animated, A)
floodfill(r, x + 1, y, animated, A)
floodfill(r, x, y - 1, animated, A)
floodfill(r, x, y + 1, animated, A)
end
function draw(r::Room)
A = Animation()
if r.robot != 0
heatmap((RGB.(r.robot.known_plane, r.z, r.z) + RGB.(r.z, r.plane, r.z))', cbar = :none, c = :blues)
heatmap!(title = "V" * r.version * " " * r.name * " Start point: " * "(" * string(r.robot.start_x) * "," * string(r.robot.start_y) * ")")
a = r.robot
xp = push!([x[1] for x in a.path], a.x + a.dir.x)
yp = push!([x[2] for x in a.path], a.y + a.dir.y)
plot!(xp, yp, linewidth=2, linecolor=RGB(0.5, 0.5, 0.5), legend=:false)
else
heatmap(RGB.(r.z, r.plane, r.z), cbar = :none, c = :blues)
heatmap!(title = "V" * r.version * " " * r.name)
end
frame(A)
gif(A, r.name * ".gif", fps = 10)
end
function frame1(r::Room)
r.z = zeros(r.width, r.height)
if r.robot != 0
heatmap((RGB.(r.robot.known_plane, r.z, r.z) + RGB.(r.z, r.plane, r.z))', cbar = :none, c = :blues)
heatmap!(title = "V" * r.version * " " * r.name * " Start point: " * "(" * string(r.robot.start_x) * "," * string(r.robot.start_y) * ")")
a = r.robot
xp = push!([x[1] for x in a.path], a.x + a.dir.x)
yp = push!([x[2] for x in a.path], a.y + a.dir.y)
plot!(xp, yp, linewidth=2, linecolor=RGB(0.5, 0.5, 0.5), legend=:false)
else
heatmap(RGB.(r.z, r.plane, r.z), cbar = :none, c = :blues)
heatmap!(title = "V" * r.version * " " * r.name)
end
end
function animatedfloodfill(r::Room)
A = Animation()
r.z = zeros(r.width, r.height)
if r.robot != 0
r.floodfill(r, r.robot.start_x, r.robot.start_y, true, A)
a = r.robot
plot!([a.x, a.x + a.dir.x], [a.y, a.y + a.dir.y], arrow=(:closed, 2.0), legend=:false)
else
x, y = generate_start_point(r)
r.floodfill(r, x, y, true, A)
end
gif(A, r.name * "A.gif", fps = 30)
r.z = zeros(r.width, r.height)
end
function make_labirinth(r::Room, lines)
for i in 1:lines
not_found = true
tries = 0
while not_found && tries < 1000
tries += 1
x = rand(2:(r.width - 2));
y = rand(2:(r.height - 2));
if sum(r.plane[(x - 1):(x + 1), (y - 1):(y + 1)]) == 0
not_found = false
dir = rand(1:4)
s = 0
s2 = 0
s3 = 0
while (s == 0) && ((s2 != 2) || (s3 == 1)) && (rand(1:r.width) > 3)
r.plane[x, y] = 1
if dir == 1
x += 1
if ( x == r.width)
break;
end
s = sum(r.plane[x, (y - 1):(y + 1)])
s2 = r.plane[x + 1, y - 1] + r.plane[x + 1, y + 1]
s3 = r.plane[x + 1, y]
elseif dir == 2
x -= 1
if ( x == 1)
break;
end
s = sum(r.plane[x, (y - 1):(y + 1)])
s2 = r.plane[x - 1, y - 1] + r.plane[x - 1, y + 1]
s3 = r.plane[x - 1, y]
elseif dir == 3
y += 1
if ( y == r.height)
break;
end
s = sum(r.plane[(x-1):(x+1), y])
s2 = r.plane[x - 1, y + 1] + r.plane[x + 1, y + 1]
s3 = r.plane[x, y + 1]
elseif dir == 4
y -= 1
if ( y == 1)
break;
end
s = sum(r.plane[(x-1):(x+1), y])
s2 = r.plane[x - 1, y - 1] + r.plane[x + 1, y - 1]
s3 = r.plane[x, y - 1]
end
end
end
end
end
end
function generate_start_point(r::Room)
width = size(r.plane, 1)
height = size(r.plane, 2)
gen_start_point = true
s_x = 0
s_y = 0
while gen_start_point
s_x = rand(1:width);
s_y = rand(1:height);
if r.plane[s_x, s_y] == 0
gen_start_point = false
end
end
return s_x, s_y
end
function generate_zero_plane(r::Room)
width = size(r.plane, 1)
height = size(r.plane, 2)
return zeros(width, height)
end
new("1.3", name, width, height, plane, zeros(width, height),
set_walls,
draw,
frame1,
floodfill,
animatedfloodfill,
make_labirinth,
generate_start_point,
generate_zero_plane,
0)
end
end