class_docstr: This is a simple implementation of the Gridworld Cliff
  reinforcement learning task.
  
  Adapted from Example 6.6 (page 106) from [Reinforcement Learning: An Introduction
  by Sutton and Barto](http://incompleteideas.net/book/bookdraft2018jan1.pdf).
  
  With inspiration from:
  [https://github.com/dennybritz/reinforcement-learning/blob/master/lib/envs/cliff_walking.py]
  (https://github.com/dennybritz/reinforcement-learning/blob/master/lib/envs/cliff_walking.py)
  
  ### Description
  The board is a 4x12 matrix, with (using NumPy matrix indexing):
  - [3, 0] as the start at bottom-left
  - [3, 11] as the goal at bottom-right
  - [3, 1..10] as the cliff at bottom-center
  
  If the agent steps on the cliff, it returns to the start.
  An episode terminates when the agent reaches the goal.
  
  ### Actions
  There are 4 discrete deterministic actions:
  - 0: move up
  - 1: move right
  - 2: move down
  - 3: move left
  
  ### Observations
  There are 3x12 + 1 possible states. In fact, the agent cannot be at the cliff, nor at the goal
  (as this results in the end of the episode).
  It remains all the positions of the first 3 rows plus the bottom-left cell.
  The observation is simply the current position encoded as [flattened index](https://numpy.org/doc/stable/reference/generated/numpy.unravel_index.html).
  
  ### Reward
  Each time step incurs -1 reward, and stepping into the cliff incurs -100 reward.
  
  ### Arguments
  
  ```
  gym.make('CliffWalking-v0')
  ```
  
  ### Version History
  - v0: Initial version release
class_docstr_tok: ["This","is","a","simple","implementation","of","the","Gridworld","Cliff","reinforcement","learning","task",".","Adapted","from","Example","6.6","(","page","106",")","from","[","Reinforcement","Learning",":","An","Introduction","by","Sutton","and","Barto","]","(","http",":","\/\/incompleteideas.net\/book\/bookdraft2018jan1.pdf",")",".","With","inspiration","from",":","[","https",":","\/\/github.com\/dennybritz\/reinforcement-learning\/blob\/master\/lib\/envs\/cliff_walking.py","]","(","https",":","\/\/github.com\/dennybritz\/reinforcement-learning\/blob\/master\/lib\/envs\/cliff_walking.py",")","#","#","#","Description","The","board","is","a","4x12","matrix",",","with","(","using","NumPy","matrix","indexing",")",":","-","[","3",",","0","]","as","the","start","at","bottom-left","-","[","3",",","11","]","as","the","goal","at","bottom-right","-","[","3",",","1","..","10","]","as","the","cliff","at","bottom-center","If","the","agent","steps","on","the","cliff",",","it","returns","to","the","start",".","An","episode","terminates","when","the","agent","reaches","the","goal",".","#","#","#","Actions","There","are","4","discrete","deterministic","actions",":","-","0",":","move","up","-","1",":","move","right","-","2",":","move","down","-","3",":","move","left","#","#","#","Observations","There","are","3x12","+","1","possible","states",".","In","fact",",","the","agent","can","not","be","at","the","cliff",",","nor","at","the","goal","(","as","this","results","in","the","end","of","the","episode",")",".","It","remains","all","the","positions","of","the","first","3","rows","plus","the","bottom-left","cell",".","The","observation","is","simply","the","current","position","encoded","as","[","flattened","index","]","(","https",":","\/\/numpy.org\/doc\/stable\/reference\/generated\/numpy.unravel_index.html",")",".","#","#","#","Reward","Each","time","step","incurs","-1","reward",",","and","stepping","into","the","cliff","incurs","-100","reward",".","#","#","#","Arguments","``","`","gym.make","(","'CliffWalking-v0","'",")","``","`","#","#","#","Version","History","-","v0",":","Initial","version","release"]
code: def _render_text(self):
      outfile = StringIO()
  
      for s in range(self.nS):
          position = np.unravel_index(s, self.shape)
          if self.s == s:
              output = " x "
          # Print terminal state
          elif position == (3, 11):
              output = " T "
          elif self._cliff[position]:
              output = " C "
          else:
              output = " o "
  
          if position[1] == 0:
              output = output.lstrip()
          if position[1] == self.shape[1] - 1:
              output = output.rstrip()
              output += "\n"
  
          outfile.write(output)
      outfile.write("\n")
  
      with closing(outfile):
          return outfile.getvalue()
  
file_path: gym/gym/envs/toy_text/cliffwalking.py
imports: from contextlib import closing
  from io import StringIO
  from os import path
  from typing import Optional
  import numpy
  from gym import Env, logger, spaces
  from gym.envs.toy_text.utils import categorical_sample
  from gym.error import DependencyNotInstalled
label_desc: Use image node_id 8 for calling the CliffWalkingEnv obj's underlying member method code with example usage: obj._render_text() and returns: outfile