\documentclass[tikz,border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows.meta, positioning, calc}

\begin{document}
\begin{tikzpicture}[
    startstop/.style={
        rectangle, 
        rounded corners=8pt, 
        minimum width=7.5cm, 
        minimum height=0.8cm,
        text centered, 
        draw=black,
        line width=1.2pt,
        fill=blue!15,
        font=\footnotesize
    },
    process/.style={
        rectangle, 
        minimum width=5.5cm, 
        minimum height=0.9cm,
        text centered, 
        draw=black,
        line width=1pt,
        fill=gray!15,
        font=\footnotesize,
        align=center
    },
    decision/.style={
        diamond, 
        minimum width=2.5cm, 
        minimum height=1.5cm,
        text centered, 
        draw=black,
        line width=1pt,
        fill=yellow!25,
        font=\footnotesize\bfseries,
        inner sep=0pt
    },
    end/.style={
        ellipse,
        minimum width=1.8cm,
        minimum height=0.8cm,
        text centered,
        draw=black,
        line width=1.2pt,
        fill=blue!15,
        font=\footnotesize\bfseries
    },
    arrow/.style={
        thick,
        ->,
        >=Stealth,
        line width=1.2pt
    },
    arrowlabel/.style={
        font=\footnotesize\bfseries,
        fill=white,
        inner sep=2pt
    }
]

% Nodes - Main flow (left side)
\node (start) [startstop] {Start at $t=1$: Initialize critic, actor, target networks, and replay buffer};

\node (dec1) [decision, below=0.9cm of start] {Is $t \leq T$?};

\node (action) [process, below=0.9cm of dec1] {Select action with exploration noise\\$a \sim \pi_{\phi}(s) + \epsilon$, $\epsilon \sim \mathcal{N}(0,\sigma)$};

\node (observe) [process, below=0.9cm of action] {Observe reward $r$ and new state $s'$\\and store transition tuple $(s,a,r,s')$\\in replay buffer $\mathcal{B}$};

\node (sample) [process, below=0.9cm of observe] {Sample mini-batch from $\mathcal{B}$\\and calculate target values};

\node (updatecritic) [process, below=0.9cm of sample] {Update critic networks by\\minimizing MSE loss};

\node (dec2) [decision, below=0.9cm of updatecritic] {$t \bmod d = 0$?};

\node (updatepolicy) [process, below=0.9cm of dec2] {Update policy network\\Update target networks};

\node (increment) [process, below=0.9cm of updatepolicy] {$t = t + 1$};

\node (end) [end, right=3.5cm of dec1] {END};

% Arrows - Main flow
\draw [arrow] (start) -- (dec1);
\draw [arrow] (dec1) -- node[arrowlabel, right=2pt] {YES} (action);
\draw [arrow] (dec1) -- node[arrowlabel, above=1pt] {NO} (end);
\draw [arrow] (action) -- (observe);
\draw [arrow] (observe) -- (sample);
\draw [arrow] (sample) -- (updatecritic);
\draw [arrow] (updatecritic) -- (dec2);

% Conditional branch from dec2
\draw [arrow] (dec2) -- node[arrowlabel, right=2pt] {YES} (updatepolicy);

% NO branch - horizontal then vertical (clean rectangular routing)
\draw [arrow] (dec2.east) -- ++(3,0) node[arrowlabel, right=2pt,yshift=-40pt] {NO} |- (increment.east);

% Continue from updatepolicy to increment
\draw [arrow] (updatepolicy) -- (increment);

% Loop back arrow - clean horizontal/vertical path
\draw [arrow] (increment.west) -- ++(-2.5,0) |- (dec1.west);

% Legend box - positioned BELOW the END node to stay in bounds
\node [draw, rectangle, line width=1pt, below=0.5cm of end, anchor=north,
       text width=4.2cm, font=\scriptsize, align=left, fill=white] (legend) {
    \textbf{Symbol Definitions:}\\[2pt]
    $T$ -- number of time steps\\
    $t$ -- current time step\\
    $a$ -- action\\
    $s$ -- state\\
    $s'$ -- next state\\
    $r$ -- reward\\
    $\mathcal{B}$ -- replay buffer\\
    $\epsilon$ -- noise\\
    $\pi_{\phi}$ -- actor network\\
    $d$ -- number of steps by which\\
    \hspace{0.5cm}policy update is delayed
};

\end{tikzpicture}
\end{document}