code: def _move_random(self):
      movable_directions = set()
      for action in ACTIONS:
          next_pos = self.env.next_pos(self.pos, action)
          if self.pos != next_pos:
              movable_directions.add(action)
  
      # no doubling back unless no other choice
      if (
          opposite_direction(self.direction) in movable_directions
          and len(movable_directions) > 1
      ):
          movable_directions.remove(opposite_direction(self.direction))
      d = np.random.choice(list(movable_directions))
      next_pos = self.env.next_pos(self.pos, d)
      self.update(next_pos, d)
  
imports: import logging
  from typing import NamedTuple
  import numpy
  from gym import Env
  from gym.spaces import Box, Discrete
label_desc: Use image node_id 3 for calling the Ghost obj's underlying member method code with example usage: obj._move_random() without return types