From 9048dbd9aed2867a4af78cd5e002dc4fcd223bf2 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sat, 10 Oct 2020 10:19:26 -0400 Subject: [PATCH 01/21] Added pickup and drop functions --- src/objects.jl | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index d5eaa2b..03700a5 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -51,6 +51,11 @@ const TURN_LEFT = TurnLeft() ##### abstract type AbstractObject end +abstract type Item <: AbstractObject end + +# Placeholder for empty inventory +struct Null <: Item end +const NULL = Null() Base.show(io::IO, x::AbstractObject) = print(io, Crayon(foreground=get_color(x), reset=true), convert(Char, x)) @@ -74,12 +79,12 @@ Door(c) = Door{c}() Base.convert(::Type{Char}, ::Door) = '⩎' get_color(::Door{C}) where C = C -struct Key{C} <: AbstractObject end +struct Key{C} <: Item end Key(c) = Key{c}() Base.convert(::Type{Char}, ::Key) = '⚷' get_color(::Key{C}) where C = C -struct Gem <: AbstractObject end +struct Gem <: Item end const GEM = Gem() Base.convert(::Type{Char}, ::Gem) = '♦' get_color(::Gem) = :magenta @@ -87,6 +92,7 @@ get_color(::Gem) = :magenta Base.@kwdef mutable struct Agent <: AbstractObject color::Symbol=:red dir::LRUD + inv::Item=NULL end function Base.convert(::Type{Char}, a::Agent) if a.dir === UP @@ -102,3 +108,25 @@ end get_color(a::Agent) = a.color get_dir(a::Agent) = a.dir set_dir!(a::Agent, d) = a.dir = d + +##### +# Pick Up and Drop +##### + +function pickup(a::Agent, o::Item) + if a.Item == NULL + a.Item = o + return true + end + return false +end + +function drop(a::Agent) + if a.item != NULL + x = a.item + a.item = NULL + return x + end + return nothing +end + From cf1963567792326ffa95d82f7b04b62540430bd9 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sat, 10 Oct 2020 10:27:49 -0400 Subject: [PATCH 02/21] added pickup() dispatch for non-item objects --- src/objects.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objects.jl b/src/objects.jl index 03700a5..635ab72 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -120,6 +120,7 @@ function pickup(a::Agent, o::Item) end return false end +pickup(a::Agent, o::AbstractObject) = nothing function drop(a::Agent) if a.item != NULL From a55e8a2c6b519d48a175e59ac6f36b9622ff24d9 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sat, 10 Oct 2020 10:39:01 -0400 Subject: [PATCH 03/21] changed to use pickup function --- src/envs/doorkey.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/envs/doorkey.jl b/src/envs/doorkey.jl index 16ae961..b61880d 100644 --- a/src/envs/doorkey.jl +++ b/src/envs/doorkey.jl @@ -6,7 +6,6 @@ mutable struct DoorKey{W<:GridWorldBase} <: AbstractGridWorld world::W agent_pos::CartesianIndex{2} agent::Agent - has_key::Bool end function DoorKey(;n=8, agent_start_pos=CartesianIndex(2,2), rng=Random.GLOBAL_RNG) @@ -41,13 +40,14 @@ function (w::DoorKey)(::MoveForward) dest = dir(w.agent_pos) if w.world[Key(:yellow), dest] - w.has_key = true - w.world[Key(:yellow), dest] = false - w.world[EMPTY, dest] = true + if pickup(w.agent, Key(:yellow)) + w.world[Key(:yellow), dest] = false + w.world[EMPTY, dest] = true + end w.agent_pos = dest - elseif w.world[Door(:yellow), dest] && w.has_key + elseif w.world[Door(:yellow), dest] && w.agent.inv == Key(:yellow) w.agent_pos = dest - elseif w.world[Door(:yellow), dest] && !w.has_key + elseif w.world[Door(:yellow), dest] && w.agent.inv == Key(:yellow) nothing elseif dest ∈ CartesianIndices((size(w.world, 2), size(w.world, 3))) && !w.world[WALL,dest] w.agent_pos = dest From a96646a789d58cf3b5328b104d9c4ee1d6dd8db1 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sat, 10 Oct 2020 10:51:49 -0400 Subject: [PATCH 04/21] fixed missed argument change --- src/envs/doorkey.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/envs/doorkey.jl b/src/envs/doorkey.jl index b61880d..d561116 100644 --- a/src/envs/doorkey.jl +++ b/src/envs/doorkey.jl @@ -32,7 +32,7 @@ function DoorKey(;n=8, agent_start_pos=CartesianIndex(2,2), rng=Random.GLOBAL_RN world[EMPTY, key_pos] = false world[Key(:yellow), key_pos] = true - DoorKey(world, agent_start_pos, Agent(dir=RIGHT),false) + DoorKey(world, agent_start_pos, Agent(dir=RIGHT)) end function (w::DoorKey)(::MoveForward) From bdc2a92256895865b63fc13178a37755a58ad4ff Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sat, 10 Oct 2020 12:18:41 -0400 Subject: [PATCH 05/21] fixed wrong attribute name --- src/objects.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 635ab72..0a7bd68 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -114,8 +114,8 @@ set_dir!(a::Agent, d) = a.dir = d ##### function pickup(a::Agent, o::Item) - if a.Item == NULL - a.Item = o + if a.inv == NULL + a.inv = o return true end return false @@ -123,9 +123,9 @@ end pickup(a::Agent, o::AbstractObject) = nothing function drop(a::Agent) - if a.item != NULL - x = a.item - a.item = NULL + if a.inv != NULL + x = a.inv + a.inv = NULL return x end return nothing From 4dd1670abc741ce3c881d92657c7e9cdbdb8c3bf Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sat, 10 Oct 2020 12:42:52 -0400 Subject: [PATCH 06/21] fixed bug allowing passage through door w/o key --- src/envs/doorkey.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/envs/doorkey.jl b/src/envs/doorkey.jl index d561116..9683f6a 100644 --- a/src/envs/doorkey.jl +++ b/src/envs/doorkey.jl @@ -47,7 +47,7 @@ function (w::DoorKey)(::MoveForward) w.agent_pos = dest elseif w.world[Door(:yellow), dest] && w.agent.inv == Key(:yellow) w.agent_pos = dest - elseif w.world[Door(:yellow), dest] && w.agent.inv == Key(:yellow) + elseif w.world[Door(:yellow), dest] && w.agent.inv != Key(:yellow) nothing elseif dest ∈ CartesianIndices((size(w.world, 2), size(w.world, 3))) && !w.world[WALL,dest] w.agent_pos = dest From 0d6c5a19d9d0ec94f619470496a4c3769e569ba9 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Sun, 11 Oct 2020 14:53:40 -0400 Subject: [PATCH 07/21] replaced NULL with `nothing` --- src/objects.jl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 0a7bd68..c3b5306 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -53,10 +53,6 @@ const TURN_LEFT = TurnLeft() abstract type AbstractObject end abstract type Item <: AbstractObject end -# Placeholder for empty inventory -struct Null <: Item end -const NULL = Null() - Base.show(io::IO, x::AbstractObject) = print(io, Crayon(foreground=get_color(x), reset=true), convert(Char, x)) struct Empty <: AbstractObject end @@ -92,7 +88,7 @@ get_color(::Gem) = :magenta Base.@kwdef mutable struct Agent <: AbstractObject color::Symbol=:red dir::LRUD - inv::Item=NULL + inv::Union{Item, Nothing} end function Base.convert(::Type{Char}, a::Agent) if a.dir === UP @@ -114,7 +110,7 @@ set_dir!(a::Agent, d) = a.dir = d ##### function pickup(a::Agent, o::Item) - if a.inv == NULL + if a.inv == nothing a.inv = o return true end @@ -123,9 +119,9 @@ end pickup(a::Agent, o::AbstractObject) = nothing function drop(a::Agent) - if a.inv != NULL + if a.inv != nothing x = a.inv - a.inv = NULL + a.inv = nothing return x end return nothing From 922529c8fbb48e6090ee3f6d3a358a1b1ead5951 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Mon, 12 Oct 2020 08:32:34 -0400 Subject: [PATCH 08/21] Added trait-based implementation of pickup --- src/objects.jl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index c3b5306..4bb4438 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -51,7 +51,6 @@ const TURN_LEFT = TurnLeft() ##### abstract type AbstractObject end -abstract type Item <: AbstractObject end Base.show(io::IO, x::AbstractObject) = print(io, Crayon(foreground=get_color(x), reset=true), convert(Char, x)) @@ -75,12 +74,12 @@ Door(c) = Door{c}() Base.convert(::Type{Char}, ::Door) = '⩎' get_color(::Door{C}) where C = C -struct Key{C} <: Item end +struct Key{C} <: AbstractObject end Key(c) = Key{c}() Base.convert(::Type{Char}, ::Key) = '⚷' get_color(::Key{C}) where C = C -struct Gem <: Item end +struct Gem <: AbstractObject end const GEM = Gem() Base.convert(::Type{Char}, ::Gem) = '♦' get_color(::Gem) = :magenta @@ -88,7 +87,7 @@ get_color(::Gem) = :magenta Base.@kwdef mutable struct Agent <: AbstractObject color::Symbol=:red dir::LRUD - inv::Union{Item, Nothing} + inv::Union{AbstractObject, Nothing}=nothing end function Base.convert(::Type{Char}, a::Agent) if a.dir === UP @@ -109,14 +108,23 @@ set_dir!(a::Agent, d) = a.dir = d # Pick Up and Drop ##### -function pickup(a::Agent, o::Item) +struct Item end +struct Nonitem end +const ITEM = Item() +const NONITEM = Nonitem() +isitem(::Type{Key{T}}) where T = ITEM +isitem(::Type{Gem}) = ITEM +isitem() = NONITEM + +pickup(a::Agent, o::T) where T = pickup(isitem(T), a, o) +function pickup(::Item, a::Agent, o::AbstractObject) if a.inv == nothing a.inv = o return true end return false end -pickup(a::Agent, o::AbstractObject) = nothing +pickup(a::Agent, ::Nonitem, o::AbstractObject) = nothing function drop(a::Agent) if a.inv != nothing From 26b536dd695c507ecc780abb9c025dd71c88a776 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Mon, 12 Oct 2020 08:54:00 -0400 Subject: [PATCH 09/21] Made pickup and drop functors --- src/envs/doorkey.jl | 2 +- src/objects.jl | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/envs/doorkey.jl b/src/envs/doorkey.jl index 9683f6a..4d6a4e6 100644 --- a/src/envs/doorkey.jl +++ b/src/envs/doorkey.jl @@ -40,7 +40,7 @@ function (w::DoorKey)(::MoveForward) dest = dir(w.agent_pos) if w.world[Key(:yellow), dest] - if pickup(w.agent, Key(:yellow)) + if PICKUP(w.agent, Key(:yellow)) w.world[Key(:yellow), dest] = false w.world[EMPTY, dest] = true end diff --git a/src/objects.jl b/src/objects.jl index 4bb4438..621a074 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -116,7 +116,10 @@ isitem(::Type{Key{T}}) where T = ITEM isitem(::Type{Gem}) = ITEM isitem() = NONITEM -pickup(a::Agent, o::T) where T = pickup(isitem(T), a, o) +struct Pickup end +const PICKUP = Pickup() + +(::Pickup)(a::Agent, o::T) where T = pickup(isitem(T), a, o) function pickup(::Item, a::Agent, o::AbstractObject) if a.inv == nothing a.inv = o @@ -126,7 +129,10 @@ function pickup(::Item, a::Agent, o::AbstractObject) end pickup(a::Agent, ::Nonitem, o::AbstractObject) = nothing -function drop(a::Agent) +struct Drop end +const DROP = Drop() + +function (::Drop)(a::Agent) if a.inv != nothing x = a.inv a.inv = nothing From 50fb8ca9820656e58779703009d57821c3ba8d45 Mon Sep 17 00:00:00 2001 From: Ben Landrum <36489943+landrumb@users.noreply.github.com> Date: Mon, 12 Oct 2020 19:29:49 -0400 Subject: [PATCH 10/21] Fix error in train implementation Co-authored-by: Jun Tian --- src/objects.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 621a074..c009b03 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -127,7 +127,7 @@ function pickup(::Item, a::Agent, o::AbstractObject) end return false end -pickup(a::Agent, ::Nonitem, o::AbstractObject) = nothing +pickup(::Nonitem, a::Agent, o::AbstractObject) = nothing struct Drop end const DROP = Drop() @@ -140,4 +140,3 @@ function (::Drop)(a::Agent) end return nothing end - From a896252cefab06c5cc1745943832c9cf90c635df Mon Sep 17 00:00:00 2001 From: Ben Landrum <36489943+landrumb@users.noreply.github.com> Date: Mon, 12 Oct 2020 19:31:40 -0400 Subject: [PATCH 11/21] added type annotation for non-item isitem() Co-authored-by: Jun Tian --- src/objects.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects.jl b/src/objects.jl index c009b03..ed61ae3 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -114,7 +114,7 @@ const ITEM = Item() const NONITEM = Nonitem() isitem(::Type{Key{T}}) where T = ITEM isitem(::Type{Gem}) = ITEM -isitem() = NONITEM +isitem(x::AbstractObject) = isitem(typeof(x)) struct Pickup end const PICKUP = Pickup() From e511da04748f41436271b7512172bfdb7227eee6 Mon Sep 17 00:00:00 2001 From: Ben Landrum <36489943+landrumb@users.noreply.github.com> Date: Mon, 12 Oct 2020 19:33:43 -0400 Subject: [PATCH 12/21] made key annotation in isitem trait cleaner Co-authored-by: Jun Tian --- src/objects.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects.jl b/src/objects.jl index ed61ae3..0f6a5b3 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -112,7 +112,7 @@ struct Item end struct Nonitem end const ITEM = Item() const NONITEM = Nonitem() -isitem(::Type{Key{T}}) where T = ITEM +isitem(::Type{<:Key}) = ITEM isitem(::Type{Gem}) = ITEM isitem(x::AbstractObject) = isitem(typeof(x)) From 849d53719e936aa31a2b531f72326ddb09841c4e Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 06:05:55 -0400 Subject: [PATCH 13/21] moved drop functor definition to pickup definition --- src/objects.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 0f6a5b3..0320486 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -119,6 +119,9 @@ isitem(x::AbstractObject) = isitem(typeof(x)) struct Pickup end const PICKUP = Pickup() +struct Drop end +const DROP = Drop() + (::Pickup)(a::Agent, o::T) where T = pickup(isitem(T), a, o) function pickup(::Item, a::Agent, o::AbstractObject) if a.inv == nothing @@ -129,9 +132,6 @@ function pickup(::Item, a::Agent, o::AbstractObject) end pickup(::Nonitem, a::Agent, o::AbstractObject) = nothing -struct Drop end -const DROP = Drop() - function (::Drop)(a::Agent) if a.inv != nothing x = a.inv From c9bc6e04e840459c0f1a566d4072233cbb92de21 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 06:09:01 -0400 Subject: [PATCH 14/21] refactored item to transportable --- src/objects.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 0320486..aa00dc6 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -108,13 +108,13 @@ set_dir!(a::Agent, d) = a.dir = d # Pick Up and Drop ##### -struct Item end -struct Nonitem end -const ITEM = Item() -const NONITEM = Nonitem() -isitem(::Type{<:Key}) = ITEM -isitem(::Type{Gem}) = ITEM -isitem(x::AbstractObject) = isitem(typeof(x)) +struct Transportable end +struct Nontransportable end +const TRANSPORTABLE = Transportable() +const NONTRANSPORTABLE = Nontransportable() +istransportable(::Type{<:Key}) = TRANSPORTABLE +istransportable(::Type{Gem}) = TRANSPORTABLE +istransportable(x::AbstractObject) = istransportable(typeof(x)) struct Pickup end const PICKUP = Pickup() @@ -122,15 +122,15 @@ const PICKUP = Pickup() struct Drop end const DROP = Drop() -(::Pickup)(a::Agent, o::T) where T = pickup(isitem(T), a, o) -function pickup(::Item, a::Agent, o::AbstractObject) +(::Pickup)(a::Agent, o::T) where T = pickup(istransportable(T), a, o) +function pickup(::Transportable, a::Agent, o::AbstractObject) if a.inv == nothing a.inv = o return true end return false end -pickup(::Nonitem, a::Agent, o::AbstractObject) = nothing +pickup(::Nontransportable, a::Agent, o::AbstractObject) = nothing function (::Drop)(a::Agent) if a.inv != nothing From a774ece30e67afbbe18796952b462d8aa0555f45 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 06:30:53 -0400 Subject: [PATCH 15/21] added array_agent --- src/objects.jl | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index aa00dc6..0f8bb29 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -84,12 +84,24 @@ const GEM = Gem() Base.convert(::Type{Char}, ::Gem) = '♦' get_color(::Gem) = :magenta -Base.@kwdef mutable struct Agent <: AbstractObject +abstract type AbstractAgent <: AbstractObject end + +Base.@kwdef mutable struct Agent <: AbstractAgent color::Symbol=:red dir::LRUD inv::Union{AbstractObject, Nothing}=nothing end -function Base.convert(::Type{Char}, a::Agent) + +Base.@kwdef mutable struct Array_agent <: AbstractAgent + color::Symbol=:red + dir::LRUD + inv::Vector{Union{AbstractObject, Nothing}}=[] +end +function Array_agent(dir::LRUD, len::Integer; color::Symbol=:red) + Array_agent(color, dir, Vector{Union{AbstractObject, Nothing}}(nothing, len)) +end + +function Base.convert(::Type{Char}, a::AbstractAgent) if a.dir === UP '↑' elseif a.dir === DOWN @@ -100,9 +112,9 @@ function Base.convert(::Type{Char}, a::Agent) '→' end end -get_color(a::Agent) = a.color -get_dir(a::Agent) = a.dir -set_dir!(a::Agent, d) = a.dir = d +get_color(a::AbstractAgent) = a.color +get_dir(a::AbstractAgent) = a.dir +set_dir!(a::AbstractAgent, d) = a.dir = d ##### # Pick Up and Drop From 8fe68296e580a8aba647d21b860759b4f1eab4be Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 06:53:40 -0400 Subject: [PATCH 16/21] implemented pickup and drop for array_agent --- src/objects.jl | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 0f8bb29..37d9dc7 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -134,15 +134,24 @@ const PICKUP = Pickup() struct Drop end const DROP = Drop() -(::Pickup)(a::Agent, o::T) where T = pickup(istransportable(T), a, o) -function pickup(::Transportable, a::Agent, o::AbstractObject) +(::Pickup)(a::AbstractAgent, o::T) where T = PICKUP(istransportable(T), a, o) +function (::Pickup)(::Transportable, a::Agent, o::AbstractObject) if a.inv == nothing a.inv = o return true end return false end -pickup(::Nontransportable, a::Agent, o::AbstractObject) = nothing +function (::Pickup)(::Transportable, a::Array_agent, o::AbstractObject) + for (i, v) in enumerate(a.inv) # Picked up objects go into the first empty index + if v == nothing + a.inv[i] = o + return true + end + end + return false +end +pickup(::Nontransportable, a::AbstractAgent, o::AbstractObject) = nothing function (::Drop)(a::Agent) if a.inv != nothing @@ -152,3 +161,12 @@ function (::Drop)(a::Agent) end return nothing end +function (::Drop)(a::Array_agent) + for (i, v) in Iterators.reverse(enumerate(a.inv)) # Most recently picked up objects are dropped first + if typeof(v)<:AbstractObject + a.inv[i] = nothing + return v + end + end + return nothing +end From 1b3efdc87419c71632613662bcababc39832d072 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 07:00:58 -0400 Subject: [PATCH 17/21] updated export statements --- src/objects.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index 37d9dc7..d23491f 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, GEM -export MoveForward, AbstractObject, Empty, Wall, Goal, Door, Gem, Agent +export COLORS, MOVE_FORWARD, TURN_LEFT, TURN_RIGHT, UP, DOWN, LEFT, RIGHT, LRUD, EMPTY, WALL, GOAL, GEM, PICKUP, DROP +export MoveForward, AbstractObject, Empty, Wall, Goal, Door, Gem, Agent, Array_agent export get_color using Crayons From 89759ae53a46cd937606f07ec781b6863d3b1579 Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 07:09:20 -0400 Subject: [PATCH 18/21] Revert "updated export statements" This reverts commit 1b3efdc87419c71632613662bcababc39832d072. --- src/objects.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index d23491f..37d9dc7 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, GEM, PICKUP, DROP -export MoveForward, AbstractObject, Empty, Wall, Goal, Door, Gem, Agent, Array_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 From a8dfb6dc6fc4f07b540b2e4b614e4354dca8acfe Mon Sep 17 00:00:00 2001 From: landrumb <36489943+landrumb@users.noreply.github.com> Date: Tue, 13 Oct 2020 08:46:47 -0400 Subject: [PATCH 19/21] Implemented Agent as a parametric struct --- src/objects.jl | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/objects.jl b/src/objects.jl index f578270..ad411d0 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -45,26 +45,22 @@ const GEM = Gem() Base.convert(::Type{Char}, ::Gem) = '♦' get_color(::Gem) = :magenta -abstract type AbstractAgent <: AbstractObject end +const INV = Union{Nothing, AbstractObject} +const INVARRAY = Vector{Union{AbstractObject, Nothing}} -Base.@kwdef mutable struct Agent <: AbstractAgent - color::Symbol=:red +mutable struct Agent{I<:Union{INV, INVARRAY}} <: AbstractObject + color::Symbol dir::LRUD - inv::Union{AbstractObject, Nothing}=nothing + inv::I end - -Base.@kwdef mutable struct Array_agent <: AbstractAgent - color::Symbol=:red - dir::LRUD - inv::Vector{Union{AbstractObject, Nothing}}=[] -end - -function Array_agent(dir::LRUD, len::Integer; color::Symbol=:red) - Array_agent(color, dir, Vector{Union{AbstractObject, Nothing}}(nothing, len)) +Agent(dir::LRUD; inv::INV=nothing, color::Symbol=:red) = Agent{INV}(color, dir, inv) +Agent(;dir::LRUD, inv::INV=nothing, color::Symbol=:red) = Agent{INV}(color, dir, inv) +function Agent{INVARRAY}(dir::LRUD, len::Integer; color::Symbol=:red) + Agent{INVARRAY}(color, dir, INVARRAY(nothing, len)) end +Agent{INV}(dir::LRUD; inv::INV=nothing, color::Symbol=:red) = Agent{INV}(color, dir, inv) -function Base.convert(::Type{Char}, a::AbstractAgent) - +function Base.convert(::Type{Char}, a::Agent) if a.dir === UP '↑' elseif a.dir === DOWN @@ -75,10 +71,9 @@ function Base.convert(::Type{Char}, a::AbstractAgent) '→' end end - -get_color(a::AbstractAgent) = a.color -get_dir(a::AbstractAgent) = a.dir -set_dir!(a::AbstractAgent, d) = a.dir = d +get_color(a::Agent) = a.color +get_dir(a::Agent) = a.dir +set_dir!(a::Agent, d) = a.dir = d ##### # Pick Up and Drop @@ -98,15 +93,15 @@ const PICKUP = Pickup() struct Drop end const DROP = Drop() -(::Pickup)(a::AbstractAgent, o::T) where T = PICKUP(istransportable(T), a, o) -function (::Pickup)(::Transportable, a::Agent, o::AbstractObject) +(::Pickup)(a::Agent, o::T) where T = PICKUP(istransportable(T), a, o) +function (::Pickup)(::Transportable, a::Agent{INV}, o::AbstractObject) if a.inv == nothing a.inv = o return true end return false end -function (::Pickup)(::Transportable, a::Array_agent, o::AbstractObject) +function (::Pickup)(::Transportable, a::Agent{INVARRAY}, o::AbstractObject) for (i, v) in enumerate(a.inv) # Picked up objects go into the first empty index if v == nothing a.inv[i] = o @@ -115,9 +110,9 @@ function (::Pickup)(::Transportable, a::Array_agent, o::AbstractObject) end return false end -pickup(::Nontransportable, a::AbstractAgent, o::AbstractObject) = nothing +pickup(::Nontransportable, a::Agent, o::AbstractObject) = nothing -function (::Drop)(a::Agent) +function (::Drop)(a::Agent{INV}) if a.inv != nothing x = a.inv a.inv = nothing @@ -125,7 +120,7 @@ function (::Drop)(a::Agent) end return nothing end -function (::Drop)(a::Array_agent) +function (::Drop)(a::Agent{INVARRAY}) for (i, v) in Iterators.reverse(enumerate(a.inv)) # Most recently picked up objects are dropped first if typeof(v)<:AbstractObject a.inv[i] = nothing From c2daeac389709f989848f1774ae91fbc750af25e Mon Sep 17 00:00:00 2001 From: Jun Tian Date: Tue, 13 Oct 2020 22:48:00 +0800 Subject: [PATCH 20/21] slightly polish --- src/actions.jl | 6 +++ src/envs/doorkey.jl | 8 ++-- src/objects.jl | 89 ++++++++++++++++++++------------------------- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/actions.jl b/src/actions.jl index 33006bd..5f30c21 100644 --- a/src/actions.jl +++ b/src/actions.jl @@ -24,3 +24,9 @@ const TURN_LEFT = TurnLeft() (x::TurnLeft)(::Up) = LEFT (x::TurnLeft)(::Right) = UP (x::TurnLeft)(::Down) = RIGHT + +struct Pickup <: AbstractGridWorldAction end +const PICK_UP = Pickup() + +struct Drop <: AbstractGridWorldAction end +const DROP = Drop() diff --git a/src/envs/doorkey.jl b/src/envs/doorkey.jl index 4d6a4e6..942d343 100644 --- a/src/envs/doorkey.jl +++ b/src/envs/doorkey.jl @@ -32,7 +32,7 @@ function DoorKey(;n=8, agent_start_pos=CartesianIndex(2,2), rng=Random.GLOBAL_RN world[EMPTY, key_pos] = false world[Key(:yellow), key_pos] = true - DoorKey(world, agent_start_pos, Agent(dir=RIGHT)) + DoorKey(world, agent_start_pos, Agent(;dir=RIGHT)) end function (w::DoorKey)(::MoveForward) @@ -45,10 +45,10 @@ function (w::DoorKey)(::MoveForward) w.world[EMPTY, dest] = true end w.agent_pos = dest - elseif w.world[Door(:yellow), dest] && w.agent.inv == Key(:yellow) - w.agent_pos = dest - elseif w.world[Door(:yellow), dest] && w.agent.inv != Key(:yellow) + elseif w.world[Door(:yellow), dest] && w.agent.inv !== Key(:yellow) nothing + elseif w.world[Door(:yellow), dest] && w.agent.inventory === Key(:yellow) + w.agent_pos = dest elseif dest ∈ CartesianIndices((size(w.world, 2), size(w.world, 3))) && !w.world[WALL,dest] w.agent_pos = dest end diff --git a/src/objects.jl b/src/objects.jl index ad411d0..08fd2fa 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -45,40 +45,34 @@ const GEM = Gem() Base.convert(::Type{Char}, ::Gem) = '♦' get_color(::Gem) = :magenta -const INV = Union{Nothing, AbstractObject} -const INVARRAY = Vector{Union{AbstractObject, Nothing}} +##### +# Agent +##### -mutable struct Agent{I<:Union{INV, INVARRAY}} <: AbstractObject +mutable struct Agent{I<:Union{Nothing, AbstractObject, Vector}} <: AbstractObject color::Symbol dir::LRUD - inv::I + inventory::I end -Agent(dir::LRUD; inv::INV=nothing, color::Symbol=:red) = Agent{INV}(color, dir, inv) -Agent(;dir::LRUD, inv::INV=nothing, color::Symbol=:red) = Agent{INV}(color, dir, inv) -function Agent{INVARRAY}(dir::LRUD, len::Integer; color::Symbol=:red) - Agent{INVARRAY}(color, dir, INVARRAY(nothing, len)) -end -Agent{INV}(dir::LRUD; inv::INV=nothing, color::Symbol=:red) = Agent{INV}(color, dir, inv) + +Agent(;dir::LRUD, inventory=nothing, color::Symbol=:red) = Agent(color, dir, inventory) function Base.convert(::Type{Char}, a::Agent) - if a.dir === UP + if a.dir === UP '↑' - elseif a.dir === DOWN + elseif a.dir === DOWN '↓' - elseif a.dir === LEFT + elseif a.dir === LEFT '←' elseif a.dir === RIGHT '→' end end + get_color(a::Agent) = a.color get_dir(a::Agent) = a.dir set_dir!(a::Agent, d) = a.dir = d -##### -# Pick Up and Drop -##### - struct Transportable end struct Nontransportable end const TRANSPORTABLE = Transportable() @@ -87,45 +81,42 @@ istransportable(::Type{<:Key}) = TRANSPORTABLE istransportable(::Type{Gem}) = TRANSPORTABLE istransportable(x::AbstractObject) = istransportable(typeof(x)) -struct Pickup end -const PICKUP = Pickup() - -struct Drop end -const DROP = Drop() - -(::Pickup)(a::Agent, o::T) where T = PICKUP(istransportable(T), a, o) -function (::Pickup)(::Transportable, a::Agent{INV}, o::AbstractObject) - if a.inv == nothing - a.inv = o - return true - end - return false -end -function (::Pickup)(::Transportable, a::Agent{INVARRAY}, o::AbstractObject) - for (i, v) in enumerate(a.inv) # Picked up objects go into the first empty index - if v == nothing - a.inv[i] = o - return true +(a::Pickup)(a::Agent, o) = a(istransportable(o), a, o) + +function (::Pickup)(::Transportable, a::Agent, o::AbstractObject) + if isnothing(a.inventory) + a.inventory = o + true + elseif a.inventory isa Vector + i = findfirst(isnothing, a.v) + if isnothing(i) + false + else + a.inventory[i] = o + true end + else + false end - return false end -pickup(::Nontransportable, a::Agent, o::AbstractObject) = nothing -function (::Drop)(a::Agent{INV}) - if a.inv != nothing +function (::Drop)(a::Agent) + if isnothing(a.inv) + nothing + elseif a.inv isa AbstractObject x = a.inv a.inv = nothing - return x - end - return nothing -end -function (::Drop)(a::Agent{INVARRAY}) - for (i, v) in Iterators.reverse(enumerate(a.inv)) # Most recently picked up objects are dropped first - if typeof(v)<:AbstractObject + x + elseif a.inv isa Vector + i = findlast(x -> x isa AbstractObject, a.inv) + if isnothing(i) + nothing + else + x = a.inv[i] a.inv[i] = nothing - return v + x end + else + @error "unknown inventory type $(a.inv)" end - return nothing end From 9c11a9c6d03adb97f2f1c27936f4a949db224024 Mon Sep 17 00:00:00 2001 From: Jun Tian Date: Tue, 13 Oct 2020 23:17:34 +0800 Subject: [PATCH 21/21] fix DoorKey --- src/envs/doorkey.jl | 4 ++-- src/objects.jl | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/envs/doorkey.jl b/src/envs/doorkey.jl index 942d343..703a268 100644 --- a/src/envs/doorkey.jl +++ b/src/envs/doorkey.jl @@ -40,12 +40,12 @@ function (w::DoorKey)(::MoveForward) dest = dir(w.agent_pos) if w.world[Key(:yellow), dest] - if PICKUP(w.agent, Key(:yellow)) + if PICK_UP(w.agent, Key(:yellow)) w.world[Key(:yellow), dest] = false w.world[EMPTY, dest] = true end w.agent_pos = dest - elseif w.world[Door(:yellow), dest] && w.agent.inv !== Key(:yellow) + elseif w.world[Door(:yellow), dest] && w.agent.inventory !== Key(:yellow) nothing elseif w.world[Door(:yellow), dest] && w.agent.inventory === Key(:yellow) w.agent_pos = dest diff --git a/src/objects.jl b/src/objects.jl index 08fd2fa..af58568 100644 --- a/src/objects.jl +++ b/src/objects.jl @@ -49,10 +49,10 @@ get_color(::Gem) = :magenta # Agent ##### -mutable struct Agent{I<:Union{Nothing, AbstractObject, Vector}} <: AbstractObject +mutable struct Agent <: AbstractObject color::Symbol dir::LRUD - inventory::I + inventory::Union{Nothing, AbstractObject, Vector} end Agent(;dir::LRUD, inventory=nothing, color::Symbol=:red) = Agent(color, dir, inventory) @@ -81,7 +81,7 @@ istransportable(::Type{<:Key}) = TRANSPORTABLE istransportable(::Type{Gem}) = TRANSPORTABLE istransportable(x::AbstractObject) = istransportable(typeof(x)) -(a::Pickup)(a::Agent, o) = a(istransportable(o), a, o) +(x::Pickup)(a::Agent, o) = x(istransportable(o), a, o) function (::Pickup)(::Transportable, a::Agent, o::AbstractObject) if isnothing(a.inventory) @@ -101,22 +101,22 @@ function (::Pickup)(::Transportable, a::Agent, o::AbstractObject) end function (::Drop)(a::Agent) - if isnothing(a.inv) + if isnothing(a.inventory) nothing - elseif a.inv isa AbstractObject - x = a.inv - a.inv = nothing + elseif a.inventory isa AbstractObject + x = a.inventory + a.inventory = nothing x - elseif a.inv isa Vector - i = findlast(x -> x isa AbstractObject, a.inv) + elseif a.inventory isa Vector + i = findlast(x -> x isa AbstractObject, a.inventory) if isnothing(i) nothing else - x = a.inv[i] - a.inv[i] = nothing + x = a.inventory[i] + a.inventory[i] = nothing x end else - @error "unknown inventory type $(a.inv)" + @error "unknown inventory type $(a.inventory)" end end