return a tuple of (s,r,a,o),
            where s is of shape self._output_shape, which is
            [H, W, (hist_len+1) * channel] if input is (H, W, channel)

def sample(self, idx):
        """ return a tuple of (s,r,a,o),
            where s is of shape self._output_shape, which is
            [H, W, (hist_len+1) * channel] if input is (H, W, channel)"""
        idx = (self._curr_pos + idx) % self._curr_size
        k = self.history_len + 1
        if idx + k <= self._curr_size:
            state = self.state[idx: idx + k]
            reward = self.reward[idx: idx + k]
            action = self.action[idx: idx + k]
            isOver = self.isOver[idx: idx + k]
        else:
            end = idx + k - self._curr_size
            state = self._slice(self.state, idx, end)
            reward = self._slice(self.reward, idx, end)
            action = self._slice(self.action, idx, end)
            isOver = self._slice(self.isOver, idx, end)
        ret = self._pad_sample(state, reward, action, isOver)
        return ret