@@ -56,6 +56,14 @@ class WindEnv(gym.Env):
5656 original (a numpy ``RandomState``, not the global numpy seed,
5757 so we do not leak into other code).
5858 wind_max: Max absolute value of each wind component. Default 0.08.
59+ dense_reward: If True, replace the sparse 0/1 goal-disk reward with
60+ a smooth distance-shaped reward ``exp(-||state - goal||)``.
61+ Bounded in ``(0, 1]``, peaks at 1 at the goal, gives non-zero
62+ gradient everywhere on the plane. Useful as a sanity-check
63+ alternative when debugging a stack that struggles with the
64+ sparse signal. Goal-disk success/membership is still tracked
65+ for logging (``Trial * Success``) regardless of this setting.
66+ Default False (preserves the original sparse reward).
5967 """
6068
6169 metadata = {"render_modes" : []}
@@ -68,12 +76,14 @@ def __init__(
6876 k_episodes : int = 1 ,
6977 wind_seed : int = 1337 ,
7078 wind_max : float = 0.08 ,
79+ dense_reward : bool = False ,
7180 ):
7281 super ().__init__ ()
7382 self .n_tasks = int (n_tasks )
7483 self ._max_episode_steps = int (max_episode_steps )
7584 self .k_episodes = int (k_episodes )
7685 self .goal_radius = float (goal_radius )
86+ self .dense_reward = bool (dense_reward )
7787
7888 # Local RandomState so the deterministic task set does not affect
7989 # the global numpy RNG (the original called np.random.seed(1337)).
@@ -153,7 +163,16 @@ def step(self, action):
153163 self ._state = (self ._state + action + self ._wind ).astype (np .float32 )
154164
155165 success = self .is_goal_state ()
156- reward = 1.0 if success else 0.0
166+ if self .dense_reward :
167+ # Smooth distance-shaped reward: bounded in (0, 1], peaks at 1
168+ # at the goal, decays as exp(-||state - goal||). Gives non-zero
169+ # gradient everywhere; with a starting position at origin and
170+ # goal at (0, 1) the initial step's reward is ~exp(-1) ≈ 0.37
171+ # and rises monotonically as the agent approaches.
172+ dist = float (np .linalg .norm (self ._state - self ._goal ))
173+ reward = float (np .exp (- dist ))
174+ else :
175+ reward = 1.0 if success else 0.0
157176 if success :
158177 self ._trial_success = True
159178
0 commit comments