Tabular Q-learning stores one number per (state, action) pair: how much total future reward the agent expects from taking that action there. After every transition it nudges exactly one of those numbers.
Q[s][a] += α · (r + γ · max(Q[s']) - Q[s][a])
The bracketed part is the temporal-difference error — the gap between what the agent expected and what it now believes after seeing reward r and landing in state s'. α controls how much of that gap to close; γ controls how much distant reward matters.
The max is what makes this off-policy: the agent bootstraps from the best action available next, whether or not it ends up taking it.
Task: write q_update(q, state, action, reward, next_state, alpha, gamma), where q is a 2D list indexed [state][action]. Return the whole updated table as a 2D list, values rounded to 4 decimal places. Only one cell changes.