Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/treasure-hunt-game/llms.txt

Use this file to discover all available pages before exploring further.

Every action a player takes in Treasure Hunt produces a numeric reward signal. This signal is drawn directly from the original deep Q-learning training loop, where an agent learned to navigate the maze by accumulating positive rewards for progress and negative penalties for wasted or illegal moves. In the browser demo the same reward arithmetic runs live, keeping a running totalReward that the HUD displays after every step. Understanding the reward values helps explain why the optimal strategy is to reach the treasure with as few moves as possible and never retrace steps or walk into walls.

Reward Values at a Glance

EventReward
Player reaches the target [7,7]+1.0
Valid step onto an unvisited open cell−0.04
Revisiting a previously visited cell−0.25
Invalid move — wall or out-of-bounds−0.75
Blocked — no valid actions availableminReward − 1

The minReward Floor

minReward is calculated once when the maze is initialized and is fixed for the lifetime of that game session:
this.minReward = -0.5 * this.rows * this.cols;
For the standard 8×8 board: −0.5 × 8 × 8 = −32. This value acts as the lower boundary for the cumulative totalReward. A blocked state issues a reward of minReward − 1 (i.e., −33), which is deliberately severe enough to push totalReward below the floor in a single step.

The getReward() Function

The engine evaluates rewards by inspecting state.mode and the player’s current position after updateState() has already been applied. The checks run in priority order — the target check fires first, so reaching [7,7] always yields +1.0 regardless of any other state:
getReward() {
  const { row, col, mode } = this.state;

  if (this.isTarget(row, col)) return 1.0;
  if (mode === "blocked")      return this.minReward - 1;
  if (this.visited.has(this.key(row, col))) return -0.25;
  if (mode === "invalid")      return -0.75;
  if (mode === "valid")        return -0.04;
  return 0;
}

How totalReward Accumulates

The act(action) method is the single entry point for all player moves. It chains the state update, the reward lookup, and the accumulation step together in one call:
1

Update state

updateState(action) moves the player (or not) and sets state.mode to "valid", "invalid", or "blocked".
2

Calculate reward

getReward() reads the new state.mode and position, then returns the appropriate point value.
3

Accumulate

The returned reward is added to totalReward: this.totalReward += reward.
4

Evaluate game status

gameStatus() checks whether the game is over (win or lose) and returns "win", "lose", or "not_over".
5

Return result

act() returns a single object with envState, reward, status, state, and totalReward so the caller has full visibility.

Win and Lose Conditions

Two terminal states can end a game. They are checked inside gameStatus() after every act() call:
gameStatus() {
  if (this.totalReward < this.minReward) return "lose";
  if (this.isTarget(this.state.row, this.state.col)) return "win";
  return "not_over";
}
StatusTrigger
"win"Player is currently standing on [7,7] (the target cell)
"lose"totalReward has dropped below minReward (below −32)
"not_over"Neither condition is met — game continues
The lose condition mirrors the early-termination rule from the original training loop, where an agent that wasted too many moves would have its episode cut short so training time was not wasted on a lost cause.

Why This Reward Structure Exists

Each penalty level discourages a specific class of bad behavior:
  • −0.04 per valid step — creates pressure to find the shortest path rather than wandering. Even a correct route costs points, so brevity is rewarded implicitly.
  • −0.25 for revisiting a cell — penalizes looping back through already-explored territory, encouraging forward progress.
  • −0.75 for invalid moves — sharply penalizes attempts to walk through walls, which are never productive.
  • minReward − 1 when blocked — a catastrophic penalty for ending up in a cell with no exits, which signals a maze-design or navigation failure.
  • +1.0 for reaching the target — the only positive signal, making the treasure cell unambiguously the goal.
In the browser demo the reward value shown in the HUD is informational. While the totalReward < minReward lose condition is fully active in the engine code, normal gameplay on a well-generated maze makes it extremely difficult to exhaust all 32 reward points before finding the treasure. Hitting walls and revisiting cells will drain totalReward steadily, but a player who keeps moving forward will typically reach [7,7] long before the floor is breached.

Build docs developers (and LLMs) love