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