diff --git a/README.md b/README.md index e111ec7..cc66bae 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,10 @@ play(w;file_name="example.gif",frame_rate=5) +- [x] CollectGems + + + ### Needs improvement - [ ] Add test cases diff --git a/docs/src/assets/img/CollectGems.gif b/docs/src/assets/img/CollectGems.gif new file mode 100644 index 0000000..16ba2b2 Binary files /dev/null and b/docs/src/assets/img/CollectGems.gif differ diff --git a/src/envs/collectgems.jl b/src/envs/collectgems.jl new file mode 100644 index 0000000..c6fae20 --- /dev/null +++ b/src/envs/collectgems.jl @@ -0,0 +1,50 @@ +export CollectGems + +mutable struct CollectGems <: AbstractGridWorld + world::GridWorldBase{Tuple{Empty,Wall,Gem}} + agent_pos::CartesianIndex{2} + agent::Agent + num_gem_init::Int + num_gem_current::Int +end + +function CollectGems(;n=8, agent_start_pos=CartesianIndex(2,2), agent_start_dir=RIGHT) + objects = (EMPTY, WALL, GEM) + w = GridWorldBase(objects, n, n) + + w[EMPTY, 2:n-1, 2:n-1] .= true + w[WALL, [1,n], 1:n] .= true + w[WALL, 1:n, [1,n]] .= true + + w[GEM, 1:n, 1:n] .= false + num_gem_init = n - 1 + num_gem_current = num_gem_init + + gem_placed = 0 + while gem_placed < num_gem_init + gem_pos = CartesianIndex(rand(2:n-1), rand(2:n-1)) + if (gem_pos == agent_start_pos) || (w[GEM, gem_pos] == true) + continue + else + w[GEM, gem_pos] = true + w[EMPTY, gem_pos] = false + gem_placed = gem_placed + 1 + end + end + + CollectGems(w, agent_start_pos, Agent(dir=agent_start_dir), num_gem_init, num_gem_current) +end + +function (w::CollectGems)(::MoveForward) + dir = get_dir(w.agent) + dest = dir(w.agent_pos) + if !w.world[WALL, dest] + w.agent_pos = dest + if w.world[GEM, dest] + w.world[GEM, dest] = false + w.world[EMPTY, dest] = true + w.num_gem_current = w.num_gem_current - 1 + end + end + w +end diff --git a/src/envs/envs.jl b/src/envs/envs.jl index 7d14ee8..a2fc559 100644 --- a/src/envs/envs.jl +++ b/src/envs/envs.jl @@ -2,3 +2,4 @@ include("empty.jl") include("fourrooms.jl") include("gotodoor.jl") include("doorkey.jl") +include("collectgems.jl") diff --git a/src/objects.jl b/src/objects.jl index 1a02bf0..d5eaa2b 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -1,5 +1,5 @@ -export COLORS, MOVE_FORWARD, TURN_LEFT, TURN_RIGHT, UP, DOWN, LEFT, RIGHT, LRUD, EMPTY, WALL, GOAL -export MoveForward, AbstractObject, Empty, Wall, Goal, Door, Agent +export COLORS, MOVE_FORWARD, TURN_LEFT, TURN_RIGHT, UP, DOWN, LEFT, RIGHT, LRUD, EMPTY, WALL, GOAL, GEM +export MoveForward, AbstractObject, Empty, Wall, Goal, Door, Gem, Agent export get_color using Crayons @@ -79,6 +79,11 @@ Key(c) = Key{c}() Base.convert(::Type{Char}, ::Key) = '⚷' get_color(::Key{C}) where C = C +struct Gem <: AbstractObject end +const GEM = Gem() +Base.convert(::Type{Char}, ::Gem) = '♦' +get_color(::Gem) = :magenta + Base.@kwdef mutable struct Agent <: AbstractObject color::Symbol=:red dir::LRUD